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