d081a8935bf13992d84206b59f03e111bc3bd53d
[samba.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 #include "lib/util/tevent_ntstatus.h"
35 #include "lib/util/sys_rw.h"
36
37 #undef DBGC_CLASS
38 #define DBGC_CLASS DBGC_VFS
39
40 static_decl_vfs;
41
42 struct vfs_fsp_data {
43     struct vfs_fsp_data *next;
44     struct vfs_handle_struct *owner;
45     void (*destroy)(void *p_data);
46     void *_dummy_;
47     /* NOTE: This structure contains four pointers so that we can guarantee
48      * that the end of the structure is always both 4-byte and 8-byte aligned.
49      */
50 };
51
52 struct vfs_init_function_entry {
53         char *name;
54         struct vfs_init_function_entry *prev, *next;
55         const struct vfs_fn_pointers *fns;
56 };
57
58 /****************************************************************************
59     maintain the list of available backends
60 ****************************************************************************/
61
62 static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
63 {
64         struct vfs_init_function_entry *entry = backends;
65
66         DEBUG(10, ("vfs_find_backend_entry called for %s\n", name));
67
68         while(entry) {
69                 if (strcmp(entry->name, name)==0) return entry;
70                 entry = entry->next;
71         }
72
73         return NULL;
74 }
75
76 NTSTATUS smb_register_vfs(int version, const char *name,
77                           const struct vfs_fn_pointers *fns)
78 {
79         struct vfs_init_function_entry *entry = backends;
80
81         if ((version != SMB_VFS_INTERFACE_VERSION)) {
82                 DEBUG(0, ("Failed to register vfs module.\n"
83                           "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
84                           "current SMB_VFS_INTERFACE_VERSION is %d.\n"
85                           "Please recompile against the current Samba Version!\n",  
86                           version, SMB_VFS_INTERFACE_VERSION));
87                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
88         }
89
90         if (!name || !name[0]) {
91                 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
92                 return NT_STATUS_INVALID_PARAMETER;
93         }
94
95         if (vfs_find_backend_entry(name)) {
96                 DEBUG(0,("VFS module %s already loaded!\n", name));
97                 return NT_STATUS_OBJECT_NAME_COLLISION;
98         }
99
100         entry = SMB_XMALLOC_P(struct vfs_init_function_entry);
101         entry->name = smb_xstrdup(name);
102         entry->fns = fns;
103
104         DLIST_ADD(backends, entry);
105         DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
106         return NT_STATUS_OK;
107 }
108
109 /****************************************************************************
110   initialise default vfs hooks
111 ****************************************************************************/
112
113 static void vfs_init_default(connection_struct *conn)
114 {
115         DEBUG(3, ("Initialising default vfs hooks\n"));
116         vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME);
117 }
118
119 /****************************************************************************
120   initialise custom vfs hooks
121  ****************************************************************************/
122
123 bool vfs_init_custom(connection_struct *conn, const char *vfs_object)
124 {
125         char *module_path = NULL;
126         char *module_name = NULL;
127         char *module_param = NULL, *p;
128         vfs_handle_struct *handle;
129         const struct vfs_init_function_entry *entry;
130
131         if (!conn||!vfs_object||!vfs_object[0]) {
132                 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
133                           "empty vfs_object!\n"));
134                 return False;
135         }
136
137         if(!backends) {
138                 static_init_vfs(NULL);
139         }
140
141         DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
142
143         module_path = smb_xstrdup(vfs_object);
144
145         p = strchr_m(module_path, ':');
146
147         if (p) {
148                 *p = 0;
149                 module_param = p+1;
150                 trim_char(module_param, ' ', ' ');
151         }
152
153         trim_char(module_path, ' ', ' ');
154
155         module_name = smb_xstrdup(module_path);
156
157         if ((module_name[0] == '/') &&
158             (strcmp(module_path, DEFAULT_VFS_MODULE_NAME) != 0)) {
159
160                 /*
161                  * Extract the module name from the path. Just use the base
162                  * name of the last path component.
163                  */
164
165                 SAFE_FREE(module_name);
166                 module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
167
168                 p = strchr_m(module_name, '.');
169
170                 if (p != NULL) {
171                         *p = '\0';
172                 }
173         }
174
175         /* First, try to load the module with the new module system */
176         entry = vfs_find_backend_entry(module_name);
177         if (!entry) {
178                 NTSTATUS status;
179
180                 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
181                           vfs_object));
182
183                 status = smb_load_module("vfs", module_path);
184                 if (!NT_STATUS_IS_OK(status)) {
185                         DEBUG(0, ("error probing vfs module '%s': %s\n",
186                                   module_path, nt_errstr(status)));
187                         goto fail;
188                 }
189
190                 entry = vfs_find_backend_entry(module_name);
191                 if (!entry) {
192                         DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
193                         goto fail;
194                 }
195         }
196
197         DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
198
199         handle = talloc_zero(conn, vfs_handle_struct);
200         if (!handle) {
201                 DEBUG(0,("TALLOC_ZERO() failed!\n"));
202                 goto fail;
203         }
204         handle->conn = conn;
205         handle->fns = entry->fns;
206         if (module_param) {
207                 handle->param = talloc_strdup(conn, module_param);
208         }
209         DLIST_ADD(conn->vfs_handles, handle);
210
211         SAFE_FREE(module_path);
212         SAFE_FREE(module_name);
213         return True;
214
215  fail:
216         SAFE_FREE(module_path);
217         SAFE_FREE(module_name);
218         return False;
219 }
220
221 /*****************************************************************
222  Allow VFS modules to extend files_struct with VFS-specific state.
223  This will be ok for small numbers of extensions, but might need to
224  be refactored if it becomes more widely used.
225 ******************************************************************/
226
227 #define EXT_DATA_AREA(e) ((uint8_t *)(e) + sizeof(struct vfs_fsp_data))
228
229 void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle,
230                                    files_struct *fsp, size_t ext_size,
231                                    void (*destroy_fn)(void *p_data))
232 {
233         struct vfs_fsp_data *ext;
234         void * ext_data;
235
236         /* Prevent VFS modules adding multiple extensions. */
237         if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
238                 return ext_data;
239         }
240
241         ext = talloc_zero_size(
242                 handle->conn, sizeof(struct vfs_fsp_data) + ext_size);
243         if (ext == NULL) {
244                 return NULL;
245         }
246
247         ext->owner = handle;
248         ext->next = fsp->vfs_extension;
249         ext->destroy = destroy_fn;
250         fsp->vfs_extension = ext;
251         return EXT_DATA_AREA(ext);
252 }
253
254 void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
255 {
256         struct vfs_fsp_data *curr;
257         struct vfs_fsp_data *prev;
258
259         for (curr = fsp->vfs_extension, prev = NULL;
260              curr;
261              prev = curr, curr = curr->next) {
262                 if (curr->owner == handle) {
263                     if (prev) {
264                             prev->next = curr->next;
265                     } else {
266                             fsp->vfs_extension = curr->next;
267                     }
268                     if (curr->destroy) {
269                             curr->destroy(EXT_DATA_AREA(curr));
270                     }
271                     TALLOC_FREE(curr);
272                     return;
273                 }
274         }
275 }
276
277 void vfs_remove_all_fsp_extensions(files_struct *fsp)
278 {
279         struct vfs_fsp_data *curr;
280         struct vfs_fsp_data *next;
281
282         for (curr = fsp->vfs_extension; curr; curr = next) {
283
284                 next = curr->next;
285                 fsp->vfs_extension = next;
286
287                 if (curr->destroy) {
288                         curr->destroy(EXT_DATA_AREA(curr));
289                 }
290                 TALLOC_FREE(curr);
291         }
292 }
293
294 void *vfs_memctx_fsp_extension(vfs_handle_struct *handle,
295                                const struct files_struct *fsp)
296 {
297         struct vfs_fsp_data *head;
298
299         for (head = fsp->vfs_extension; head; head = head->next) {
300                 if (head->owner == handle) {
301                         return head;
302                 }
303         }
304
305         return NULL;
306 }
307
308 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle,
309                               const struct files_struct *fsp)
310 {
311         struct vfs_fsp_data *head;
312
313         head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
314         if (head != NULL) {
315                 return EXT_DATA_AREA(head);
316         }
317
318         return NULL;
319 }
320
321 #undef EXT_DATA_AREA
322
323 /*
324  * Ensure this module catches all VFS functions.
325  */
326 #ifdef DEVELOPER
327 void smb_vfs_assert_all_fns(const struct vfs_fn_pointers* fns,
328                             const char *module)
329 {
330         bool missing_fn = false;
331         unsigned int idx;
332         const uintptr_t *end = (const uintptr_t *)(fns + 1);
333
334         for (idx = 0; ((const uintptr_t *)fns + idx) < end; idx++) {
335                 if (*((const uintptr_t *)fns + idx) == 0) {
336                         DBG_ERR("VFS function at index %d not implemented "
337                                 "in module %s\n", idx, module);
338                         missing_fn = true;
339                 }
340         }
341
342         if (missing_fn) {
343                 smb_panic("Required VFS function not implemented in module.\n");
344         }
345 }
346 #else
347 void smb_vfs_assert_all_fns(const struct vfs_fn_pointers* fns,
348                             const char *module)
349 {
350 }
351 #endif
352
353 /*****************************************************************
354  Generic VFS init.
355 ******************************************************************/
356
357 bool smbd_vfs_init(connection_struct *conn)
358 {
359         const char **vfs_objects;
360         unsigned int i = 0;
361         int j = 0;
362
363         /* Normal share - initialise with disk access functions */
364         vfs_init_default(conn);
365
366         /* No need to load vfs modules for printer connections */
367         if (conn->printer) {
368                 return True;
369         }
370
371         if (lp_widelinks(SNUM(conn))) {
372                 /*
373                  * As the widelinks logic is now moving into a
374                  * vfs_widelinks module, we need to custom load
375                  * it after the default module is initialized.
376                  * That way no changes to smb.conf files are
377                  * needed.
378                  */
379                 bool ok = vfs_init_custom(conn, "widelinks");
380                 if (!ok) {
381                         DBG_ERR("widelinks enabled and vfs_init_custom "
382                                 "failed for vfs_widelinks module\n");
383                         return false;
384                 }
385         }
386
387         vfs_objects = lp_vfs_objects(SNUM(conn));
388
389         /* Override VFS functions if 'vfs object' was not specified*/
390         if (!vfs_objects || !vfs_objects[0])
391                 return True;
392
393         for (i=0; vfs_objects[i] ;) {
394                 i++;
395         }
396
397         for (j=i-1; j >= 0; j--) {
398                 if (!vfs_init_custom(conn, vfs_objects[j])) {
399                         DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
400                         return False;
401                 }
402         }
403         return True;
404 }
405
406 /*******************************************************************
407  Check if a file exists in the vfs.
408 ********************************************************************/
409
410 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
411 {
412         /* Only return OK if stat was successful and S_ISREG */
413         if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
414             S_ISREG(smb_fname->st.st_ex_mode)) {
415                 return NT_STATUS_OK;
416         }
417
418         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
419 }
420
421 bool vfs_valid_pread_range(off_t offset, size_t length)
422 {
423         return sys_valid_io_range(offset, length);
424 }
425
426 bool vfs_valid_pwrite_range(off_t offset, size_t length)
427 {
428         /*
429          * See MAXFILESIZE in [MS-FSA] 2.1.5.3 Server Requests a Write
430          */
431         static const uint64_t maxfilesize = 0xfffffff0000;
432         uint64_t last_byte_ofs;
433         bool ok;
434
435         ok = sys_valid_io_range(offset, length);
436         if (!ok) {
437                 return false;
438         }
439
440         if (length == 0) {
441                 return true;
442         }
443
444         last_byte_ofs = offset + length;
445         if (last_byte_ofs > maxfilesize) {
446                 return false;
447         }
448
449         return true;
450 }
451
452 ssize_t vfs_pwrite_data(struct smb_request *req,
453                         files_struct *fsp,
454                         const char *buffer,
455                         size_t N,
456                         off_t offset)
457 {
458         size_t total=0;
459         ssize_t ret;
460         bool ok;
461
462         ok = vfs_valid_pwrite_range(offset, N);
463         if (!ok) {
464                 errno = EINVAL;
465                 return -1;
466         }
467
468         if (req && req->unread_bytes) {
469                 int sockfd = req->xconn->transport.sock;
470                 SMB_ASSERT(req->unread_bytes == N);
471                 /* VFS_RECVFILE must drain the socket
472                  * before returning. */
473                 req->unread_bytes = 0;
474                 /*
475                  * Leave the socket non-blocking and
476                  * use SMB_VFS_RECVFILE. If it returns
477                  * EAGAIN || EWOULDBLOCK temporarily set
478                  * the socket blocking and retry
479                  * the RECVFILE.
480                  */
481                 while (total < N) {
482                         ret = SMB_VFS_RECVFILE(sockfd,
483                                                 fsp,
484                                                 offset + total,
485                                                 N - total);
486                         if (ret == 0 || (ret == -1 &&
487                                          (errno == EAGAIN ||
488                                           errno == EWOULDBLOCK))) {
489                                 int old_flags;
490                                 /* Ensure the socket is blocking. */
491                                 old_flags = fcntl(sockfd, F_GETFL, 0);
492                                 if (set_blocking(sockfd, true) == -1) {
493                                         return (ssize_t)-1;
494                                 }
495                                 ret = SMB_VFS_RECVFILE(sockfd,
496                                                         fsp,
497                                                         offset + total,
498                                                         N - total);
499                                 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
500                                         return (ssize_t)-1;
501                                 }
502                                 if (ret == -1) {
503                                         return (ssize_t)-1;
504                                 }
505                                 total += ret;
506                                 return (ssize_t)total;
507                         }
508                         /* Any other error case. */
509                         if (ret == -1) {
510                                 return ret;
511                         }
512                         total += ret;
513                 }
514                 return (ssize_t)total;
515         }
516
517         while (total < N) {
518                 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
519                                      offset + total);
520
521                 if (ret == -1)
522                         return -1;
523                 if (ret == 0)
524                         return total;
525
526                 total += ret;
527         }
528         return (ssize_t)total;
529 }
530 /****************************************************************************
531  An allocate file space call using the vfs interface.
532  Allocates space for a file from a filedescriptor.
533  Returns 0 on success, -1 on failure.
534 ****************************************************************************/
535
536 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
537 {
538         int ret;
539         connection_struct *conn = fsp->conn;
540         uint64_t space_avail;
541         uint64_t bsize,dfree,dsize;
542         NTSTATUS status;
543         bool ok;
544
545         /*
546          * Actually try and commit the space on disk....
547          */
548
549         DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
550                   fsp_str_dbg(fsp), (double)len));
551
552         ok = vfs_valid_pwrite_range((off_t)len, 0);
553         if (!ok) {
554                 DEBUG(0,("vfs_allocate_file_space: %s negative/invalid len "
555                          "requested.\n", fsp_str_dbg(fsp)));
556                 errno = EINVAL;
557                 return -1;
558         }
559
560         status = vfs_stat_fsp(fsp);
561         if (!NT_STATUS_IS_OK(status)) {
562                 return -1;
563         }
564
565         if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
566                 return 0;
567
568         if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
569                 /* Shrink - use ftruncate. */
570
571                 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
572                           "size %.0f\n", fsp_str_dbg(fsp),
573                           (double)fsp->fsp_name->st.st_ex_size));
574
575                 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
576
577                 ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len);
578
579                 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
580
581                 return ret;
582         }
583
584         /* Grow - we need to test if we have enough space. */
585
586         contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
587
588         if (lp_strict_allocate(SNUM(fsp->conn))) {
589                 /* See if we have a syscall that will allocate beyond
590                    end-of-file without changing EOF. */
591                 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_FL_KEEP_SIZE,
592                                         0, len);
593         } else {
594                 ret = 0;
595         }
596
597         contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
598
599         if (ret == 0) {
600                 /* We changed the allocation size on disk, but not
601                    EOF - exactly as required. We're done ! */
602                 return 0;
603         }
604
605         if (ret == -1 && errno == ENOSPC) {
606                 return -1;
607         }
608
609         len -= fsp->fsp_name->st.st_ex_size;
610         len /= 1024; /* Len is now number of 1k blocks needed. */
611         space_avail =
612             get_dfree_info(conn, fsp->fsp_name, &bsize, &dfree, &dsize);
613         if (space_avail == (uint64_t)-1) {
614                 return -1;
615         }
616
617         DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
618                   "needed blocks = %.0f, space avail = %.0f\n",
619                   fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
620                   (double)space_avail));
621
622         if (len > space_avail) {
623                 errno = ENOSPC;
624                 return -1;
625         }
626
627         return 0;
628 }
629
630 /****************************************************************************
631  A vfs set_filelen call.
632  set the length of a file from a filedescriptor.
633  Returns 0 on success, -1 on failure.
634 ****************************************************************************/
635
636 int vfs_set_filelen(files_struct *fsp, off_t len)
637 {
638         int ret;
639         bool ok;
640
641         ok = vfs_valid_pwrite_range(len, 0);
642         if (!ok) {
643                 errno = EINVAL;
644                 return -1;
645         }
646
647         contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
648
649         DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
650                   fsp_str_dbg(fsp), (double)len));
651         if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
652                 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
653                              FILE_NOTIFY_CHANGE_SIZE
654                              | FILE_NOTIFY_CHANGE_ATTRIBUTES,
655                              fsp->fsp_name->base_name);
656         }
657
658         contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
659
660         return ret;
661 }
662
663 /****************************************************************************
664  A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
665  fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
666  as this is also called from the default SMB_VFS_FTRUNCATE code.
667  Always extends the file size.
668  Returns 0 on success, -1 on failure.
669 ****************************************************************************/
670
671 #define SPARSE_BUF_WRITE_SIZE (32*1024)
672
673 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
674 {
675         ssize_t pwrite_ret;
676         size_t total = 0;
677         bool ok;
678
679         ok = vfs_valid_pwrite_range(offset, len);
680         if (!ok) {
681                 errno = EINVAL;
682                 return -1;
683         }
684
685         if (!sparse_buf) {
686                 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
687                 if (!sparse_buf) {
688                         errno = ENOMEM;
689                         return -1;
690                 }
691         }
692
693         while (total < len) {
694                 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
695
696                 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
697                 if (pwrite_ret == -1) {
698                         int saved_errno = errno;
699                         DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
700                                   "%s failed with error %s\n",
701                                   fsp_str_dbg(fsp), strerror(saved_errno)));
702                         errno = saved_errno;
703                         return -1;
704                 }
705                 total += pwrite_ret;
706         }
707
708         return 0;
709 }
710
711 /****************************************************************************
712  A vfs fill sparse call.
713  Writes zeros from the end of file to len, if len is greater than EOF.
714  Used only by strict_sync.
715  Returns 0 on success, -1 on failure.
716 ****************************************************************************/
717
718 int vfs_fill_sparse(files_struct *fsp, off_t len)
719 {
720         int ret;
721         NTSTATUS status;
722         off_t offset;
723         size_t num_to_write;
724         bool ok;
725
726         ok = vfs_valid_pwrite_range(len, 0);
727         if (!ok) {
728                 errno = EINVAL;
729                 return -1;
730         }
731
732         status = vfs_stat_fsp(fsp);
733         if (!NT_STATUS_IS_OK(status)) {
734                 return -1;
735         }
736
737         if (len <= fsp->fsp_name->st.st_ex_size) {
738                 return 0;
739         }
740
741 #ifdef S_ISFIFO
742         if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
743                 return 0;
744         }
745 #endif
746
747         DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
748                   "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
749                   (double)fsp->fsp_name->st.st_ex_size, (double)len,
750                   (double)(len - fsp->fsp_name->st.st_ex_size)));
751
752         contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
753
754         offset = fsp->fsp_name->st.st_ex_size;
755         num_to_write = len - fsp->fsp_name->st.st_ex_size;
756
757         /* Only do this on non-stream file handles. */
758         if (fsp->base_fsp == NULL) {
759                 /* for allocation try fallocate first. This can fail on some
760                  * platforms e.g. when the filesystem doesn't support it and no
761                  * emulation is being done by the libc (like on AIX with JFS1). In that
762                  * case we do our own emulation. fallocate implementations can
763                  * return ENOTSUP or EINVAL in cases like that. */
764                 ret = SMB_VFS_FALLOCATE(fsp, 0, offset, num_to_write);
765                 if (ret == -1 && errno == ENOSPC) {
766                         goto out;
767                 }
768                 if (ret == 0) {
769                         goto out;
770                 }
771                 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
772                         "error %d. Falling back to slow manual allocation\n", ret));
773         }
774
775         ret = vfs_slow_fallocate(fsp, offset, num_to_write);
776
777  out:
778
779         contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
780         return ret;
781 }
782
783 /*******************************************************************************
784  Set a fd into blocking/nonblocking mode through VFS
785 *******************************************************************************/
786
787 int vfs_set_blocking(files_struct *fsp, bool set)
788 {
789         int val;
790 #ifdef O_NONBLOCK
791 #define FLAG_TO_SET O_NONBLOCK
792 #else
793 #ifdef SYSV
794 #define FLAG_TO_SET O_NDELAY
795 #else /* BSD */
796 #define FLAG_TO_SET FNDELAY
797 #endif
798 #endif
799
800         if (fsp->fsp_flags.is_pathref) {
801                 return 0;
802         }
803
804         val = SMB_VFS_FCNTL(fsp, F_GETFL, 0);
805         if (val == -1) {
806                 return -1;
807         }
808
809         if (set) {
810                 val &= ~FLAG_TO_SET;
811         } else {
812                 val |= FLAG_TO_SET;
813         }
814
815         return SMB_VFS_FCNTL(fsp, F_SETFL, val);
816 #undef FLAG_TO_SET
817 }
818
819 /****************************************************************************
820  Transfer some data (n bytes) between two file_struct's.
821 ****************************************************************************/
822
823 static ssize_t vfs_pread_fn(void *file, void *buf, size_t len, off_t offset)
824 {
825         struct files_struct *fsp = (struct files_struct *)file;
826
827         return SMB_VFS_PREAD(fsp, buf, len, offset);
828 }
829
830 static ssize_t vfs_pwrite_fn(void *file, const void *buf, size_t len, off_t offset)
831 {
832         struct files_struct *fsp = (struct files_struct *)file;
833
834         return SMB_VFS_PWRITE(fsp, buf, len, offset);
835 }
836
837 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
838 {
839         return transfer_file_internal((void *)in, (void *)out, n,
840                                       vfs_pread_fn, vfs_pwrite_fn);
841 }
842
843 /*******************************************************************
844  A vfs_readdir wrapper which just returns the file name.
845 ********************************************************************/
846
847 const char *vfs_readdirname(connection_struct *conn,
848                             struct files_struct *dirfsp,
849                             void *p,
850                             SMB_STRUCT_STAT *sbuf,
851                             char **talloced)
852 {
853         struct dirent *ptr= NULL;
854         const char *dname;
855         char *translated;
856         NTSTATUS status;
857
858         if (!p)
859                 return(NULL);
860
861         ptr = SMB_VFS_READDIR(conn, dirfsp, (DIR *)p, sbuf);
862         if (!ptr)
863                 return(NULL);
864
865         dname = ptr->d_name;
866
867         status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
868                                         talloc_tos(), &translated);
869         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
870                 *talloced = NULL;
871                 return dname;
872         }
873         *talloced = translated;
874         if (!NT_STATUS_IS_OK(status)) {
875                 return NULL;
876         }
877         return translated;
878 }
879
880 /*******************************************************************
881  A wrapper for vfs_chdir().
882 ********************************************************************/
883
884 int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
885 {
886         int ret;
887         struct smb_filename *cwd = NULL;
888
889         if (!LastDir) {
890                 LastDir = SMB_STRDUP("");
891         }
892
893         if (ISDOT(smb_fname->base_name)) {
894                 /*
895                  * passing a '.' is a noop,
896                  * and we only expect this after
897                  * everything is initialized.
898                  *
899                  * So the first vfs_ChDir() on a given
900                  * connection_struct must not be '.'.
901                  *
902                  * Note: conn_new() sets
903                  * conn->cwd_fsp->fh->fd = -1
904                  * and vfs_ChDir() leaves with
905                  * conn->cwd_fsp->fh->fd = AT_FDCWD
906                  * on success!
907                  */
908                 if (fsp_get_pathref_fd(conn->cwd_fsp) != AT_FDCWD) {
909                         /*
910                          * This should never happen and
911                          * we might change this to
912                          * SMB_ASSERT() in future.
913                          */
914                         DBG_ERR("Called with '.' as first operation!\n");
915                         log_stack_trace();
916                         errno = EINVAL;
917                         return -1;
918                 }
919                 return 0;
920         }
921
922         if (smb_fname->base_name[0] == '/' &&
923             strcsequal(LastDir,smb_fname->base_name))
924         {
925                 /*
926                  * conn->cwd_fsp->fsp_name and the kernel
927                  * are already correct, but conn->cwd_fsp->fh->fd
928                  * might still be -1 as initialized in conn_new().
929                  *
930                  * This can happen when a client made a 2nd
931                  * tree connect to a share with the same underlying
932                  * path (may or may not the same share).
933                  */
934                 fsp_set_fd(conn->cwd_fsp, AT_FDCWD);
935                 return 0;
936         }
937
938         DEBUG(4,("vfs_ChDir to %s\n", smb_fname->base_name));
939
940         ret = SMB_VFS_CHDIR(conn, smb_fname);
941         if (ret != 0) {
942                 return -1;
943         }
944
945         /*
946          * Always replace conn->cwd_fsp. We
947          * don't know if it's been modified by
948          * VFS modules in the stack.
949          */
950
951         /* conn cache. */
952         cwd = vfs_GetWd(conn, conn);
953         if (cwd == NULL) {
954                 /*
955                  * vfs_GetWd() failed.
956                  * We must be able to read cwd.
957                  * Return to original directory
958                  * and return -1.
959                  */
960                 int saved_errno = errno;
961
962                 if (conn->cwd_fsp->fsp_name == NULL) {
963                         /*
964                          * Failed on the very first chdir()+getwd()
965                          * for this connection. We can't
966                          * continue.
967                          */
968                         smb_panic("conn->cwd getwd failed\n");
969                         /* NOTREACHED */
970                         return -1;
971                 }
972
973                 /* Return to the previous $cwd. */
974                 ret = SMB_VFS_CHDIR(conn, conn->cwd_fsp->fsp_name);
975                 if (ret != 0) {
976                         smb_panic("conn->cwd getwd failed\n");
977                         /* NOTREACHED */
978                         return -1;
979                 }
980                 errno = saved_errno;
981                 /* And fail the chdir(). */
982                 return -1;
983         }
984
985         /* vfs_GetWd() succeeded. */
986         /* Replace global cache. */
987         SAFE_FREE(LastDir);
988         LastDir = SMB_STRDUP(smb_fname->base_name);
989
990         /*
991          * (Indirect) Callers of vfs_ChDir() may still hold references to the
992          * old conn->cwd_fsp->fsp_name. Move it to talloc_tos(), that way
993          * callers can use it for the lifetime of the SMB request.
994          */
995         talloc_move(talloc_tos(), &conn->cwd_fsp->fsp_name);
996
997         conn->cwd_fsp->fsp_name = talloc_move(conn->cwd_fsp, &cwd);
998         fsp_set_fd(conn->cwd_fsp, AT_FDCWD);
999
1000         DBG_INFO("vfs_ChDir got %s\n", fsp_str_dbg(conn->cwd_fsp));
1001
1002         return ret;
1003 }
1004
1005 /*******************************************************************
1006  Return the absolute current directory path - given a UNIX pathname.
1007  Note that this path is returned in DOS format, not UNIX
1008  format. Note this can be called with conn == NULL.
1009 ********************************************************************/
1010
1011 struct smb_filename *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
1012 {
1013         struct smb_filename *current_dir_fname = NULL;
1014         struct file_id key;
1015         struct smb_filename *smb_fname_dot = NULL;
1016         struct smb_filename *smb_fname_full = NULL;
1017         struct smb_filename *result = NULL;
1018
1019         if (!lp_getwd_cache()) {
1020                 goto nocache;
1021         }
1022
1023         smb_fname_dot = synthetic_smb_fname(ctx,
1024                                             ".",
1025                                             NULL,
1026                                             NULL,
1027                                             0,
1028                                             0);
1029         if (smb_fname_dot == NULL) {
1030                 errno = ENOMEM;
1031                 goto out;
1032         }
1033
1034         if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
1035                 /*
1036                  * Known to fail for root: the directory may be NFS-mounted
1037                  * and exported with root_squash (so has no root access).
1038                  */
1039                 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
1040                          "(NFS problem ?)\n", strerror(errno) ));
1041                 goto nocache;
1042         }
1043
1044         key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
1045
1046         smb_fname_full = (struct smb_filename *)memcache_lookup_talloc(
1047                                         smbd_memcache(),
1048                                         GETWD_CACHE,
1049                                         data_blob_const(&key, sizeof(key)));
1050
1051         if (smb_fname_full == NULL) {
1052                 goto nocache;
1053         }
1054
1055         if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
1056             (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
1057             (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
1058             (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
1059                 /*
1060                  * Ok, we're done
1061                  * Note: smb_fname_full is owned by smbd_memcache()
1062                  * so we must make a copy to return.
1063                  */
1064                 result = cp_smb_filename(ctx, smb_fname_full);
1065                 if (result == NULL) {
1066                         errno = ENOMEM;
1067                 }
1068                 goto out;
1069         }
1070
1071  nocache:
1072
1073         /*
1074          * We don't have the information to hand so rely on traditional
1075          * methods. The very slow getcwd, which spawns a process on some
1076          * systems, or the not quite so bad getwd.
1077          */
1078
1079         current_dir_fname = SMB_VFS_GETWD(conn, ctx);
1080         if (current_dir_fname == NULL) {
1081                 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
1082                           strerror(errno)));
1083                 goto out;
1084         }
1085
1086         if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
1087                 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
1088
1089                 /*
1090                  * smbd_memcache() will own current_dir_fname after the
1091                  * memcache_add_talloc call, so we must make
1092                  * a copy on ctx to return.
1093                  */
1094                 result = cp_smb_filename(ctx, current_dir_fname);
1095                 if (result == NULL) {
1096                         errno = ENOMEM;
1097                 }
1098
1099                 /*
1100                  * Ensure the memory going into the cache
1101                  * doesn't have a destructor so it can be
1102                  * cleanly freed.
1103                  */
1104                 talloc_set_destructor(current_dir_fname, NULL);
1105
1106                 memcache_add_talloc(smbd_memcache(),
1107                                 GETWD_CACHE,
1108                                 data_blob_const(&key, sizeof(key)),
1109                                 &current_dir_fname);
1110                 /* current_dir_fname is now == NULL here. */
1111         } else {
1112                 /* current_dir_fname is already allocated on ctx. */
1113                 result = current_dir_fname;
1114         }
1115
1116  out:
1117         TALLOC_FREE(smb_fname_dot);
1118         /*
1119          * Don't free current_dir_fname here. It's either been moved
1120          * to the memcache or is being returned in result.
1121          */
1122         return result;
1123 }
1124
1125 /*******************************************************************
1126  Reduce a file name, removing .. elements and checking that
1127  it is below dir in the hierarchy. This uses realpath.
1128  This function must run as root, and will return names
1129  and valid stat structs that can be checked on open.
1130 ********************************************************************/
1131
1132 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
1133                         const struct smb_filename *smb_fname,
1134                         struct smb_request *smbreq)
1135 {
1136         NTSTATUS status;
1137         TALLOC_CTX *ctx = talloc_tos();
1138         const char *conn_rootdir;
1139         size_t rootdir_len;
1140         char *resolved_name = NULL;
1141         struct smb_filename *resolved_fname = NULL;
1142         struct smb_filename *saved_dir_fname = NULL;
1143         struct smb_filename *smb_fname_cwd = NULL;
1144         int ret;
1145         struct smb_filename *parent_name = NULL;
1146         struct smb_filename *file_name = NULL;
1147         bool ok;
1148
1149         DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
1150                         smb_fname->base_name,
1151                         conn->connectpath));
1152
1153
1154         ok = parent_smb_fname(ctx,
1155                               smb_fname,
1156                               &parent_name,
1157                               &file_name);
1158         if (!ok) {
1159                 status = NT_STATUS_NO_MEMORY;
1160                 goto err;
1161         }
1162
1163         if (SMB_VFS_STAT(conn, parent_name) != 0) {
1164                 status = map_nt_error_from_unix(errno);
1165                 goto err;
1166         }
1167         /* Remember where we were. */
1168         saved_dir_fname = vfs_GetWd(ctx, conn);
1169         if (!saved_dir_fname) {
1170                 status = map_nt_error_from_unix(errno);
1171                 goto err;
1172         }
1173
1174         if (vfs_ChDir(conn, parent_name) == -1) {
1175                 status = map_nt_error_from_unix(errno);
1176                 goto err;
1177         }
1178
1179         smb_fname_cwd = synthetic_smb_fname(talloc_tos(),
1180                                             ".",
1181                                             NULL,
1182                                             NULL,
1183                                             parent_name->twrp,
1184                                             0);
1185         if (smb_fname_cwd == NULL) {
1186                 status = NT_STATUS_NO_MEMORY;
1187                 goto err;
1188         }
1189
1190         /* Get the absolute path of the parent directory. */
1191         resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname_cwd);
1192         if (resolved_fname == NULL) {
1193                 status = map_nt_error_from_unix(errno);
1194                 goto err;
1195         }
1196         resolved_name = resolved_fname->base_name;
1197
1198         if (*resolved_name != '/') {
1199                 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1200                         "doesn't return absolute paths !\n"));
1201                 status = NT_STATUS_OBJECT_NAME_INVALID;
1202                 goto err;
1203         }
1204
1205         DBG_DEBUG("realpath [%s] -> [%s]\n",
1206                   smb_fname_str_dbg(parent_name),
1207                   resolved_name);
1208
1209         /* Now check the stat value is the same. */
1210         if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1211                 status = map_nt_error_from_unix(errno);
1212                 goto err;
1213         }
1214
1215         /* Ensure we're pointing at the same place. */
1216         if (!check_same_stat(&smb_fname_cwd->st, &parent_name->st)) {
1217                 DBG_ERR("device/inode/uid/gid on directory %s changed. "
1218                         "Denying access !\n",
1219                         smb_fname_str_dbg(parent_name));
1220                 status = NT_STATUS_ACCESS_DENIED;
1221                 goto err;
1222         }
1223
1224         /* Ensure we're below the connect path. */
1225
1226         conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
1227         if (conn_rootdir == NULL) {
1228                 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1229                         "conn_rootdir\n"));
1230                 status = NT_STATUS_ACCESS_DENIED;
1231                 goto err;
1232         }
1233
1234         rootdir_len = strlen(conn_rootdir);
1235
1236         /*
1237          * In the case of rootdir_len == 1, we know that conn_rootdir is
1238          * "/", and we also know that resolved_name starts with a slash.
1239          * So, in this corner case, resolved_name is automatically a
1240          * sub-directory of the conn_rootdir. Thus we can skip the string
1241          * comparison and the next character checks (which are even
1242          * wrong in this case).
1243          */
1244         if (rootdir_len != 1) {
1245                 bool matched;
1246
1247                 matched = (strncmp(conn_rootdir, resolved_name,
1248                                 rootdir_len) == 0);
1249
1250                 if (!matched || (resolved_name[rootdir_len] != '/' &&
1251                                  resolved_name[rootdir_len] != '\0')) {
1252                         DBG_WARNING("%s is a symlink outside the "
1253                                     "share path\n",
1254                                     smb_fname_str_dbg(parent_name));
1255                         DEBUGADD(1, ("conn_rootdir =%s\n", conn_rootdir));
1256                         DEBUGADD(1, ("resolved_name=%s\n", resolved_name));
1257                         status = NT_STATUS_ACCESS_DENIED;
1258                         goto err;
1259                 }
1260         }
1261
1262         /* Now ensure that the last component either doesn't
1263            exist, or is *NOT* a symlink. */
1264
1265         ret = SMB_VFS_LSTAT(conn, file_name);
1266         if (ret == -1) {
1267                 /* Errno must be ENOENT for this be ok. */
1268                 if (errno != ENOENT) {
1269                         status = map_nt_error_from_unix(errno);
1270                         DBG_WARNING("LSTAT on %s failed with %s\n",
1271                                     smb_fname_str_dbg(file_name),
1272                                     nt_errstr(status));
1273                         goto err;
1274                 }
1275         }
1276
1277         if (VALID_STAT(file_name->st) &&
1278             S_ISLNK(file_name->st.st_ex_mode))
1279         {
1280                 DBG_WARNING("Last component %s is a symlink. Denying"
1281                             "access.\n",
1282                             smb_fname_str_dbg(file_name));
1283                 status = NT_STATUS_ACCESS_DENIED;
1284                 goto err;
1285         }
1286
1287         status = NT_STATUS_OK;
1288
1289   err:
1290
1291         if (saved_dir_fname != NULL) {
1292                 vfs_ChDir(conn, saved_dir_fname);
1293                 TALLOC_FREE(saved_dir_fname);
1294         }
1295         TALLOC_FREE(resolved_fname);
1296         TALLOC_FREE(parent_name);
1297         return status;
1298 }
1299
1300 /*******************************************************************
1301  Reduce a file name, removing .. elements and checking that
1302  it is below dir in the hierarchy. This uses realpath.
1303
1304  If cwd_name == NULL then fname is a client given path relative
1305  to the root path of the share.
1306
1307  If cwd_name != NULL then fname is a client given path relative
1308  to cwd_name. cwd_name is relative to the root path of the share.
1309 ********************************************************************/
1310
1311 NTSTATUS check_reduced_name(connection_struct *conn,
1312                                 const struct smb_filename *cwd_fname,
1313                                 const struct smb_filename *smb_fname)
1314 {
1315         TALLOC_CTX *ctx = talloc_tos();
1316         const char *cwd_name = cwd_fname ? cwd_fname->base_name : NULL;
1317         const char *fname = smb_fname->base_name;
1318         struct smb_filename *resolved_fname;
1319         char *resolved_name = NULL;
1320         char *new_fname = NULL;
1321         bool allow_symlinks = true;
1322         const char *conn_rootdir;
1323         size_t rootdir_len;
1324         bool ok;
1325
1326         DBG_DEBUG("check_reduced_name [%s] [%s]\n", fname, conn->connectpath);
1327
1328         resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname);
1329
1330         if (resolved_fname == NULL) {
1331                 struct smb_filename *dir_fname = NULL;
1332                 struct smb_filename *last_component = NULL;
1333
1334                 if (errno == ENOTDIR) {
1335                         DBG_NOTICE("Component not a directory in getting "
1336                                    "realpath for %s\n",
1337                                    fname);
1338                         return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1339                 }
1340                 if (errno != ENOENT) {
1341                         NTSTATUS status = map_nt_error_from_unix(errno);
1342                         DBG_NOTICE("couldn't get realpath for %s: %s\n",
1343                                    fname,
1344                                    strerror(errno));
1345                         return status;
1346                 }
1347
1348                 /* errno == ENOENT */
1349
1350                 /*
1351                  * Last component didn't exist. Remove it and try and
1352                  * canonicalise the directory name.
1353                  */
1354
1355                 ok = parent_smb_fname(ctx,
1356                                       smb_fname,
1357                                       &dir_fname,
1358                                       &last_component);
1359                 if (!ok) {
1360                         return NT_STATUS_NO_MEMORY;
1361                 }
1362
1363                 resolved_fname = SMB_VFS_REALPATH(conn, ctx, dir_fname);
1364                 if (resolved_fname == NULL) {
1365                         NTSTATUS status = map_nt_error_from_unix(errno);
1366
1367                         if (errno == ENOENT || errno == ENOTDIR) {
1368                                 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1369                         }
1370
1371                         DBG_NOTICE("couldn't get realpath for "
1372                                    "%s (%s)\n",
1373                                    smb_fname_str_dbg(dir_fname),
1374                                    nt_errstr(status));
1375                         return status;
1376                 }
1377                 resolved_name = talloc_asprintf(ctx,
1378                                                 "%s/%s",
1379                                                 resolved_fname->base_name,
1380                                                 last_component->base_name);
1381                 if (resolved_name == NULL) {
1382                         return NT_STATUS_NO_MEMORY;
1383                 }
1384         } else {
1385                 resolved_name = resolved_fname->base_name;
1386         }
1387
1388         DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1389                   resolved_name));
1390
1391         if (*resolved_name != '/') {
1392                 DEBUG(0,("check_reduced_name: realpath doesn't return "
1393                          "absolute paths !\n"));
1394                 TALLOC_FREE(resolved_fname);
1395                 return NT_STATUS_OBJECT_NAME_INVALID;
1396         }
1397
1398         /* Common widelinks and symlinks checks. */
1399         conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
1400         if (conn_rootdir == NULL) {
1401                 DBG_NOTICE("Could not get conn_rootdir\n");
1402                 TALLOC_FREE(resolved_fname);
1403                 return NT_STATUS_ACCESS_DENIED;
1404         }
1405
1406         rootdir_len = strlen(conn_rootdir);
1407
1408         /*
1409          * In the case of rootdir_len == 1, we know that
1410          * conn_rootdir is "/", and we also know that
1411          * resolved_name starts with a slash.  So, in this
1412          * corner case, resolved_name is automatically a
1413          * sub-directory of the conn_rootdir. Thus we can skip
1414          * the string comparison and the next character checks
1415          * (which are even wrong in this case).
1416          */
1417         if (rootdir_len != 1) {
1418                 bool matched;
1419
1420                 matched = (strncmp(conn_rootdir, resolved_name,
1421                                 rootdir_len) == 0);
1422                 if (!matched || (resolved_name[rootdir_len] != '/' &&
1423                                  resolved_name[rootdir_len] != '\0')) {
1424                         DBG_NOTICE("Bad access attempt: %s is a symlink "
1425                                 "outside the "
1426                                 "share path\n"
1427                                 "conn_rootdir =%s\n"
1428                                 "resolved_name=%s\n",
1429                                 fname,
1430                                 conn_rootdir,
1431                                 resolved_name);
1432                         TALLOC_FREE(resolved_fname);
1433                         return NT_STATUS_ACCESS_DENIED;
1434                 }
1435         }
1436
1437         /* Extra checks if all symlinks are disallowed. */
1438         allow_symlinks = lp_follow_symlinks(SNUM(conn));
1439         if (!allow_symlinks) {
1440                 /* fname can't have changed in resolved_path. */
1441                 const char *p = &resolved_name[rootdir_len];
1442
1443                 /*
1444                  * UNIX filesystem semantics, names consisting
1445                  * only of "." or ".." CANNOT be symlinks.
1446                  */
1447                 if (ISDOT(fname) || ISDOTDOT(fname)) {
1448                         goto out;
1449                 }
1450
1451                 if (*p != '/') {
1452                         DBG_NOTICE("logic error (%c) "
1453                                 "in resolved_name: %s\n",
1454                                 *p,
1455                                 fname);
1456                         TALLOC_FREE(resolved_fname);
1457                         return NT_STATUS_ACCESS_DENIED;
1458                 }
1459
1460                 p++;
1461
1462                 /*
1463                  * If cwd_name is present and not ".",
1464                  * then fname is relative to that, not
1465                  * the root of the share. Make sure the
1466                  * path we check is the one the client
1467                  * sent (cwd_name+fname).
1468                  */
1469                 if (cwd_name != NULL && !ISDOT(cwd_name)) {
1470                         new_fname = talloc_asprintf(ctx,
1471                                                 "%s/%s",
1472                                                 cwd_name,
1473                                                 fname);
1474                         if (new_fname == NULL) {
1475                                 TALLOC_FREE(resolved_fname);
1476                                 return NT_STATUS_NO_MEMORY;
1477                         }
1478                         fname = new_fname;
1479                 }
1480
1481                 if (strcmp(fname, p)!=0) {
1482                         DBG_NOTICE("Bad access "
1483                                 "attempt: %s is a symlink to %s\n",
1484                                 fname,
1485                                 p);
1486                         TALLOC_FREE(resolved_fname);
1487                         TALLOC_FREE(new_fname);
1488                         return NT_STATUS_ACCESS_DENIED;
1489                 }
1490         }
1491
1492   out:
1493
1494         DBG_INFO("%s reduced to %s\n", fname, resolved_name);
1495         TALLOC_FREE(resolved_fname);
1496         TALLOC_FREE(new_fname);
1497         return NT_STATUS_OK;
1498 }
1499
1500 /*
1501  * Ensure LSTAT is called for POSIX paths.
1502  */
1503 int vfs_stat(struct connection_struct *conn,
1504              struct smb_filename *smb_fname)
1505 {
1506         if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) {
1507                 return SMB_VFS_LSTAT(conn, smb_fname);
1508         }
1509         return SMB_VFS_STAT(conn, smb_fname);
1510 }
1511
1512 /**
1513  * XXX: This is temporary and there should be no callers of this once
1514  * smb_filename is plumbed through all path based operations.
1515  *
1516  * Called when we know stream name parsing has already been done.
1517  */
1518 int vfs_stat_smb_basename(struct connection_struct *conn,
1519                         const struct smb_filename *smb_fname_in,
1520                         SMB_STRUCT_STAT *psbuf)
1521 {
1522         struct smb_filename smb_fname = {
1523                 .base_name = discard_const_p(char, smb_fname_in->base_name),
1524                 .flags = smb_fname_in->flags,
1525                 .twrp = smb_fname_in->twrp,
1526         };
1527         int ret;
1528
1529         if (smb_fname.flags & SMB_FILENAME_POSIX_PATH) {
1530                 ret = SMB_VFS_LSTAT(conn, &smb_fname);
1531         } else {
1532                 ret = SMB_VFS_STAT(conn, &smb_fname);
1533         }
1534
1535         if (ret != -1) {
1536                 *psbuf = smb_fname.st;
1537         }
1538         return ret;
1539 }
1540
1541 /**
1542  * Ensure LSTAT is called for POSIX paths.
1543  */
1544
1545 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1546 {
1547         int ret;
1548         struct stat_ex saved_stat = fsp->fsp_name->st;
1549
1550         if (fsp_get_pathref_fd(fsp) == -1) {
1551                 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1552                         ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1553                 } else {
1554                         ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1555                 }
1556         } else {
1557                 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
1558         }
1559         if (ret == -1) {
1560                 return map_nt_error_from_unix(errno);
1561         }
1562         update_stat_ex_from_saved_stat(&fsp->fsp_name->st, &saved_stat);
1563         return NT_STATUS_OK;
1564 }
1565
1566 void init_smb_file_time(struct smb_file_time *ft)
1567 {
1568         *ft = (struct smb_file_time) {
1569                 .atime = make_omit_timespec(),
1570                 .ctime = make_omit_timespec(),
1571                 .mtime = make_omit_timespec(),
1572                 .create_time = make_omit_timespec()
1573         };
1574 }
1575
1576 /**
1577  * Initialize num_streams and streams, then call VFS op streaminfo
1578  */
1579 NTSTATUS vfs_streaminfo(connection_struct *conn,
1580                         struct files_struct *fsp,
1581                         const struct smb_filename *smb_fname,
1582                         TALLOC_CTX *mem_ctx,
1583                         unsigned int *num_streams,
1584                         struct stream_struct **streams)
1585 {
1586         *num_streams = 0;
1587         *streams = NULL;
1588         return SMB_VFS_STREAMINFO(conn,
1589                         fsp,
1590                         smb_fname,
1591                         mem_ctx,
1592                         num_streams,
1593                         streams);
1594 }
1595
1596 int vfs_fake_fd(void)
1597 {
1598         int pipe_fds[2];
1599         int ret;
1600
1601         /*
1602          * Return a valid fd, but ensure any attempt to use
1603          * it returns an error (EPIPE).
1604          */
1605         ret = pipe(pipe_fds);
1606         if (ret != 0) {
1607                 return -1;
1608         }
1609
1610         close(pipe_fds[1]);
1611         return pipe_fds[0];
1612 }
1613
1614 /*
1615  * This is just a helper to make
1616  * users of vfs_fake_fd() more symetric
1617  */
1618 int vfs_fake_fd_close(int fd)
1619 {
1620         return close(fd);
1621 }
1622
1623 /*
1624   generate a file_id from a stat structure
1625  */
1626 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1627 {
1628         return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1629 }
1630
1631 NTSTATUS vfs_at_fspcwd(TALLOC_CTX *mem_ctx,
1632                        struct connection_struct *conn,
1633                        struct files_struct **_fsp)
1634 {
1635         struct files_struct *fsp = NULL;
1636
1637         fsp = talloc_zero(mem_ctx, struct files_struct);
1638         if (fsp == NULL) {
1639                 return NT_STATUS_NO_MEMORY;
1640         }
1641
1642         fsp->fsp_name = synthetic_smb_fname(fsp, ".", NULL, NULL, 0, 0);
1643         if (fsp->fsp_name == NULL) {
1644                 TALLOC_FREE(fsp);
1645                 return NT_STATUS_NO_MEMORY;
1646         }
1647
1648         fsp->fh = fd_handle_create(fsp);
1649         if (fsp->fh == NULL) {
1650                 TALLOC_FREE(fsp);
1651                 return NT_STATUS_NO_MEMORY;
1652         }
1653
1654         fsp_set_fd(fsp, AT_FDCWD);
1655         fsp->fnum = FNUM_FIELD_INVALID;
1656         fsp->conn = conn;
1657
1658         *_fsp = fsp;
1659         return NT_STATUS_OK;
1660 }
1661
1662 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1663                          const char *service, const char *user)
1664 {
1665         VFS_FIND(connect);
1666         return handle->fns->connect_fn(handle, service, user);
1667 }
1668
1669 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1670 {
1671         VFS_FIND(disconnect);
1672         handle->fns->disconnect_fn(handle);
1673 }
1674
1675 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1676                                 const struct smb_filename *smb_fname,
1677                                 uint64_t *bsize,
1678                                 uint64_t *dfree,
1679                                 uint64_t *dsize)
1680 {
1681         VFS_FIND(disk_free);
1682         return handle->fns->disk_free_fn(handle, smb_fname,
1683                         bsize, dfree, dsize);
1684 }
1685
1686 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1687                                 const struct smb_filename *smb_fname,
1688                                 enum SMB_QUOTA_TYPE qtype,
1689                                 unid_t id,
1690                                 SMB_DISK_QUOTA *qt)
1691 {
1692         VFS_FIND(get_quota);
1693         return handle->fns->get_quota_fn(handle, smb_fname, qtype, id, qt);
1694 }
1695
1696 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1697                            enum SMB_QUOTA_TYPE qtype, unid_t id,
1698                            SMB_DISK_QUOTA *qt)
1699 {
1700         VFS_FIND(set_quota);
1701         return handle->fns->set_quota_fn(handle, qtype, id, qt);
1702 }
1703
1704 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1705                                       struct files_struct *fsp,
1706                                       struct shadow_copy_data *shadow_copy_data,
1707                                       bool labels)
1708 {
1709         VFS_FIND(get_shadow_copy_data);
1710         return handle->fns->get_shadow_copy_data_fn(handle, fsp, 
1711                                                     shadow_copy_data,
1712                                                     labels);
1713 }
1714 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle,
1715                         const struct smb_filename *smb_fname,
1716                         struct vfs_statvfs_struct *statbuf)
1717 {
1718         VFS_FIND(statvfs);
1719         return handle->fns->statvfs_fn(handle, smb_fname, statbuf);
1720 }
1721
1722 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1723                         enum timestamp_set_resolution *p_ts_res)
1724 {
1725         VFS_FIND(fs_capabilities);
1726         return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1727 }
1728
1729 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1730                                         struct dfs_GetDFSReferral *r)
1731 {
1732         VFS_FIND(get_dfs_referrals);
1733         return handle->fns->get_dfs_referrals_fn(handle, r);
1734 }
1735
1736 NTSTATUS smb_vfs_call_create_dfs_pathat(struct vfs_handle_struct *handle,
1737                                 struct files_struct *dirfsp,
1738                                 const struct smb_filename *smb_fname,
1739                                 const struct referral *reflist,
1740                                 size_t referral_count)
1741 {
1742         VFS_FIND(create_dfs_pathat);
1743         return handle->fns->create_dfs_pathat_fn(handle,
1744                                                 dirfsp,
1745                                                 smb_fname,
1746                                                 reflist,
1747                                                 referral_count);
1748 }
1749
1750 NTSTATUS smb_vfs_call_read_dfs_pathat(struct vfs_handle_struct *handle,
1751                                 TALLOC_CTX *mem_ctx,
1752                                 struct files_struct *dirfsp,
1753                                 struct smb_filename *smb_fname,
1754                                 struct referral **ppreflist,
1755                                 size_t *preferral_count)
1756 {
1757         VFS_FIND(read_dfs_pathat);
1758         return handle->fns->read_dfs_pathat_fn(handle,
1759                                                 mem_ctx,
1760                                                 dirfsp,
1761                                                 smb_fname,
1762                                                 ppreflist,
1763                                                 preferral_count);
1764 }
1765
1766 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1767                                         struct files_struct *fsp,
1768                                         const char *mask,
1769                                         uint32_t attributes)
1770 {
1771         VFS_FIND(fdopendir);
1772         return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1773 }
1774
1775 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1776                                     struct files_struct *dirfsp,
1777                                     DIR *dirp,
1778                                     SMB_STRUCT_STAT *sbuf)
1779 {
1780         VFS_FIND(readdir);
1781         return handle->fns->readdir_fn(handle, dirfsp, dirp, sbuf);
1782 }
1783
1784 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1785                           DIR *dirp, long offset)
1786 {
1787         VFS_FIND(seekdir);
1788         handle->fns->seekdir_fn(handle, dirp, offset);
1789 }
1790
1791 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1792                           DIR *dirp)
1793 {
1794         VFS_FIND(telldir);
1795         return handle->fns->telldir_fn(handle, dirp);
1796 }
1797
1798 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1799                              DIR *dirp)
1800 {
1801         VFS_FIND(rewind_dir);
1802         handle->fns->rewind_dir_fn(handle, dirp);
1803 }
1804
1805 int smb_vfs_call_mkdirat(struct vfs_handle_struct *handle,
1806                         struct files_struct *dirfsp,
1807                         const struct smb_filename *smb_fname,
1808                         mode_t mode)
1809 {
1810         VFS_FIND(mkdirat);
1811         return handle->fns->mkdirat_fn(handle,
1812                         dirfsp,
1813                         smb_fname,
1814                         mode);
1815 }
1816
1817 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1818                           DIR *dir)
1819 {
1820         VFS_FIND(closedir);
1821         return handle->fns->closedir_fn(handle, dir);
1822 }
1823
1824 int smb_vfs_call_openat(struct vfs_handle_struct *handle,
1825                         const struct files_struct *dirfsp,
1826                         const struct smb_filename *smb_fname,
1827                         struct files_struct *fsp,
1828                         int flags,
1829                         mode_t mode)
1830 {
1831         VFS_FIND(openat);
1832         return handle->fns->openat_fn(handle,
1833                                       dirfsp,
1834                                       smb_fname,
1835                                       fsp,
1836                                       flags,
1837                                       mode);
1838 }
1839
1840 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1841                                   struct smb_request *req,
1842                                   struct smb_filename *smb_fname,
1843                                   uint32_t access_mask,
1844                                   uint32_t share_access,
1845                                   uint32_t create_disposition,
1846                                   uint32_t create_options,
1847                                   uint32_t file_attributes,
1848                                   uint32_t oplock_request,
1849                                   const struct smb2_lease *lease,
1850                                   uint64_t allocation_size,
1851                                   uint32_t private_flags,
1852                                   struct security_descriptor *sd,
1853                                   struct ea_list *ea_list,
1854                                   files_struct **result,
1855                                   int *pinfo,
1856                                   const struct smb2_create_blobs *in_context_blobs,
1857                                   struct smb2_create_blobs *out_context_blobs)
1858 {
1859         VFS_FIND(create_file);
1860         return handle->fns->create_file_fn(
1861                 handle, req, smb_fname,
1862                 access_mask, share_access, create_disposition, create_options,
1863                 file_attributes, oplock_request, lease, allocation_size,
1864                 private_flags, sd, ea_list,
1865                 result, pinfo, in_context_blobs, out_context_blobs);
1866 }
1867
1868 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1869                        struct files_struct *fsp)
1870 {
1871         VFS_FIND(close);
1872         return handle->fns->close_fn(handle, fsp);
1873 }
1874
1875 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1876                            struct files_struct *fsp, void *data, size_t n,
1877                            off_t offset)
1878 {
1879         VFS_FIND(pread);
1880         return handle->fns->pread_fn(handle, fsp, data, n, offset);
1881 }
1882
1883 struct smb_vfs_call_pread_state {
1884         ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1885         ssize_t retval;
1886         struct vfs_aio_state vfs_aio_state;
1887 };
1888
1889 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1890
1891 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1892                                            TALLOC_CTX *mem_ctx,
1893                                            struct tevent_context *ev,
1894                                            struct files_struct *fsp,
1895                                            void *data,
1896                                            size_t n, off_t offset)
1897 {
1898         struct tevent_req *req, *subreq;
1899         struct smb_vfs_call_pread_state *state;
1900
1901         req = tevent_req_create(mem_ctx, &state,
1902                                 struct smb_vfs_call_pread_state);
1903         if (req == NULL) {
1904                 return NULL;
1905         }
1906         VFS_FIND(pread_send);
1907         state->recv_fn = handle->fns->pread_recv_fn;
1908
1909         subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1910                                             offset);
1911         if (tevent_req_nomem(subreq, req)) {
1912                 return tevent_req_post(req, ev);
1913         }
1914         tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1915         return req;
1916 }
1917
1918 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1919 {
1920         struct tevent_req *req = tevent_req_callback_data(
1921                 subreq, struct tevent_req);
1922         struct smb_vfs_call_pread_state *state = tevent_req_data(
1923                 req, struct smb_vfs_call_pread_state);
1924
1925         state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1926         TALLOC_FREE(subreq);
1927         if (state->retval == -1) {
1928                 tevent_req_error(req, state->vfs_aio_state.error);
1929                 return;
1930         }
1931         tevent_req_done(req);
1932 }
1933
1934 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req,
1935                            struct vfs_aio_state *vfs_aio_state)
1936 {
1937         struct smb_vfs_call_pread_state *state = tevent_req_data(
1938                 req, struct smb_vfs_call_pread_state);
1939         ssize_t retval;
1940
1941         if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1942                 tevent_req_received(req);
1943                 return -1;
1944         }
1945         *vfs_aio_state = state->vfs_aio_state;
1946         retval = state->retval;
1947         tevent_req_received(req);
1948         return retval;
1949 }
1950
1951 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1952                             struct files_struct *fsp, const void *data,
1953                             size_t n, off_t offset)
1954 {
1955         VFS_FIND(pwrite);
1956         return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1957 }
1958
1959 struct smb_vfs_call_pwrite_state {
1960         ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1961         ssize_t retval;
1962         struct vfs_aio_state vfs_aio_state;
1963 };
1964
1965 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1966
1967 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1968                                             TALLOC_CTX *mem_ctx,
1969                                             struct tevent_context *ev,
1970                                             struct files_struct *fsp,
1971                                             const void *data,
1972                                             size_t n, off_t offset)
1973 {
1974         struct tevent_req *req, *subreq;
1975         struct smb_vfs_call_pwrite_state *state;
1976
1977         req = tevent_req_create(mem_ctx, &state,
1978                                 struct smb_vfs_call_pwrite_state);
1979         if (req == NULL) {
1980                 return NULL;
1981         }
1982         VFS_FIND(pwrite_send);
1983         state->recv_fn = handle->fns->pwrite_recv_fn;
1984
1985         subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1986                                              offset);
1987         if (tevent_req_nomem(subreq, req)) {
1988                 return tevent_req_post(req, ev);
1989         }
1990         tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1991         return req;
1992 }
1993
1994 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1995 {
1996         struct tevent_req *req = tevent_req_callback_data(
1997                 subreq, struct tevent_req);
1998         struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1999                 req, struct smb_vfs_call_pwrite_state);
2000
2001         state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
2002         TALLOC_FREE(subreq);
2003         if (state->retval == -1) {
2004                 tevent_req_error(req, state->vfs_aio_state.error);
2005                 return;
2006         }
2007         tevent_req_done(req);
2008 }
2009
2010 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req,
2011                             struct vfs_aio_state *vfs_aio_state)
2012 {
2013         struct smb_vfs_call_pwrite_state *state = tevent_req_data(
2014                 req, struct smb_vfs_call_pwrite_state);
2015         ssize_t retval;
2016
2017         if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
2018                 tevent_req_received(req);
2019                 return -1;
2020         }
2021         *vfs_aio_state = state->vfs_aio_state;
2022         retval = state->retval;
2023         tevent_req_received(req);
2024         return retval;
2025 }
2026
2027 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
2028                              struct files_struct *fsp, off_t offset,
2029                              int whence)
2030 {
2031         VFS_FIND(lseek);
2032         return handle->fns->lseek_fn(handle, fsp, offset, whence);
2033 }
2034
2035 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
2036                               files_struct *fromfsp, const DATA_BLOB *header,
2037                               off_t offset, size_t count)
2038 {
2039         VFS_FIND(sendfile);
2040         return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
2041                                         count);
2042 }
2043
2044 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
2045                               files_struct *tofsp, off_t offset,
2046                               size_t count)
2047 {
2048         VFS_FIND(recvfile);
2049         return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
2050 }
2051
2052 int smb_vfs_call_renameat(struct vfs_handle_struct *handle,
2053                         files_struct *srcfsp,
2054                         const struct smb_filename *smb_fname_src,
2055                         files_struct *dstfsp,
2056                         const struct smb_filename *smb_fname_dst)
2057 {
2058         VFS_FIND(renameat);
2059         return handle->fns->renameat_fn(handle,
2060                                 srcfsp,
2061                                 smb_fname_src,
2062                                 dstfsp,
2063                                 smb_fname_dst);
2064 }
2065
2066 struct smb_vfs_call_fsync_state {
2067         int (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
2068         int retval;
2069         struct vfs_aio_state vfs_aio_state;
2070 };
2071
2072 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
2073
2074 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
2075                                            TALLOC_CTX *mem_ctx,
2076                                            struct tevent_context *ev,
2077                                            struct files_struct *fsp)
2078 {
2079         struct tevent_req *req, *subreq;
2080         struct smb_vfs_call_fsync_state *state;
2081
2082         req = tevent_req_create(mem_ctx, &state,
2083                                 struct smb_vfs_call_fsync_state);
2084         if (req == NULL) {
2085                 return NULL;
2086         }
2087         VFS_FIND(fsync_send);
2088         state->recv_fn = handle->fns->fsync_recv_fn;
2089
2090         subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
2091         if (tevent_req_nomem(subreq, req)) {
2092                 return tevent_req_post(req, ev);
2093         }
2094         tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
2095         return req;
2096 }
2097
2098 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
2099 {
2100         struct tevent_req *req = tevent_req_callback_data(
2101                 subreq, struct tevent_req);
2102         struct smb_vfs_call_fsync_state *state = tevent_req_data(
2103                 req, struct smb_vfs_call_fsync_state);
2104
2105         state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
2106         TALLOC_FREE(subreq);
2107         if (state->retval == -1) {
2108                 tevent_req_error(req, state->vfs_aio_state.error);
2109                 return;
2110         }
2111         tevent_req_done(req);
2112 }
2113
2114 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state)
2115 {
2116         struct smb_vfs_call_fsync_state *state = tevent_req_data(
2117                 req, struct smb_vfs_call_fsync_state);
2118         ssize_t retval;
2119
2120         if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
2121                 tevent_req_received(req);
2122                 return -1;
2123         }
2124         *vfs_aio_state = state->vfs_aio_state;
2125         retval = state->retval;
2126         tevent_req_received(req);
2127         return retval;
2128 }
2129
2130 /*
2131  * Synchronous version of fsync, built from backend
2132  * async VFS primitives. Uses a temporary sub-event
2133  * context (NOT NESTED).
2134  */
2135
2136 int smb_vfs_fsync_sync(files_struct *fsp)
2137 {
2138         TALLOC_CTX *frame = talloc_stackframe();
2139         struct tevent_req *req = NULL;
2140         struct vfs_aio_state aio_state = { 0 };
2141         int ret = -1;
2142         bool ok;
2143         struct tevent_context *ev = samba_tevent_context_init(frame);
2144
2145         if (ev == NULL) {
2146                 goto out;
2147         }
2148
2149         req = SMB_VFS_FSYNC_SEND(talloc_tos(), ev, fsp);
2150         if (req == NULL) {
2151                 goto out;
2152         }
2153
2154         ok = tevent_req_poll(req, ev);
2155         if (!ok) {
2156                 goto out;
2157         }
2158
2159         ret = SMB_VFS_FSYNC_RECV(req, &aio_state);
2160
2161   out:
2162
2163         TALLOC_FREE(frame);
2164         if (aio_state.error != 0) {
2165                 errno = aio_state.error;
2166         }
2167         return ret;
2168 }
2169
2170 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
2171                       struct smb_filename *smb_fname)
2172 {
2173         VFS_FIND(stat);
2174         return handle->fns->stat_fn(handle, smb_fname);
2175 }
2176
2177 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
2178                        struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
2179 {
2180         VFS_FIND(fstat);
2181         return handle->fns->fstat_fn(handle, fsp, sbuf);
2182 }
2183
2184 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
2185                        struct smb_filename *smb_filename)
2186 {
2187         VFS_FIND(lstat);
2188         return handle->fns->lstat_fn(handle, smb_filename);
2189 }
2190
2191 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
2192                                      struct files_struct *fsp,
2193                                      const SMB_STRUCT_STAT *sbuf)
2194 {
2195         VFS_FIND(get_alloc_size);
2196         return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
2197 }
2198
2199 int smb_vfs_call_unlinkat(struct vfs_handle_struct *handle,
2200                         struct files_struct *dirfsp,
2201                         const struct smb_filename *smb_fname,
2202                         int flags)
2203 {
2204         VFS_FIND(unlinkat);
2205         return handle->fns->unlinkat_fn(handle,
2206                         dirfsp,
2207                         smb_fname,
2208                         flags);
2209 }
2210
2211 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
2212                         struct files_struct *fsp, mode_t mode)
2213 {
2214         VFS_FIND(fchmod);
2215         return handle->fns->fchmod_fn(handle, fsp, mode);
2216 }
2217
2218 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
2219                         struct files_struct *fsp, uid_t uid, gid_t gid)
2220 {
2221         VFS_FIND(fchown);
2222         return handle->fns->fchown_fn(handle, fsp, uid, gid);
2223 }
2224
2225 int smb_vfs_call_lchown(struct vfs_handle_struct *handle,
2226                         const struct smb_filename *smb_fname,
2227                         uid_t uid,
2228                         gid_t gid)
2229 {
2230         VFS_FIND(lchown);
2231         return handle->fns->lchown_fn(handle, smb_fname, uid, gid);
2232 }
2233
2234 int smb_vfs_call_chdir(struct vfs_handle_struct *handle,
2235                         const struct smb_filename *smb_fname)
2236 {
2237         VFS_FIND(chdir);
2238         return handle->fns->chdir_fn(handle, smb_fname);
2239 }
2240
2241 struct smb_filename *smb_vfs_call_getwd(struct vfs_handle_struct *handle,
2242                                 TALLOC_CTX *ctx)
2243 {
2244         VFS_FIND(getwd);
2245         return handle->fns->getwd_fn(handle, ctx);
2246 }
2247
2248 int smb_vfs_call_fntimes(struct vfs_handle_struct *handle,
2249                          struct files_struct *fsp,
2250                          struct smb_file_time *ft)
2251 {
2252         VFS_FIND(fntimes);
2253         return handle->fns->fntimes_fn(handle, fsp, ft);
2254 }
2255
2256 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2257                            struct files_struct *fsp, off_t offset)
2258 {
2259         VFS_FIND(ftruncate);
2260         return handle->fns->ftruncate_fn(handle, fsp, offset);
2261 }
2262
2263 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2264                            struct files_struct *fsp,
2265                            uint32_t mode,
2266                            off_t offset,
2267                            off_t len)
2268 {
2269         VFS_FIND(fallocate);
2270         return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2271 }
2272
2273 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2274                               struct files_struct *fsp, uint32_t share_mode,
2275                               uint32_t access_mask)
2276 {
2277         VFS_FIND(kernel_flock);
2278         return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2279                                          access_mask);
2280 }
2281
2282 int smb_vfs_call_fcntl(struct vfs_handle_struct *handle,
2283                        struct files_struct *fsp, int cmd, ...)
2284 {
2285         int result;
2286         va_list cmd_arg;
2287
2288         VFS_FIND(fcntl);
2289
2290         va_start(cmd_arg, cmd);
2291         result = handle->fns->fcntl_fn(handle, fsp, cmd, cmd_arg);
2292         va_end(cmd_arg);
2293
2294         return result;
2295 }
2296
2297 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2298                                 struct files_struct *fsp, int leasetype)
2299 {
2300         VFS_FIND(linux_setlease);
2301         return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2302 }
2303
2304 int smb_vfs_call_symlinkat(struct vfs_handle_struct *handle,
2305                         const struct smb_filename *link_target,
2306                         struct files_struct *dirfsp,
2307                         const struct smb_filename *new_smb_fname)
2308 {
2309         VFS_FIND(symlinkat);
2310         return handle->fns->symlinkat_fn(handle,
2311                                 link_target,
2312                                 dirfsp,
2313                                 new_smb_fname);
2314 }
2315
2316 int smb_vfs_call_readlinkat(struct vfs_handle_struct *handle,
2317                         const struct files_struct *dirfsp,
2318                         const struct smb_filename *smb_fname,
2319                         char *buf,
2320                         size_t bufsiz)
2321 {
2322         VFS_FIND(readlinkat);
2323         return handle->fns->readlinkat_fn(handle,
2324                                 dirfsp,
2325                                 smb_fname,
2326                                 buf,
2327                                 bufsiz);
2328 }
2329
2330 int smb_vfs_call_linkat(struct vfs_handle_struct *handle,
2331                         struct files_struct *srcfsp,
2332                         const struct smb_filename *old_smb_fname,
2333                         struct files_struct *dstfsp,
2334                         const struct smb_filename *new_smb_fname,
2335                         int flags)
2336 {
2337         VFS_FIND(linkat);
2338         return handle->fns->linkat_fn(handle,
2339                                 srcfsp,
2340                                 old_smb_fname,
2341                                 dstfsp,
2342                                 new_smb_fname,
2343                                 flags);
2344 }
2345
2346 int smb_vfs_call_mknodat(struct vfs_handle_struct *handle,
2347                         struct files_struct *dirfsp,
2348                         const struct smb_filename *smb_fname,
2349                         mode_t mode,
2350                         SMB_DEV_T dev)
2351 {
2352         VFS_FIND(mknodat);
2353         return handle->fns->mknodat_fn(handle,
2354                                 dirfsp,
2355                                 smb_fname,
2356                                 mode,
2357                                 dev);
2358 }
2359
2360 struct smb_filename *smb_vfs_call_realpath(struct vfs_handle_struct *handle,
2361                         TALLOC_CTX *ctx,
2362                         const struct smb_filename *smb_fname)
2363 {
2364         VFS_FIND(realpath);
2365         return handle->fns->realpath_fn(handle, ctx, smb_fname);
2366 }
2367
2368 int smb_vfs_call_chflags(struct vfs_handle_struct *handle,
2369                         const struct smb_filename *smb_fname,
2370                         unsigned int flags)
2371 {
2372         VFS_FIND(chflags);
2373         return handle->fns->chflags_fn(handle, smb_fname, flags);
2374 }
2375
2376 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2377                                            const SMB_STRUCT_STAT *sbuf)
2378 {
2379         VFS_FIND(file_id_create);
2380         return handle->fns->file_id_create_fn(handle, sbuf);
2381 }
2382
2383 uint64_t smb_vfs_call_fs_file_id(struct vfs_handle_struct *handle,
2384                                  const SMB_STRUCT_STAT *sbuf)
2385 {
2386         VFS_FIND(fs_file_id);
2387         return handle->fns->fs_file_id_fn(handle, sbuf);
2388 }
2389
2390 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2391                                  struct files_struct *fsp,
2392                                  const struct smb_filename *smb_fname,
2393                                  TALLOC_CTX *mem_ctx,
2394                                  unsigned int *num_streams,
2395                                  struct stream_struct **streams)
2396 {
2397         VFS_FIND(streaminfo);
2398         return handle->fns->streaminfo_fn(handle, fsp, smb_fname, mem_ctx,
2399                                           num_streams, streams);
2400 }
2401
2402 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2403                                    const struct smb_filename *path,
2404                                    const char *name,
2405                                    TALLOC_CTX *mem_ctx,
2406                                    char **found_name)
2407 {
2408         VFS_FIND(get_real_filename);
2409         return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2410                                                  found_name);
2411 }
2412
2413 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2414                                  const struct smb_filename *smb_fname)
2415 {
2416         VFS_FIND(connectpath);
2417         return handle->fns->connectpath_fn(handle, smb_fname);
2418 }
2419
2420 bool smb_vfs_call_strict_lock_check(struct vfs_handle_struct *handle,
2421                                     struct files_struct *fsp,
2422                                     struct lock_struct *plock)
2423 {
2424         VFS_FIND(strict_lock_check);
2425         return handle->fns->strict_lock_check_fn(handle, fsp, plock);
2426 }
2427
2428 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2429                                      const char *name,
2430                                      enum vfs_translate_direction direction,
2431                                      TALLOC_CTX *mem_ctx,
2432                                      char **mapped_name)
2433 {
2434         VFS_FIND(translate_name);
2435         return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2436                                               mapped_name);
2437 }
2438
2439 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2440                             struct files_struct *fsp,
2441                             TALLOC_CTX *ctx,
2442                             uint32_t function,
2443                             uint16_t req_flags,
2444                             const uint8_t *in_data,
2445                             uint32_t in_len,
2446                             uint8_t **out_data,
2447                             uint32_t max_out_len,
2448                             uint32_t *out_len)
2449 {
2450         VFS_FIND(fsctl);
2451         return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2452                                      in_data, in_len, out_data, max_out_len,
2453                                      out_len);
2454 }
2455
2456 NTSTATUS smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct *handle,
2457                                           struct files_struct *fsp,
2458                                           uint32_t *dosmode)
2459 {
2460         VFS_FIND(fget_dos_attributes);
2461         return handle->fns->fget_dos_attributes_fn(handle, fsp, dosmode);
2462 }
2463
2464 NTSTATUS smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct *handle,
2465                                           struct files_struct *fsp,
2466                                           uint32_t dosmode)
2467 {
2468         VFS_FIND(fset_dos_attributes);
2469         return handle->fns->fset_dos_attributes_fn(handle, fsp, dosmode);
2470 }
2471
2472 struct tevent_req *smb_vfs_call_offload_read_send(TALLOC_CTX *mem_ctx,
2473                                                   struct tevent_context *ev,
2474                                                   struct vfs_handle_struct *handle,
2475                                                   struct files_struct *fsp,
2476                                                   uint32_t fsctl,
2477                                                   uint32_t ttl,
2478                                                   off_t offset,
2479                                                   size_t to_copy)
2480 {
2481         VFS_FIND(offload_read_send);
2482         return handle->fns->offload_read_send_fn(mem_ctx, ev, handle,
2483                                                  fsp, fsctl,
2484                                                  ttl, offset, to_copy);
2485 }
2486
2487 NTSTATUS smb_vfs_call_offload_read_recv(struct tevent_req *req,
2488                                         struct vfs_handle_struct *handle,
2489                                         TALLOC_CTX *mem_ctx,
2490                                         DATA_BLOB *token_blob)
2491 {
2492         VFS_FIND(offload_read_recv);
2493         return handle->fns->offload_read_recv_fn(req, handle, mem_ctx, token_blob);
2494 }
2495
2496 struct tevent_req *smb_vfs_call_offload_write_send(struct vfs_handle_struct *handle,
2497                                                    TALLOC_CTX *mem_ctx,
2498                                                    struct tevent_context *ev,
2499                                                    uint32_t fsctl,
2500                                                    DATA_BLOB *token,
2501                                                    off_t transfer_offset,
2502                                                    struct files_struct *dest_fsp,
2503                                                    off_t dest_off,
2504                                                    off_t num)
2505 {
2506         VFS_FIND(offload_write_send);
2507         return handle->fns->offload_write_send_fn(handle, mem_ctx, ev, fsctl,
2508                                                token, transfer_offset,
2509                                                dest_fsp, dest_off, num);
2510 }
2511
2512 NTSTATUS smb_vfs_call_offload_write_recv(struct vfs_handle_struct *handle,
2513                                          struct tevent_req *req,
2514                                          off_t *copied)
2515 {
2516         VFS_FIND(offload_write_recv);
2517         return handle->fns->offload_write_recv_fn(handle, req, copied);
2518 }
2519
2520 struct smb_vfs_call_get_dos_attributes_state {
2521         files_struct *dir_fsp;
2522         NTSTATUS (*recv_fn)(struct tevent_req *req,
2523                             struct vfs_aio_state *aio_state,
2524                             uint32_t *dosmode);
2525         struct vfs_aio_state aio_state;
2526         uint32_t dos_attributes;
2527 };
2528
2529 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq);
2530
2531 struct tevent_req *smb_vfs_call_get_dos_attributes_send(
2532                         TALLOC_CTX *mem_ctx,
2533                         struct tevent_context *ev,
2534                         struct vfs_handle_struct *handle,
2535                         files_struct *dir_fsp,
2536                         struct smb_filename *smb_fname)
2537 {
2538         struct tevent_req *req = NULL;
2539         struct smb_vfs_call_get_dos_attributes_state *state = NULL;
2540         struct tevent_req *subreq = NULL;
2541
2542         req = tevent_req_create(mem_ctx, &state,
2543                                 struct smb_vfs_call_get_dos_attributes_state);
2544         if (req == NULL) {
2545                 return NULL;
2546         }
2547
2548         VFS_FIND(get_dos_attributes_send);
2549
2550         *state = (struct smb_vfs_call_get_dos_attributes_state) {
2551                 .dir_fsp = dir_fsp,
2552                 .recv_fn = handle->fns->get_dos_attributes_recv_fn,
2553         };
2554
2555         subreq = handle->fns->get_dos_attributes_send_fn(mem_ctx,
2556                                                          ev,
2557                                                          handle,
2558                                                          dir_fsp,
2559                                                          smb_fname);
2560         if (tevent_req_nomem(subreq, req)) {
2561                 return tevent_req_post(req, ev);
2562         }
2563         tevent_req_defer_callback(req, ev);
2564
2565         tevent_req_set_callback(subreq,
2566                                 smb_vfs_call_get_dos_attributes_done,
2567                                 req);
2568
2569         return req;
2570 }
2571
2572 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq)
2573 {
2574         struct tevent_req *req =
2575                 tevent_req_callback_data(subreq,
2576                 struct tevent_req);
2577         struct smb_vfs_call_get_dos_attributes_state *state =
2578                 tevent_req_data(req,
2579                 struct smb_vfs_call_get_dos_attributes_state);
2580         NTSTATUS status;
2581         bool ok;
2582
2583         /*
2584          * Make sure we run as the user again
2585          */
2586         ok = change_to_user_and_service_by_fsp(state->dir_fsp);
2587         SMB_ASSERT(ok);
2588
2589         status = state->recv_fn(subreq,
2590                                 &state->aio_state,
2591                                 &state->dos_attributes);
2592         TALLOC_FREE(subreq);
2593         if (tevent_req_nterror(req, status)) {
2594                 return;
2595         }
2596
2597         tevent_req_done(req);
2598 }
2599
2600 NTSTATUS smb_vfs_call_get_dos_attributes_recv(
2601                 struct tevent_req *req,
2602                 struct vfs_aio_state *aio_state,
2603                 uint32_t *dos_attributes)
2604 {
2605         struct smb_vfs_call_get_dos_attributes_state *state =
2606                 tevent_req_data(req,
2607                 struct smb_vfs_call_get_dos_attributes_state);
2608         NTSTATUS status;
2609
2610         if (tevent_req_is_nterror(req, &status)) {
2611                 tevent_req_received(req);
2612                 return status;
2613         }
2614
2615         *aio_state = state->aio_state;
2616         *dos_attributes = state->dos_attributes;
2617         tevent_req_received(req);
2618         return NT_STATUS_OK;
2619 }
2620
2621 NTSTATUS smb_vfs_call_fget_compression(vfs_handle_struct *handle,
2622                                       TALLOC_CTX *mem_ctx,
2623                                       struct files_struct *fsp,
2624                                       uint16_t *_compression_fmt)
2625 {
2626         VFS_FIND(fget_compression);
2627         return handle->fns->fget_compression_fn(handle, mem_ctx, fsp,
2628                                                _compression_fmt);
2629 }
2630
2631 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2632                                       TALLOC_CTX *mem_ctx,
2633                                       struct files_struct *fsp,
2634                                       uint16_t compression_fmt)
2635 {
2636         VFS_FIND(set_compression);
2637         return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2638                                                compression_fmt);
2639 }
2640
2641 NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
2642                                       TALLOC_CTX *mem_ctx,
2643                                       const char *service_path,
2644                                       char **base_volume)
2645 {
2646         VFS_FIND(snap_check_path);
2647         return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path,
2648                                                base_volume);
2649 }
2650
2651 NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle,
2652                                   TALLOC_CTX *mem_ctx,
2653                                   const char *base_volume,
2654                                   time_t *tstamp,
2655                                   bool rw,
2656                                   char **base_path,
2657                                   char **snap_path)
2658 {
2659         VFS_FIND(snap_create);
2660         return handle->fns->snap_create_fn(handle, mem_ctx, base_volume, tstamp,
2661                                            rw, base_path, snap_path);
2662 }
2663
2664 NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle,
2665                                   TALLOC_CTX *mem_ctx,
2666                                   char *base_path,
2667                                   char *snap_path)
2668 {
2669         VFS_FIND(snap_delete);
2670         return handle->fns->snap_delete_fn(handle, mem_ctx, base_path,
2671                                            snap_path);
2672 }
2673
2674 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2675                                   struct files_struct *fsp,
2676                                   uint32_t security_info,
2677                                   TALLOC_CTX *mem_ctx,
2678                                   struct security_descriptor **ppdesc)
2679 {
2680         VFS_FIND(fget_nt_acl);
2681         return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2682                                            mem_ctx, ppdesc);
2683 }
2684
2685 NTSTATUS smb_vfs_call_get_nt_acl_at(struct vfs_handle_struct *handle,
2686                         struct files_struct *dirfsp,
2687                         const struct smb_filename *smb_fname,
2688                         uint32_t security_info,
2689                         TALLOC_CTX *mem_ctx,
2690                         struct security_descriptor **ppdesc)
2691 {
2692         VFS_FIND(get_nt_acl_at);
2693         return handle->fns->get_nt_acl_at_fn(handle,
2694                                 dirfsp,
2695                                 smb_fname,
2696                                 security_info,
2697                                 mem_ctx,
2698                                 ppdesc);
2699 }
2700
2701 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2702                                   struct files_struct *fsp,
2703                                   uint32_t security_info_sent,
2704                                   const struct security_descriptor *psd)
2705 {
2706         VFS_FIND(fset_nt_acl);
2707         return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent, 
2708                                            psd);
2709 }
2710
2711 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2712                                  struct smb_filename *file,
2713                                  struct security_acl *sacl,
2714                                  uint32_t access_requested,
2715                                  uint32_t access_denied)
2716 {
2717         VFS_FIND(audit_file);
2718         return handle->fns->audit_file_fn(handle, 
2719                                           file, 
2720                                           sacl, 
2721                                           access_requested, 
2722                                           access_denied);
2723 }
2724
2725 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2726                                         const struct smb_filename *smb_fname,
2727                                         SMB_ACL_TYPE_T type,
2728                                         TALLOC_CTX *mem_ctx)
2729 {
2730         VFS_FIND(sys_acl_get_file);
2731         return handle->fns->sys_acl_get_file_fn(handle, smb_fname, type, mem_ctx);
2732 }
2733
2734 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2735                                       struct files_struct *fsp,
2736                                       TALLOC_CTX *mem_ctx)
2737 {
2738         VFS_FIND(sys_acl_get_fd);
2739         return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2740 }
2741
2742 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2743                                 const struct smb_filename *smb_fname,
2744                                 TALLOC_CTX *mem_ctx,
2745                                 char **blob_description,
2746                                 DATA_BLOB *blob)
2747 {
2748         VFS_FIND(sys_acl_blob_get_file);
2749         return handle->fns->sys_acl_blob_get_file_fn(handle, smb_fname,
2750                         mem_ctx, blob_description, blob);
2751 }
2752
2753 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2754                                      struct files_struct *fsp,
2755                                      TALLOC_CTX *mem_ctx, 
2756                                      char **blob_description,
2757                                      DATA_BLOB *blob)
2758 {
2759         VFS_FIND(sys_acl_blob_get_fd);
2760         return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2761 }
2762
2763 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2764                                 struct files_struct *fsp,
2765                                 SMB_ACL_TYPE_T type,
2766                                 SMB_ACL_T theacl)
2767 {
2768         VFS_FIND(sys_acl_set_fd);
2769         return handle->fns->sys_acl_set_fd_fn(handle, fsp, type, theacl);
2770 }
2771
2772 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2773                                 const struct smb_filename *smb_fname)
2774 {
2775         VFS_FIND(sys_acl_delete_def_file);
2776         return handle->fns->sys_acl_delete_def_file_fn(handle, smb_fname);
2777 }
2778
2779 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2780                                 const struct smb_filename *smb_fname,
2781                                 const char *name,
2782                                 void *value,
2783                                 size_t size)
2784 {
2785         VFS_FIND(getxattr);
2786         return handle->fns->getxattr_fn(handle, smb_fname, name, value, size);
2787 }
2788
2789
2790 struct smb_vfs_call_getxattrat_state {
2791         files_struct *dir_fsp;
2792         ssize_t (*recv_fn)(struct tevent_req *req,
2793                            struct vfs_aio_state *aio_state,
2794                            TALLOC_CTX *mem_ctx,
2795                            uint8_t **xattr_value);
2796         ssize_t retval;
2797         uint8_t *xattr_value;
2798         struct vfs_aio_state aio_state;
2799 };
2800
2801 static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq);
2802
2803 struct tevent_req *smb_vfs_call_getxattrat_send(
2804                         TALLOC_CTX *mem_ctx,
2805                         struct tevent_context *ev,
2806                         struct vfs_handle_struct *handle,
2807                         files_struct *dir_fsp,
2808                         const struct smb_filename *smb_fname,
2809                         const char *xattr_name,
2810                         size_t alloc_hint)
2811 {
2812         struct tevent_req *req = NULL;
2813         struct smb_vfs_call_getxattrat_state *state = NULL;
2814         struct tevent_req *subreq = NULL;
2815
2816         req = tevent_req_create(mem_ctx, &state,
2817                                 struct smb_vfs_call_getxattrat_state);
2818         if (req == NULL) {
2819                 return NULL;
2820         }
2821
2822         VFS_FIND(getxattrat_send);
2823
2824         *state = (struct smb_vfs_call_getxattrat_state) {
2825                 .dir_fsp = dir_fsp,
2826                 .recv_fn = handle->fns->getxattrat_recv_fn,
2827         };
2828
2829         subreq = handle->fns->getxattrat_send_fn(mem_ctx,
2830                                                  ev,
2831                                                  handle,
2832                                                  dir_fsp,
2833                                                  smb_fname,
2834                                                  xattr_name,
2835                                                  alloc_hint);
2836         if (tevent_req_nomem(subreq, req)) {
2837                 return tevent_req_post(req, ev);
2838         }
2839         tevent_req_defer_callback(req, ev);
2840
2841         tevent_req_set_callback(subreq, smb_vfs_call_getxattrat_done, req);
2842         return req;
2843 }
2844
2845 static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq)
2846 {
2847         struct tevent_req *req = tevent_req_callback_data(
2848                 subreq, struct tevent_req);
2849         struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2850                 req, struct smb_vfs_call_getxattrat_state);
2851         bool ok;
2852
2853         /*
2854          * Make sure we run as the user again
2855          */
2856         ok = change_to_user_and_service_by_fsp(state->dir_fsp);
2857         SMB_ASSERT(ok);
2858
2859         state->retval = state->recv_fn(subreq,
2860                                        &state->aio_state,
2861                                        state,
2862                                        &state->xattr_value);
2863         TALLOC_FREE(subreq);
2864         if (state->retval == -1) {
2865                 tevent_req_error(req, state->aio_state.error);
2866                 return;
2867         }
2868
2869         tevent_req_done(req);
2870 }
2871
2872 ssize_t smb_vfs_call_getxattrat_recv(struct tevent_req *req,
2873                                      struct vfs_aio_state *aio_state,
2874                                      TALLOC_CTX *mem_ctx,
2875                                      uint8_t **xattr_value)
2876 {
2877         struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2878                 req, struct smb_vfs_call_getxattrat_state);
2879         size_t xattr_size;
2880
2881         if (tevent_req_is_unix_error(req, &aio_state->error)) {
2882                 tevent_req_received(req);
2883                 return -1;
2884         }
2885
2886         *aio_state = state->aio_state;
2887         xattr_size = state->retval;
2888         if (xattr_value != NULL) {
2889                 *xattr_value = talloc_move(mem_ctx, &state->xattr_value);
2890         }
2891
2892         tevent_req_received(req);
2893         return xattr_size;
2894 }
2895
2896 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2897                                struct files_struct *fsp, const char *name,
2898                                void *value, size_t size)
2899 {
2900         VFS_FIND(fgetxattr);
2901         return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2902 }
2903
2904 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2905                                 struct files_struct *fsp, char *list,
2906                                 size_t size)
2907 {
2908         VFS_FIND(flistxattr);
2909         return handle->fns->flistxattr_fn(handle, fsp, list, size);
2910 }
2911
2912 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2913                               struct files_struct *fsp, const char *name)
2914 {
2915         VFS_FIND(fremovexattr);
2916         return handle->fns->fremovexattr_fn(handle, fsp, name);
2917 }
2918
2919 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2920                            struct files_struct *fsp, const char *name,
2921                            const void *value, size_t size, int flags)
2922 {
2923         VFS_FIND(fsetxattr);
2924         return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2925 }
2926
2927 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2928                             struct files_struct *fsp)
2929 {
2930         VFS_FIND(aio_force);
2931         return handle->fns->aio_force_fn(handle, fsp);
2932 }
2933
2934 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2935                                      struct files_struct *fsp,
2936                                      TALLOC_CTX *mem_ctx,
2937                                      DATA_BLOB *cookie)
2938 {
2939         VFS_FIND(durable_cookie);
2940         return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2941 }
2942
2943 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2944                                          struct files_struct *fsp,
2945                                          const DATA_BLOB old_cookie,
2946                                          TALLOC_CTX *mem_ctx,
2947                                          DATA_BLOB *new_cookie)
2948 {
2949         VFS_FIND(durable_disconnect);
2950         return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2951                                                   mem_ctx, new_cookie);
2952 }
2953
2954 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2955                                         struct smb_request *smb1req,
2956                                         struct smbXsrv_open *op,
2957                                         const DATA_BLOB old_cookie,
2958                                         TALLOC_CTX *mem_ctx,
2959                                         struct files_struct **fsp,
2960                                         DATA_BLOB *new_cookie)
2961 {
2962         VFS_FIND(durable_reconnect);
2963         return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2964                                                  old_cookie, mem_ctx, fsp,
2965                                                  new_cookie);
2966 }
2967
2968 NTSTATUS smb_vfs_call_readdir_attr(struct vfs_handle_struct *handle,
2969                                    const struct smb_filename *fname,
2970                                    TALLOC_CTX *mem_ctx,
2971                                    struct readdir_attr_data **attr_data)
2972 {
2973         VFS_FIND(readdir_attr);
2974         return handle->fns->readdir_attr_fn(handle, fname, mem_ctx, attr_data);
2975 }