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