TODO anon? s3:smb3_sesssetup: close the previous SMB2 session if requested and allowed
[metze/samba/wip.git] / source3 / smbd / vfs.c
1 /*
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    VFS initialisation and support functions
5    Copyright (C) Tim Potter 1999
6    Copyright (C) Alexander Bokovoy 2002
7    Copyright (C) James Peach 2006
8    Copyright (C) Volker Lendecke 2009
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
23    This work was sponsored by Optifacio Software Services, Inc.
24 */
25
26 #include "includes.h"
27 #include "system/filesys.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "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_load_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, 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                                         (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                         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 (((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, (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, 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, off_t offset, 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, off_t len)
623 {
624         int ret;
625         NTSTATUS status;
626         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 off_t vfs_transfer_file(files_struct *in, files_struct *out, 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         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, (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_request *smbreq)
905 {
906         NTSTATUS status;
907         TALLOC_CTX *ctx = talloc_tos();
908         const char *conn_rootdir;
909         size_t rootdir_len;
910         char *dir_name = NULL;
911         const char *last_component = NULL;
912         char *resolved_name = NULL;
913         char *saved_dir = NULL;
914         struct smb_filename *smb_fname_cwd = NULL;
915         struct privilege_paths *priv_paths = NULL;
916         int ret;
917
918         DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
919                         fname,
920                         conn->connectpath));
921
922
923         priv_paths = talloc_zero(smbreq, struct privilege_paths);
924         if (!priv_paths) {
925                 status = NT_STATUS_NO_MEMORY;
926                 goto err;
927         }
928
929         if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
930                 status = NT_STATUS_NO_MEMORY;
931                 goto err;
932         }
933
934         priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
935         priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
936
937         if (priv_paths->parent_name.base_name == NULL ||
938                         priv_paths->file_name.base_name == NULL) {
939                 status = NT_STATUS_NO_MEMORY;
940                 goto err;
941         }
942
943         if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
944                 status = map_nt_error_from_unix(errno);
945                 goto err;
946         }
947         /* Remember where we were. */
948         saved_dir = vfs_GetWd(ctx, conn);
949         if (!saved_dir) {
950                 status = map_nt_error_from_unix(errno);
951                 goto err;
952         }
953
954         /* Go to the parent directory to lock in memory. */
955         if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
956                 status = map_nt_error_from_unix(errno);
957                 goto err;
958         }
959
960         /* Get the absolute path of the parent directory. */
961         resolved_name = SMB_VFS_REALPATH(conn,".");
962         if (!resolved_name) {
963                 status = map_nt_error_from_unix(errno);
964                 goto err;
965         }
966
967         if (*resolved_name != '/') {
968                 DEBUG(0,("check_reduced_name_with_privilege: realpath "
969                         "doesn't return absolute paths !\n"));
970                 status = NT_STATUS_OBJECT_NAME_INVALID;
971                 goto err;
972         }
973
974         DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
975                 priv_paths->parent_name.base_name,
976                 resolved_name));
977
978         /* Now check the stat value is the same. */
979         status = create_synthetic_smb_fname(talloc_tos(), ".",
980                                         NULL, NULL,
981                                         &smb_fname_cwd);
982         if (!NT_STATUS_IS_OK(status)) {
983                 goto err;
984         }
985
986         if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
987                 status = map_nt_error_from_unix(errno);
988                 goto err;
989         }
990
991         /* Ensure we're pointing at the same place. */
992         if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
993                 DEBUG(0,("check_reduced_name_with_privilege: "
994                         "device/inode/uid/gid on directory %s changed. "
995                         "Denying access !\n",
996                         priv_paths->parent_name.base_name));
997                 status = NT_STATUS_ACCESS_DENIED;
998                 goto err;
999         }
1000
1001         /* Ensure we're below the connect path. */
1002
1003         conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1004         if (conn_rootdir == NULL) {
1005                 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1006                         "conn_rootdir\n"));
1007                 status = NT_STATUS_ACCESS_DENIED;
1008                 goto err;
1009         }
1010
1011         rootdir_len = strlen(conn_rootdir);
1012         if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1013                 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1014                         "attempt: %s is a symlink outside the "
1015                         "share path\n",
1016                         dir_name));
1017                 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1018                 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1019                 status = NT_STATUS_ACCESS_DENIED;
1020                 goto err;
1021         }
1022
1023         /* Now ensure that the last component either doesn't
1024            exist, or is *NOT* a symlink. */
1025
1026         ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1027         if (ret == -1) {
1028                 /* Errno must be ENOENT for this be ok. */
1029                 if (errno != ENOENT) {
1030                         status = map_nt_error_from_unix(errno);
1031                         DEBUG(2, ("check_reduced_name_with_privilege: "
1032                                 "LSTAT on %s failed with %s\n",
1033                                 priv_paths->file_name.base_name,
1034                                 nt_errstr(status)));
1035                         goto err;
1036                 }
1037         }
1038
1039         if (VALID_STAT(priv_paths->file_name.st) &&
1040                         S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1041                 DEBUG(2, ("check_reduced_name_with_privilege: "
1042                         "Last component %s is a symlink. Denying"
1043                         "access.\n",
1044                         priv_paths->file_name.base_name));
1045                 status = NT_STATUS_ACCESS_DENIED;
1046                 goto err;
1047         }
1048
1049         smbreq->priv_paths = priv_paths;
1050         status = NT_STATUS_OK;
1051
1052   err:
1053
1054         if (saved_dir) {
1055                 vfs_ChDir(conn, saved_dir);
1056         }
1057         SAFE_FREE(resolved_name);
1058         if (!NT_STATUS_IS_OK(status)) {
1059                 TALLOC_FREE(priv_paths);
1060         }
1061         return status;
1062 }
1063
1064 /*******************************************************************
1065  Reduce a file name, removing .. elements and checking that
1066  it is below dir in the heirachy. This uses realpath.
1067 ********************************************************************/
1068
1069 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1070 {
1071         char *resolved_name = NULL;
1072         bool allow_symlinks = true;
1073         bool allow_widelinks = false;
1074
1075         DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1076
1077         resolved_name = SMB_VFS_REALPATH(conn,fname);
1078
1079         if (!resolved_name) {
1080                 switch (errno) {
1081                         case ENOTDIR:
1082                                 DEBUG(3,("check_reduced_name: Component not a "
1083                                          "directory in getting realpath for "
1084                                          "%s\n", fname));
1085                                 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1086                         case ENOENT:
1087                         {
1088                                 TALLOC_CTX *ctx = talloc_tos();
1089                                 char *dir_name = NULL;
1090                                 const char *last_component = NULL;
1091                                 char *new_name = NULL;
1092                                 int ret;
1093
1094                                 /* Last component didn't exist.
1095                                    Remove it and try and canonicalise
1096                                    the directory name. */
1097                                 if (!parent_dirname(ctx, fname,
1098                                                 &dir_name,
1099                                                 &last_component)) {
1100                                         return NT_STATUS_NO_MEMORY;
1101                                 }
1102
1103                                 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1104                                 if (!resolved_name) {
1105                                         NTSTATUS status = map_nt_error_from_unix(errno);
1106
1107                                         if (errno == ENOENT || errno == ENOTDIR) {
1108                                                 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1109                                         }
1110
1111                                         DEBUG(3,("check_reduce_name: "
1112                                                  "couldn't get realpath for "
1113                                                  "%s (%s)\n",
1114                                                 fname,
1115                                                 nt_errstr(status)));
1116                                         return status;
1117                                 }
1118                                 ret = asprintf(&new_name, "%s/%s",
1119                                                resolved_name, last_component);
1120                                 SAFE_FREE(resolved_name);
1121                                 if (ret == -1) {
1122                                         return NT_STATUS_NO_MEMORY;
1123                                 }
1124                                 resolved_name = new_name;
1125                                 break;
1126                         }
1127                         default:
1128                                 DEBUG(3,("check_reduced_name: couldn't get "
1129                                          "realpath for %s\n", fname));
1130                                 return map_nt_error_from_unix(errno);
1131                 }
1132         }
1133
1134         DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1135                   resolved_name));
1136
1137         if (*resolved_name != '/') {
1138                 DEBUG(0,("check_reduced_name: realpath doesn't return "
1139                          "absolute paths !\n"));
1140                 SAFE_FREE(resolved_name);
1141                 return NT_STATUS_OBJECT_NAME_INVALID;
1142         }
1143
1144         allow_widelinks = lp_widelinks(SNUM(conn));
1145         allow_symlinks = lp_symlinks(SNUM(conn));
1146
1147         /* Common widelinks and symlinks checks. */
1148         if (!allow_widelinks || !allow_symlinks) {
1149                 const char *conn_rootdir;
1150                 size_t rootdir_len;
1151
1152                 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1153                 if (conn_rootdir == NULL) {
1154                         DEBUG(2, ("check_reduced_name: Could not get "
1155                                 "conn_rootdir\n"));
1156                         SAFE_FREE(resolved_name);
1157                         return NT_STATUS_ACCESS_DENIED;
1158                 }
1159
1160                 rootdir_len = strlen(conn_rootdir);
1161                 if (strncmp(conn_rootdir, resolved_name,
1162                                 rootdir_len) != 0) {
1163                         DEBUG(2, ("check_reduced_name: Bad access "
1164                                 "attempt: %s is a symlink outside the "
1165                                 "share path\n", fname));
1166                         DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1167                         DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1168                         SAFE_FREE(resolved_name);
1169                         return NT_STATUS_ACCESS_DENIED;
1170                 }
1171
1172                 /* Extra checks if all symlinks are disallowed. */
1173                 if (!allow_symlinks) {
1174                         /* fname can't have changed in resolved_path. */
1175                         const char *p = &resolved_name[rootdir_len];
1176
1177                         /* *p can be '\0' if fname was "." */
1178                         if (*p == '\0' && ISDOT(fname)) {
1179                                 goto out;
1180                         }
1181
1182                         if (*p != '/') {
1183                                 DEBUG(2, ("check_reduced_name: logic error (%c) "
1184                                         "in resolved_name: %s\n",
1185                                         *p,
1186                                         fname));
1187                                 SAFE_FREE(resolved_name);
1188                                 return NT_STATUS_ACCESS_DENIED;
1189                         }
1190
1191                         p++;
1192                         if (strcmp(fname, p)!=0) {
1193                                 DEBUG(2, ("check_reduced_name: Bad access "
1194                                         "attempt: %s is a symlink\n",
1195                                         fname));
1196                                 SAFE_FREE(resolved_name);
1197                                 return NT_STATUS_ACCESS_DENIED;
1198                         }
1199                 }
1200         }
1201
1202   out:
1203
1204         DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1205                  resolved_name));
1206         SAFE_FREE(resolved_name);
1207         return NT_STATUS_OK;
1208 }
1209
1210 /**
1211  * XXX: This is temporary and there should be no callers of this once
1212  * smb_filename is plumbed through all path based operations.
1213  */
1214 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1215                        SMB_STRUCT_STAT *psbuf)
1216 {
1217         struct smb_filename *smb_fname = NULL;
1218         NTSTATUS status;
1219         int ret;
1220
1221         status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1222                                                   &smb_fname);
1223         if (!NT_STATUS_IS_OK(status)) {
1224                 errno = map_errno_from_nt_status(status);
1225                 return -1;
1226         }
1227
1228         if (lp_posix_pathnames()) {
1229                 ret = SMB_VFS_LSTAT(conn, smb_fname);
1230         } else {
1231                 ret = SMB_VFS_STAT(conn, smb_fname);
1232         }
1233
1234         if (ret != -1) {
1235                 *psbuf = smb_fname->st;
1236         }
1237
1238         TALLOC_FREE(smb_fname);
1239         return ret;
1240 }
1241
1242 /**
1243  * XXX: This is temporary and there should be no callers of this once
1244  * smb_filename is plumbed through all path based operations.
1245  */
1246 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1247                         SMB_STRUCT_STAT *psbuf)
1248 {
1249         struct smb_filename *smb_fname = NULL;
1250         NTSTATUS status;
1251         int ret;
1252
1253         status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1254                                                   &smb_fname);
1255         if (!NT_STATUS_IS_OK(status)) {
1256                 errno = map_errno_from_nt_status(status);
1257                 return -1;
1258         }
1259
1260         ret = SMB_VFS_LSTAT(conn, smb_fname);
1261         if (ret != -1) {
1262                 *psbuf = smb_fname->st;
1263         }
1264
1265         TALLOC_FREE(smb_fname);
1266         return ret;
1267 }
1268
1269 /**
1270  * Ensure LSTAT is called for POSIX paths.
1271  */
1272
1273 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1274 {
1275         int ret;
1276
1277         if(fsp->fh->fd == -1) {
1278                 if (fsp->posix_open) {
1279                         ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1280                 } else {
1281                         ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1282                 }
1283                 if (ret == -1) {
1284                         return map_nt_error_from_unix(errno);
1285                 }
1286         } else {
1287                 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1288                         return map_nt_error_from_unix(errno);
1289                 }
1290         }
1291         return NT_STATUS_OK;
1292 }
1293
1294 /**
1295  * Initialize num_streams and streams, then call VFS op streaminfo
1296  */
1297 NTSTATUS vfs_streaminfo(connection_struct *conn,
1298                         struct files_struct *fsp,
1299                         const char *fname,
1300                         TALLOC_CTX *mem_ctx,
1301                         unsigned int *num_streams,
1302                         struct stream_struct **streams)
1303 {
1304         *num_streams = 0;
1305         *streams = NULL;
1306         return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1307 }
1308
1309 /*
1310   generate a file_id from a stat structure
1311  */
1312 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1313 {
1314         return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1315 }
1316
1317 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1318                          const char *service, const char *user)
1319 {
1320         VFS_FIND(connect);
1321         return handle->fns->connect_fn(handle, service, user);
1322 }
1323
1324 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1325 {
1326         VFS_FIND(disconnect);
1327         handle->fns->disconnect_fn(handle);
1328 }
1329
1330 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1331                                 const char *path, bool small_query,
1332                                 uint64_t *bsize, uint64_t *dfree,
1333                                 uint64_t *dsize)
1334 {
1335         VFS_FIND(disk_free);
1336         return handle->fns->disk_free_fn(handle, path, small_query, bsize, 
1337                                          dfree, dsize);
1338 }
1339
1340 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1341                            enum SMB_QUOTA_TYPE qtype, unid_t id,
1342                            SMB_DISK_QUOTA *qt)
1343 {
1344         VFS_FIND(get_quota);
1345         return handle->fns->get_quota_fn(handle, qtype, id, qt);
1346 }
1347
1348 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1349                            enum SMB_QUOTA_TYPE qtype, unid_t id,
1350                            SMB_DISK_QUOTA *qt)
1351 {
1352         VFS_FIND(set_quota);
1353         return handle->fns->set_quota_fn(handle, qtype, id, qt);
1354 }
1355
1356 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1357                                       struct files_struct *fsp,
1358                                       struct shadow_copy_data *shadow_copy_data,
1359                                       bool labels)
1360 {
1361         VFS_FIND(get_shadow_copy_data);
1362         return handle->fns->get_shadow_copy_data_fn(handle, fsp, 
1363                                                     shadow_copy_data,
1364                                                     labels);
1365 }
1366 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1367                          struct vfs_statvfs_struct *statbuf)
1368 {
1369         VFS_FIND(statvfs);
1370         return handle->fns->statvfs_fn(handle, path, statbuf);
1371 }
1372
1373 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1374                         enum timestamp_set_resolution *p_ts_res)
1375 {
1376         VFS_FIND(fs_capabilities);
1377         return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1378 }
1379
1380 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1381                                         struct dfs_GetDFSReferral *r)
1382 {
1383         VFS_FIND(get_dfs_referrals);
1384         return handle->fns->get_dfs_referrals_fn(handle, r);
1385 }
1386
1387 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1388                                      const char *fname, const char *mask,
1389                                      uint32 attributes)
1390 {
1391         VFS_FIND(opendir);
1392         return handle->fns->opendir_fn(handle, fname, mask, attributes);
1393 }
1394
1395 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1396                                         struct files_struct *fsp,
1397                                         const char *mask,
1398                                         uint32 attributes)
1399 {
1400         VFS_FIND(fdopendir);
1401         return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1402 }
1403
1404 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1405                                               DIR *dirp,
1406                                               SMB_STRUCT_STAT *sbuf)
1407 {
1408         VFS_FIND(readdir);
1409         return handle->fns->readdir_fn(handle, dirp, sbuf);
1410 }
1411
1412 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1413                           DIR *dirp, long offset)
1414 {
1415         VFS_FIND(seekdir);
1416         handle->fns->seekdir_fn(handle, dirp, offset);
1417 }
1418
1419 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1420                           DIR *dirp)
1421 {
1422         VFS_FIND(telldir);
1423         return handle->fns->telldir_fn(handle, dirp);
1424 }
1425
1426 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1427                              DIR *dirp)
1428 {
1429         VFS_FIND(rewind_dir);
1430         handle->fns->rewind_dir_fn(handle, dirp);
1431 }
1432
1433 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1434                        mode_t mode)
1435 {
1436         VFS_FIND(mkdir);
1437         return handle->fns->mkdir_fn(handle, path, mode);
1438 }
1439
1440 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1441 {
1442         VFS_FIND(rmdir);
1443         return handle->fns->rmdir_fn(handle, path);
1444 }
1445
1446 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1447                           DIR *dir)
1448 {
1449         VFS_FIND(closedir);
1450         return handle->fns->closedir_fn(handle, dir);
1451 }
1452
1453 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1454                                  DIR *dirp)
1455 {
1456         VFS_FIND(init_search_op);
1457         handle->fns->init_search_op_fn(handle, dirp);
1458 }
1459
1460 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1461                       struct smb_filename *smb_fname, struct files_struct *fsp,
1462                       int flags, mode_t mode)
1463 {
1464         VFS_FIND(open);
1465         return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1466 }
1467
1468 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1469                                   struct smb_request *req,
1470                                   uint16_t root_dir_fid,
1471                                   struct smb_filename *smb_fname,
1472                                   uint32_t access_mask,
1473                                   uint32_t share_access,
1474                                   uint32_t create_disposition,
1475                                   uint32_t create_options,
1476                                   uint32_t file_attributes,
1477                                   uint32_t oplock_request,
1478                                   uint64_t allocation_size,
1479                                   uint32_t private_flags,
1480                                   struct security_descriptor *sd,
1481                                   struct ea_list *ea_list,
1482                                   files_struct **result,
1483                                   int *pinfo)
1484 {
1485         VFS_FIND(create_file);
1486         return handle->fns->create_file_fn(
1487                 handle, req, root_dir_fid, smb_fname, access_mask,
1488                 share_access, create_disposition, create_options,
1489                 file_attributes, oplock_request, allocation_size,
1490                 private_flags, sd, ea_list,
1491                 result, pinfo);
1492 }
1493
1494 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1495                        struct files_struct *fsp)
1496 {
1497         VFS_FIND(close);
1498         return handle->fns->close_fn(handle, fsp);
1499 }
1500
1501 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1502                           struct files_struct *fsp, void *data, size_t n)
1503 {
1504         VFS_FIND(read);
1505         return handle->fns->read_fn(handle, fsp, data, n);
1506 }
1507
1508 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1509                            struct files_struct *fsp, void *data, size_t n,
1510                            off_t offset)
1511 {
1512         VFS_FIND(pread);
1513         return handle->fns->pread_fn(handle, fsp, data, n, offset);
1514 }
1515
1516 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1517                            struct files_struct *fsp, const void *data,
1518                            size_t n)
1519 {
1520         VFS_FIND(write);
1521         return handle->fns->write_fn(handle, fsp, data, n);
1522 }
1523
1524 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1525                             struct files_struct *fsp, const void *data,
1526                             size_t n, off_t offset)
1527 {
1528         VFS_FIND(pwrite);
1529         return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1530 }
1531
1532 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1533                              struct files_struct *fsp, off_t offset,
1534                              int whence)
1535 {
1536         VFS_FIND(lseek);
1537         return handle->fns->lseek_fn(handle, fsp, offset, whence);
1538 }
1539
1540 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1541                               files_struct *fromfsp, const DATA_BLOB *header,
1542                               off_t offset, size_t count)
1543 {
1544         VFS_FIND(sendfile);
1545         return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1546                                         count);
1547 }
1548
1549 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1550                               files_struct *tofsp, off_t offset,
1551                               size_t count)
1552 {
1553         VFS_FIND(recvfile);
1554         return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1555 }
1556
1557 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1558                         const struct smb_filename *smb_fname_src,
1559                         const struct smb_filename *smb_fname_dst)
1560 {
1561         VFS_FIND(rename);
1562         return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1563 }
1564
1565 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1566                        struct files_struct *fsp)
1567 {
1568         VFS_FIND(fsync);
1569         return handle->fns->fsync_fn(handle, fsp);
1570 }
1571
1572 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1573                       struct smb_filename *smb_fname)
1574 {
1575         VFS_FIND(stat);
1576         return handle->fns->stat_fn(handle, smb_fname);
1577 }
1578
1579 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1580                        struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1581 {
1582         VFS_FIND(fstat);
1583         return handle->fns->fstat_fn(handle, fsp, sbuf);
1584 }
1585
1586 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1587                        struct smb_filename *smb_filename)
1588 {
1589         VFS_FIND(lstat);
1590         return handle->fns->lstat_fn(handle, smb_filename);
1591 }
1592
1593 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1594                                      struct files_struct *fsp,
1595                                      const SMB_STRUCT_STAT *sbuf)
1596 {
1597         VFS_FIND(get_alloc_size);
1598         return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1599 }
1600
1601 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1602                         const struct smb_filename *smb_fname)
1603 {
1604         VFS_FIND(unlink);
1605         return handle->fns->unlink_fn(handle, smb_fname);
1606 }
1607
1608 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1609                        mode_t mode)
1610 {
1611         VFS_FIND(chmod);
1612         return handle->fns->chmod_fn(handle, path, mode);
1613 }
1614
1615 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1616                         struct files_struct *fsp, mode_t mode)
1617 {
1618         VFS_FIND(fchmod);
1619         return handle->fns->fchmod_fn(handle, fsp, mode);
1620 }
1621
1622 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1623                        uid_t uid, gid_t gid)
1624 {
1625         VFS_FIND(chown);
1626         return handle->fns->chown_fn(handle, path, uid, gid);
1627 }
1628
1629 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1630                         struct files_struct *fsp, uid_t uid, gid_t gid)
1631 {
1632         VFS_FIND(fchown);
1633         return handle->fns->fchown_fn(handle, fsp, uid, gid);
1634 }
1635
1636 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1637                         uid_t uid, gid_t gid)
1638 {
1639         VFS_FIND(lchown);
1640         return handle->fns->lchown_fn(handle, path, uid, gid);
1641 }
1642
1643 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1644 {
1645         int ret;
1646         bool as_root = false;
1647         const char *path;
1648         char *saved_dir = NULL;
1649         char *parent_dir = NULL;
1650         NTSTATUS status;
1651
1652         if (fsp->fh->fd != -1) {
1653                 /* Try fchown. */
1654                 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1655                 if (ret == 0) {
1656                         return NT_STATUS_OK;
1657                 }
1658                 if (ret == -1 && errno != ENOSYS) {
1659                         return map_nt_error_from_unix(errno);
1660                 }
1661         }
1662
1663         as_root = (geteuid() == 0);
1664
1665         if (as_root) {
1666                 /*
1667                  * We are being asked to chown as root. Make
1668                  * sure we chdir() into the path to pin it,
1669                  * and always act using lchown to ensure we
1670                  * don't deref any symbolic links.
1671                  */
1672                 const char *final_component = NULL;
1673                 struct smb_filename local_fname;
1674
1675                 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1676                 if (!saved_dir) {
1677                         status = map_nt_error_from_unix(errno);
1678                         DEBUG(0,("vfs_chown_fsp: failed to get "
1679                                 "current working directory. Error was %s\n",
1680                                 strerror(errno)));
1681                         return status;
1682                 }
1683
1684                 if (!parent_dirname(talloc_tos(),
1685                                 fsp->fsp_name->base_name,
1686                                 &parent_dir,
1687                                 &final_component)) {
1688                         return NT_STATUS_NO_MEMORY;
1689                 }
1690
1691                 /* cd into the parent dir to pin it. */
1692                 ret = vfs_ChDir(fsp->conn, parent_dir);
1693                 if (ret == -1) {
1694                         return map_nt_error_from_unix(errno);
1695                 }
1696
1697                 ZERO_STRUCT(local_fname);
1698                 local_fname.base_name = discard_const_p(char, final_component);
1699
1700                 /* Must use lstat here. */
1701                 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1702                 if (ret == -1) {
1703                         status = map_nt_error_from_unix(errno);
1704                         goto out;
1705                 }
1706
1707                 /* Ensure it matches the fsp stat. */
1708                 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1709                         status = NT_STATUS_ACCESS_DENIED;
1710                         goto out;
1711                 }
1712                 path = final_component;
1713         } else {
1714                 path = fsp->fsp_name->base_name;
1715         }
1716
1717         if (fsp->posix_open || as_root) {
1718                 ret = SMB_VFS_LCHOWN(fsp->conn,
1719                         path,
1720                         uid, gid);
1721         } else {
1722                 ret = SMB_VFS_CHOWN(fsp->conn,
1723                         path,
1724                         uid, gid);
1725         }
1726
1727         if (ret == 0) {
1728                 status = NT_STATUS_OK;
1729         } else {
1730                 status = map_nt_error_from_unix(errno);
1731         }
1732
1733   out:
1734
1735         if (as_root) {
1736                 vfs_ChDir(fsp->conn,saved_dir);
1737                 TALLOC_FREE(saved_dir);
1738                 TALLOC_FREE(parent_dir);
1739         }
1740         return status;
1741 }
1742
1743 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1744 {
1745         VFS_FIND(chdir);
1746         return handle->fns->chdir_fn(handle, path);
1747 }
1748
1749 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
1750 {
1751         VFS_FIND(getwd);
1752         return handle->fns->getwd_fn(handle);
1753 }
1754
1755 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
1756                         const struct smb_filename *smb_fname,
1757                         struct smb_file_time *ft)
1758 {
1759         VFS_FIND(ntimes);
1760         return handle->fns->ntimes_fn(handle, smb_fname, ft);
1761 }
1762
1763 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
1764                            struct files_struct *fsp, off_t offset)
1765 {
1766         VFS_FIND(ftruncate);
1767         return handle->fns->ftruncate_fn(handle, fsp, offset);
1768 }
1769
1770 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
1771                                 struct files_struct *fsp,
1772                                 enum vfs_fallocate_mode mode,
1773                                 off_t offset,
1774                                 off_t len)
1775 {
1776         VFS_FIND(fallocate);
1777         return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
1778 }
1779
1780 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
1781                               struct files_struct *fsp, uint32 share_mode,
1782                               uint32_t access_mask)
1783 {
1784         VFS_FIND(kernel_flock);
1785         return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
1786                                          access_mask);
1787 }
1788
1789 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
1790                                 struct files_struct *fsp, int leasetype)
1791 {
1792         VFS_FIND(linux_setlease);
1793         return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
1794 }
1795
1796 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
1797                          const char *newpath)
1798 {
1799         VFS_FIND(symlink);
1800         return handle->fns->symlink_fn(handle, oldpath, newpath);
1801 }
1802
1803 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
1804                               const char *path, char *buf, size_t bufsiz)
1805 {
1806         VFS_FIND(readlink);
1807         return handle->fns->readlink_fn(handle, path, buf, bufsiz);
1808 }
1809
1810 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
1811                       const char *newpath)
1812 {
1813         VFS_FIND(link);
1814         return handle->fns->link_fn(handle, oldpath, newpath);
1815 }
1816
1817 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
1818                        mode_t mode, SMB_DEV_T dev)
1819 {
1820         VFS_FIND(mknod);
1821         return handle->fns->mknod_fn(handle, path, mode, dev);
1822 }
1823
1824 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
1825 {
1826         VFS_FIND(realpath);
1827         return handle->fns->realpath_fn(handle, path);
1828 }
1829
1830 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
1831                                    struct sys_notify_context *ctx,
1832                                    const char *path,
1833                                    uint32_t *filter,
1834                                    uint32_t *subdir_filter,
1835                                    void (*callback)(struct sys_notify_context *ctx,
1836                                                     void *private_data,
1837                                                     struct notify_event *ev),
1838                                    void *private_data, void *handle_p)
1839 {
1840         VFS_FIND(notify_watch);
1841         return handle->fns->notify_watch_fn(handle, ctx, path,
1842                                             filter, subdir_filter, callback,
1843                                             private_data, handle_p);
1844 }
1845
1846 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
1847                          unsigned int flags)
1848 {
1849         VFS_FIND(chflags);
1850         return handle->fns->chflags_fn(handle, path, flags);
1851 }
1852
1853 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
1854                                            const SMB_STRUCT_STAT *sbuf)
1855 {
1856         VFS_FIND(file_id_create);
1857         return handle->fns->file_id_create_fn(handle, sbuf);
1858 }
1859
1860 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
1861                                  struct files_struct *fsp,
1862                                  const char *fname,
1863                                  TALLOC_CTX *mem_ctx,
1864                                  unsigned int *num_streams,
1865                                  struct stream_struct **streams)
1866 {
1867         VFS_FIND(streaminfo);
1868         return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
1869                                           num_streams, streams);
1870 }
1871
1872 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
1873                                    const char *path, const char *name,
1874                                    TALLOC_CTX *mem_ctx, char **found_name)
1875 {
1876         VFS_FIND(get_real_filename);
1877         return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
1878                                                  found_name);
1879 }
1880
1881 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
1882                                      const char *filename)
1883 {
1884         VFS_FIND(connectpath);
1885         return handle->fns->connectpath_fn(handle, filename);
1886 }
1887
1888 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
1889                               struct files_struct *fsp,
1890                               struct lock_struct *plock)
1891 {
1892         VFS_FIND(strict_lock);
1893         return handle->fns->strict_lock_fn(handle, fsp, plock);
1894 }
1895
1896 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
1897                                 struct files_struct *fsp,
1898                                 struct lock_struct *plock)
1899 {
1900         VFS_FIND(strict_unlock);
1901         handle->fns->strict_unlock_fn(handle, fsp, plock);
1902 }
1903
1904 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
1905                                      const char *name,
1906                                      enum vfs_translate_direction direction,
1907                                      TALLOC_CTX *mem_ctx,
1908                                      char **mapped_name)
1909 {
1910         VFS_FIND(translate_name);
1911         return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
1912                                               mapped_name);
1913 }
1914
1915 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
1916                             struct files_struct *fsp,
1917                             TALLOC_CTX *ctx,
1918                             uint32_t function,
1919                             uint16_t req_flags,
1920                             const uint8_t *in_data,
1921                             uint32_t in_len,
1922                             uint8_t **out_data,
1923                             uint32_t max_out_len,
1924                             uint32_t *out_len)
1925 {
1926         VFS_FIND(fsctl);
1927         return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags, 
1928                                      in_data, in_len, out_data, max_out_len, 
1929                                      out_len);
1930 }
1931
1932 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
1933                                   struct files_struct *fsp,
1934                                   uint32 security_info,
1935                                   struct security_descriptor **ppdesc)
1936 {
1937         VFS_FIND(fget_nt_acl);
1938         return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
1939                                            ppdesc);
1940 }
1941
1942 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
1943                                  const char *name,
1944                                  uint32 security_info,
1945                                  struct security_descriptor **ppdesc)
1946 {
1947         VFS_FIND(get_nt_acl);
1948         return handle->fns->get_nt_acl_fn(handle, name, security_info, ppdesc);
1949 }
1950
1951 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
1952                                   struct files_struct *fsp,
1953                                   uint32 security_info_sent,
1954                                   const struct security_descriptor *psd)
1955 {
1956         VFS_FIND(fset_nt_acl);
1957         return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent, 
1958                                            psd);
1959 }
1960
1961 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
1962                                  struct smb_filename *file,
1963                                  struct security_acl *sacl,
1964                                  uint32_t access_requested,
1965                                  uint32_t access_denied)
1966 {
1967         VFS_FIND(audit_file);
1968         return handle->fns->audit_file_fn(handle, 
1969                                           file, 
1970                                           sacl, 
1971                                           access_requested, 
1972                                           access_denied);
1973 }
1974
1975 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
1976                            mode_t mode)
1977 {
1978         VFS_FIND(chmod_acl);
1979         return handle->fns->chmod_acl_fn(handle, name, mode);
1980 }
1981
1982 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
1983                             struct files_struct *fsp, mode_t mode)
1984 {
1985         VFS_FIND(fchmod_acl);
1986         return handle->fns->fchmod_acl_fn(handle, fsp, mode);
1987 }
1988
1989 int smb_vfs_call_sys_acl_get_entry(struct vfs_handle_struct *handle,
1990                                    SMB_ACL_T theacl, int entry_id,
1991                                    SMB_ACL_ENTRY_T *entry_p)
1992 {
1993         VFS_FIND(sys_acl_get_entry);
1994         return handle->fns->sys_acl_get_entry_fn(handle, theacl, entry_id,
1995                                                  entry_p);
1996 }
1997
1998 int smb_vfs_call_sys_acl_get_tag_type(struct vfs_handle_struct *handle,
1999                                       SMB_ACL_ENTRY_T entry_d,
2000                                       SMB_ACL_TAG_T *tag_type_p)
2001 {
2002         VFS_FIND(sys_acl_get_tag_type);
2003         return handle->fns->sys_acl_get_tag_type_fn(handle, entry_d, 
2004                                                     tag_type_p);
2005 }
2006
2007 int smb_vfs_call_sys_acl_get_permset(struct vfs_handle_struct *handle,
2008                                      SMB_ACL_ENTRY_T entry_d,
2009                                      SMB_ACL_PERMSET_T *permset_p)
2010 {
2011         VFS_FIND(sys_acl_get_permset);
2012         return handle->fns->sys_acl_get_permset_fn(handle, entry_d, permset_p);
2013 }
2014
2015 void * smb_vfs_call_sys_acl_get_qualifier(struct vfs_handle_struct *handle,
2016                                           SMB_ACL_ENTRY_T entry_d)
2017 {
2018         VFS_FIND(sys_acl_get_qualifier);
2019         return handle->fns->sys_acl_get_qualifier_fn(handle, entry_d);
2020 }
2021
2022 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2023                                         const char *path_p,
2024                                         SMB_ACL_TYPE_T type)
2025 {
2026         VFS_FIND(sys_acl_get_file);
2027         return handle->fns->sys_acl_get_file_fn(handle, path_p, type);
2028 }
2029
2030 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2031                                       struct files_struct *fsp)
2032 {
2033         VFS_FIND(sys_acl_get_fd);
2034         return handle->fns->sys_acl_get_fd_fn(handle, fsp);
2035 }
2036
2037 int smb_vfs_call_sys_acl_clear_perms(struct vfs_handle_struct *handle,
2038                                      SMB_ACL_PERMSET_T permset)
2039 {
2040         VFS_FIND(sys_acl_clear_perms);
2041         return handle->fns->sys_acl_clear_perms_fn(handle, permset);
2042 }
2043
2044 int smb_vfs_call_sys_acl_add_perm(struct vfs_handle_struct *handle,
2045                                   SMB_ACL_PERMSET_T permset,
2046                                   SMB_ACL_PERM_T perm)
2047 {
2048         VFS_FIND(sys_acl_add_perm);
2049         return handle->fns->sys_acl_add_perm_fn(handle, permset, perm);
2050 }
2051
2052 char * smb_vfs_call_sys_acl_to_text(struct vfs_handle_struct *handle,
2053                                     SMB_ACL_T theacl, ssize_t *plen)
2054 {
2055         VFS_FIND(sys_acl_to_text);
2056         return handle->fns->sys_acl_to_text_fn(handle, theacl, plen);
2057 }
2058
2059 SMB_ACL_T smb_vfs_call_sys_acl_init(struct vfs_handle_struct *handle,
2060                                     int count)
2061 {
2062         VFS_FIND(sys_acl_init);
2063         return handle->fns->sys_acl_init_fn(handle, count);
2064 }
2065
2066 int smb_vfs_call_sys_acl_create_entry(struct vfs_handle_struct *handle,
2067                                       SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2068 {
2069         VFS_FIND(sys_acl_create_entry);
2070         return handle->fns->sys_acl_create_entry_fn(handle, pacl, pentry);
2071 }
2072
2073 int smb_vfs_call_sys_acl_set_tag_type(struct vfs_handle_struct *handle,
2074                                       SMB_ACL_ENTRY_T entry,
2075                                       SMB_ACL_TAG_T tagtype)
2076 {
2077         VFS_FIND(sys_acl_set_tag_type);
2078         return handle->fns->sys_acl_set_tag_type_fn(handle, entry, tagtype);
2079 }
2080
2081 int smb_vfs_call_sys_acl_set_qualifier(struct vfs_handle_struct *handle,
2082                                        SMB_ACL_ENTRY_T entry, void *qual)
2083 {
2084         VFS_FIND(sys_acl_set_qualifier);
2085         return handle->fns->sys_acl_set_qualifier_fn(handle, entry, qual);
2086 }
2087
2088 int smb_vfs_call_sys_acl_set_permset(struct vfs_handle_struct *handle,
2089                                      SMB_ACL_ENTRY_T entry,
2090                                      SMB_ACL_PERMSET_T permset)
2091 {
2092         VFS_FIND(sys_acl_set_permset);
2093         return handle->fns->sys_acl_set_permset_fn(handle, entry, permset);
2094 }
2095
2096 int smb_vfs_call_sys_acl_valid(struct vfs_handle_struct *handle,
2097                                SMB_ACL_T theacl)
2098 {
2099         VFS_FIND(sys_acl_valid);
2100         return handle->fns->sys_acl_valid_fn(handle, theacl);
2101 }
2102
2103 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2104                                   const char *name, SMB_ACL_TYPE_T acltype,
2105                                   SMB_ACL_T theacl)
2106 {
2107         VFS_FIND(sys_acl_set_file);
2108         return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2109 }
2110
2111 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2112                                 struct files_struct *fsp, SMB_ACL_T theacl)
2113 {
2114         VFS_FIND(sys_acl_set_fd);
2115         return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2116 }
2117
2118 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2119                                          const char *path)
2120 {
2121         VFS_FIND(sys_acl_delete_def_file);
2122         return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2123 }
2124
2125 int smb_vfs_call_sys_acl_get_perm(struct vfs_handle_struct *handle,
2126                                   SMB_ACL_PERMSET_T permset,
2127                                   SMB_ACL_PERM_T perm)
2128 {
2129         VFS_FIND(sys_acl_get_perm);
2130         return handle->fns->sys_acl_get_perm_fn(handle, permset, perm);
2131 }
2132
2133 int smb_vfs_call_sys_acl_free_text(struct vfs_handle_struct *handle,
2134                                    char *text)
2135 {
2136         VFS_FIND(sys_acl_free_text);
2137         return handle->fns->sys_acl_free_text_fn(handle, text);
2138 }
2139
2140 int smb_vfs_call_sys_acl_free_acl(struct vfs_handle_struct *handle,
2141                                   SMB_ACL_T posix_acl)
2142 {
2143         VFS_FIND(sys_acl_free_acl);
2144         return handle->fns->sys_acl_free_acl_fn(handle, posix_acl);
2145 }
2146
2147 int smb_vfs_call_sys_acl_free_qualifier(struct vfs_handle_struct *handle,
2148                                         void *qualifier, SMB_ACL_TAG_T tagtype)
2149 {
2150         VFS_FIND(sys_acl_free_qualifier);
2151         return handle->fns->sys_acl_free_qualifier_fn(handle, qualifier, 
2152                                                       tagtype);
2153 }
2154
2155 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2156                               const char *path, const char *name, void *value,
2157                               size_t size)
2158 {
2159         VFS_FIND(getxattr);
2160         return handle->fns->getxattr_fn(handle, path, name, value, size);
2161 }
2162
2163 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2164                                struct files_struct *fsp, const char *name,
2165                                void *value, size_t size)
2166 {
2167         VFS_FIND(fgetxattr);
2168         return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2169 }
2170
2171 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2172                                const char *path, char *list, size_t size)
2173 {
2174         VFS_FIND(listxattr);
2175         return handle->fns->listxattr_fn(handle, path, list, size);
2176 }
2177
2178 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2179                                 struct files_struct *fsp, char *list,
2180                                 size_t size)
2181 {
2182         VFS_FIND(flistxattr);
2183         return handle->fns->flistxattr_fn(handle, fsp, list, size);
2184 }
2185
2186 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2187                              const char *path, const char *name)
2188 {
2189         VFS_FIND(removexattr);
2190         return handle->fns->removexattr_fn(handle, path, name);
2191 }
2192
2193 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2194                               struct files_struct *fsp, const char *name)
2195 {
2196         VFS_FIND(fremovexattr);
2197         return handle->fns->fremovexattr_fn(handle, fsp, name);
2198 }
2199
2200 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2201                           const char *name, const void *value, size_t size,
2202                           int flags)
2203 {
2204         VFS_FIND(setxattr);
2205         return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2206 }
2207
2208 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2209                            struct files_struct *fsp, const char *name,
2210                            const void *value, size_t size, int flags)
2211 {
2212         VFS_FIND(fsetxattr);
2213         return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2214 }
2215
2216 int smb_vfs_call_aio_read(struct vfs_handle_struct *handle,
2217                           struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2218 {
2219         VFS_FIND(aio_read);
2220         return handle->fns->aio_read_fn(handle, fsp, aiocb);
2221 }
2222
2223 int smb_vfs_call_aio_write(struct vfs_handle_struct *handle,
2224                            struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2225 {
2226         VFS_FIND(aio_write);
2227         return handle->fns->aio_write_fn(handle, fsp, aiocb);
2228 }
2229
2230 ssize_t smb_vfs_call_aio_return(struct vfs_handle_struct *handle,
2231                                 struct files_struct *fsp,
2232                                 SMB_STRUCT_AIOCB *aiocb)
2233 {
2234         VFS_FIND(aio_return);
2235         return handle->fns->aio_return_fn(handle, fsp, aiocb);
2236 }
2237
2238 int smb_vfs_call_aio_cancel(struct vfs_handle_struct *handle,
2239                             struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2240 {
2241         VFS_FIND(aio_cancel);
2242         return handle->fns->aio_cancel_fn(handle, fsp, aiocb);
2243 }
2244
2245 int smb_vfs_call_aio_error(struct vfs_handle_struct *handle,
2246                            struct files_struct *fsp,
2247                            SMB_STRUCT_AIOCB *aiocb)
2248 {
2249         VFS_FIND(aio_error);
2250         return handle->fns->aio_error_fn(handle, fsp, aiocb);
2251 }
2252
2253 int smb_vfs_call_aio_fsync(struct vfs_handle_struct *handle,
2254                            struct files_struct *fsp, int op,
2255                            SMB_STRUCT_AIOCB *aiocb)
2256 {
2257         VFS_FIND(aio_fsync);
2258         return handle->fns->aio_fsync_fn(handle, fsp, op, aiocb);
2259 }
2260
2261 int smb_vfs_call_aio_suspend(struct vfs_handle_struct *handle,
2262                              struct files_struct *fsp,
2263                              const SMB_STRUCT_AIOCB * const aiocb[], int n,
2264                              const struct timespec *timeout)
2265 {
2266         VFS_FIND(aio_suspend);
2267         return handle->fns->aio_suspend_fn(handle, fsp, aiocb, n, timeout);
2268 }
2269
2270 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2271                             struct files_struct *fsp)
2272 {
2273         VFS_FIND(aio_force);
2274         return handle->fns->aio_force_fn(handle, fsp);
2275 }
2276
2277 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2278                              const struct smb_filename *fname,
2279                              SMB_STRUCT_STAT *sbuf)
2280 {
2281         VFS_FIND(is_offline);
2282         return handle->fns->is_offline_fn(handle, fname, sbuf);
2283 }
2284
2285 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2286                              const struct smb_filename *fname)
2287 {
2288         VFS_FIND(set_offline);
2289         return handle->fns->set_offline_fn(handle, fname);
2290 }