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