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