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