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