s3: Pass filters explicitly through vfs notify watch
[bbaumbach/samba-autobuild/.git] / source3 / smbd / vfs.c
1 /*
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    VFS initialisation and support functions
5    Copyright (C) Tim Potter 1999
6    Copyright (C) Alexander Bokovoy 2002
7    Copyright (C) James Peach 2006
8    Copyright (C) Volker Lendecke 2009
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
23    This work was sponsored by Optifacio Software Services, Inc.
24 */
25
26 #include "includes.h"
27 #include "system/filesys.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "memcache.h"
31 #include "transfer_file.h"
32 #include "ntioctl.h"
33
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_VFS
36
37 static_decl_vfs;
38
39 struct vfs_init_function_entry {
40         char *name;
41         struct vfs_init_function_entry *prev, *next;
42         const struct vfs_fn_pointers *fns;
43 };
44
45 /****************************************************************************
46     maintain the list of available backends
47 ****************************************************************************/
48
49 static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
50 {
51         struct vfs_init_function_entry *entry = backends;
52
53         DEBUG(10, ("vfs_find_backend_entry called for %s\n", name));
54
55         while(entry) {
56                 if (strcmp(entry->name, name)==0) return entry;
57                 entry = entry->next;
58         }
59
60         return NULL;
61 }
62
63 NTSTATUS smb_register_vfs(int version, const char *name,
64                           const struct vfs_fn_pointers *fns)
65 {
66         struct vfs_init_function_entry *entry = backends;
67
68         if ((version != SMB_VFS_INTERFACE_VERSION)) {
69                 DEBUG(0, ("Failed to register vfs module.\n"
70                           "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
71                           "current SMB_VFS_INTERFACE_VERSION is %d.\n"
72                           "Please recompile against the current Samba Version!\n",  
73                           version, SMB_VFS_INTERFACE_VERSION));
74                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
75         }
76
77         if (!name || !name[0]) {
78                 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
79                 return NT_STATUS_INVALID_PARAMETER;
80         }
81
82         if (vfs_find_backend_entry(name)) {
83                 DEBUG(0,("VFS module %s already loaded!\n", name));
84                 return NT_STATUS_OBJECT_NAME_COLLISION;
85         }
86
87         entry = SMB_XMALLOC_P(struct vfs_init_function_entry);
88         entry->name = smb_xstrdup(name);
89         entry->fns = fns;
90
91         DLIST_ADD(backends, entry);
92         DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
93         return NT_STATUS_OK;
94 }
95
96 /****************************************************************************
97   initialise default vfs hooks
98 ****************************************************************************/
99
100 static void vfs_init_default(connection_struct *conn)
101 {
102         DEBUG(3, ("Initialising default vfs hooks\n"));
103         vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME);
104 }
105
106 /****************************************************************************
107   initialise custom vfs hooks
108  ****************************************************************************/
109
110 bool vfs_init_custom(connection_struct *conn, const char *vfs_object)
111 {
112         char *module_path = NULL;
113         char *module_name = NULL;
114         char *module_param = NULL, *p;
115         vfs_handle_struct *handle;
116         const struct vfs_init_function_entry *entry;
117
118         if (!conn||!vfs_object||!vfs_object[0]) {
119                 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
120                           "empty vfs_object!\n"));
121                 return False;
122         }
123
124         if(!backends) {
125                 static_init_vfs;
126         }
127
128         DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
129
130         module_path = smb_xstrdup(vfs_object);
131
132         p = strchr_m(module_path, ':');
133
134         if (p) {
135                 *p = 0;
136                 module_param = p+1;
137                 trim_char(module_param, ' ', ' ');
138         }
139
140         trim_char(module_path, ' ', ' ');
141
142         module_name = smb_xstrdup(module_path);
143
144         if ((module_name[0] == '/') &&
145             (strcmp(module_path, DEFAULT_VFS_MODULE_NAME) != 0)) {
146
147                 /*
148                  * Extract the module name from the path. Just use the base
149                  * name of the last path component.
150                  */
151
152                 SAFE_FREE(module_name);
153                 module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
154
155                 p = strchr_m(module_name, '.');
156
157                 if (p != NULL) {
158                         *p = '\0';
159                 }
160         }
161
162         /* First, try to load the module with the new module system */
163         entry = vfs_find_backend_entry(module_name);
164         if (!entry) {
165                 NTSTATUS status;
166
167                 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
168                           vfs_object));
169
170                 status = smb_probe_module("vfs", module_path);
171                 if (!NT_STATUS_IS_OK(status)) {
172                         DEBUG(0, ("error probing vfs module '%s': %s\n",
173                                   module_path, nt_errstr(status)));
174                         goto fail;
175                 }
176
177                 entry = vfs_find_backend_entry(module_name);
178                 if (!entry) {
179                         DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
180                         goto fail;
181                 }
182         }
183
184         DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
185
186         handle = talloc_zero(conn, vfs_handle_struct);
187         if (!handle) {
188                 DEBUG(0,("TALLOC_ZERO() failed!\n"));
189                 goto fail;
190         }
191         handle->conn = conn;
192         handle->fns = entry->fns;
193         if (module_param) {
194                 handle->param = talloc_strdup(conn, module_param);
195         }
196         DLIST_ADD(conn->vfs_handles, handle);
197
198         SAFE_FREE(module_path);
199         SAFE_FREE(module_name);
200         return True;
201
202  fail:
203         SAFE_FREE(module_path);
204         SAFE_FREE(module_name);
205         return False;
206 }
207
208 /*****************************************************************
209  Allow VFS modules to extend files_struct with VFS-specific state.
210  This will be ok for small numbers of extensions, but might need to
211  be refactored if it becomes more widely used.
212 ******************************************************************/
213
214 #define EXT_DATA_AREA(e) ((uint8 *)(e) + sizeof(struct vfs_fsp_data))
215
216 void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle,
217                                    files_struct *fsp, size_t ext_size,
218                                    void (*destroy_fn)(void *p_data))
219 {
220         struct vfs_fsp_data *ext;
221         void * ext_data;
222
223         /* Prevent VFS modules adding multiple extensions. */
224         if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
225                 return ext_data;
226         }
227
228         ext = (struct vfs_fsp_data *)TALLOC_ZERO(
229                 handle->conn, sizeof(struct vfs_fsp_data) + ext_size);
230         if (ext == NULL) {
231                 return NULL;
232         }
233
234         ext->owner = handle;
235         ext->next = fsp->vfs_extension;
236         ext->destroy = destroy_fn;
237         fsp->vfs_extension = ext;
238         return EXT_DATA_AREA(ext);
239 }
240
241 void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
242 {
243         struct vfs_fsp_data *curr;
244         struct vfs_fsp_data *prev;
245
246         for (curr = fsp->vfs_extension, prev = NULL;
247              curr;
248              prev = curr, curr = curr->next) {
249                 if (curr->owner == handle) {
250                     if (prev) {
251                             prev->next = curr->next;
252                     } else {
253                             fsp->vfs_extension = curr->next;
254                     }
255                     if (curr->destroy) {
256                             curr->destroy(EXT_DATA_AREA(curr));
257                     }
258                     TALLOC_FREE(curr);
259                     return;
260                 }
261         }
262 }
263
264 void *vfs_memctx_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
265 {
266         struct vfs_fsp_data *head;
267
268         for (head = fsp->vfs_extension; head; head = head->next) {
269                 if (head->owner == handle) {
270                         return head;
271                 }
272         }
273
274         return NULL;
275 }
276
277 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
278 {
279         struct vfs_fsp_data *head;
280
281         head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
282         if (head != NULL) {
283                 return EXT_DATA_AREA(head);
284         }
285
286         return NULL;
287 }
288
289 #undef EXT_DATA_AREA
290
291 /*****************************************************************
292  Generic VFS init.
293 ******************************************************************/
294
295 bool smbd_vfs_init(connection_struct *conn)
296 {
297         const char **vfs_objects;
298         unsigned int i = 0;
299         int j = 0;
300
301         /* Normal share - initialise with disk access functions */
302         vfs_init_default(conn);
303         vfs_objects = lp_vfs_objects(SNUM(conn));
304
305         /* Override VFS functions if 'vfs object' was not specified*/
306         if (!vfs_objects || !vfs_objects[0])
307                 return True;
308
309         for (i=0; vfs_objects[i] ;) {
310                 i++;
311         }
312
313         for (j=i-1; j >= 0; j--) {
314                 if (!vfs_init_custom(conn, vfs_objects[j])) {
315                         DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
316                         return False;
317                 }
318         }
319         return True;
320 }
321
322 /*******************************************************************
323  Check if a file exists in the vfs.
324 ********************************************************************/
325
326 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
327 {
328         /* Only return OK if stat was successful and S_ISREG */
329         if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
330             S_ISREG(smb_fname->st.st_ex_mode)) {
331                 return NT_STATUS_OK;
332         }
333
334         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
335 }
336
337 /****************************************************************************
338  Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
339 ****************************************************************************/
340
341 ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
342 {
343         size_t total=0;
344
345         while (total < byte_count)
346         {
347                 ssize_t ret = SMB_VFS_READ(fsp, buf + total,
348                                            byte_count - total);
349
350                 if (ret == 0) return total;
351                 if (ret == -1) {
352                         if (errno == EINTR)
353                                 continue;
354                         else
355                                 return -1;
356                 }
357                 total += ret;
358         }
359         return (ssize_t)total;
360 }
361
362 ssize_t vfs_pread_data(files_struct *fsp, char *buf,
363                 size_t byte_count, SMB_OFF_T offset)
364 {
365         size_t total=0;
366
367         while (total < byte_count)
368         {
369                 ssize_t ret = SMB_VFS_PREAD(fsp, buf + total,
370                                         byte_count - total, offset + total);
371
372                 if (ret == 0) return total;
373                 if (ret == -1) {
374                         if (errno == EINTR)
375                                 continue;
376                         else
377                                 return -1;
378                 }
379                 total += ret;
380         }
381         return (ssize_t)total;
382 }
383
384 /****************************************************************************
385  Write data to a fd on the vfs.
386 ****************************************************************************/
387
388 ssize_t vfs_write_data(struct smb_request *req,
389                         files_struct *fsp,
390                         const char *buffer,
391                         size_t N)
392 {
393         size_t total=0;
394         ssize_t ret;
395
396         if (req && req->unread_bytes) {
397                 SMB_ASSERT(req->unread_bytes == N);
398                 /* VFS_RECVFILE must drain the socket
399                  * before returning. */
400                 req->unread_bytes = 0;
401                 return SMB_VFS_RECVFILE(req->sconn->sock,
402                                         fsp,
403                                         (SMB_OFF_T)-1,
404                                         N);
405         }
406
407         while (total < N) {
408                 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
409
410                 if (ret == -1)
411                         return -1;
412                 if (ret == 0)
413                         return total;
414
415                 total += ret;
416         }
417         return (ssize_t)total;
418 }
419
420 ssize_t vfs_pwrite_data(struct smb_request *req,
421                         files_struct *fsp,
422                         const char *buffer,
423                         size_t N,
424                         SMB_OFF_T offset)
425 {
426         size_t total=0;
427         ssize_t ret;
428
429         if (req && req->unread_bytes) {
430                 SMB_ASSERT(req->unread_bytes == N);
431                 /* VFS_RECVFILE must drain the socket
432                  * before returning. */
433                 req->unread_bytes = 0;
434                 return SMB_VFS_RECVFILE(req->sconn->sock,
435                                         fsp,
436                                         offset,
437                                         N);
438         }
439
440         while (total < N) {
441                 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
442                                      offset + total);
443
444                 if (ret == -1)
445                         return -1;
446                 if (ret == 0)
447                         return total;
448
449                 total += ret;
450         }
451         return (ssize_t)total;
452 }
453 /****************************************************************************
454  An allocate file space call using the vfs interface.
455  Allocates space for a file from a filedescriptor.
456  Returns 0 on success, -1 on failure.
457 ****************************************************************************/
458
459 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
460 {
461         int ret;
462         connection_struct *conn = fsp->conn;
463         uint64_t space_avail;
464         uint64_t bsize,dfree,dsize;
465         NTSTATUS status;
466
467         /*
468          * Actually try and commit the space on disk....
469          */
470
471         DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
472                   fsp_str_dbg(fsp), (double)len));
473
474         if (((SMB_OFF_T)len) < 0) {
475                 DEBUG(0,("vfs_allocate_file_space: %s negative len "
476                          "requested.\n", fsp_str_dbg(fsp)));
477                 errno = EINVAL;
478                 return -1;
479         }
480
481         status = vfs_stat_fsp(fsp);
482         if (!NT_STATUS_IS_OK(status)) {
483                 return -1;
484         }
485
486         if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
487                 return 0;
488
489         if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
490                 /* Shrink - use ftruncate. */
491
492                 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
493                           "size %.0f\n", fsp_str_dbg(fsp),
494                           (double)fsp->fsp_name->st.st_ex_size));
495
496                 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
497
498                 flush_write_cache(fsp, SIZECHANGE_FLUSH);
499                 if ((ret = SMB_VFS_FTRUNCATE(fsp, (SMB_OFF_T)len)) != -1) {
500                         set_filelen_write_cache(fsp, len);
501                 }
502
503                 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
504
505                 return ret;
506         }
507
508         if (!lp_strict_allocate(SNUM(fsp->conn)))
509                 return 0;
510
511         /* Grow - we need to test if we have enough space. */
512
513         contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
514
515         /* See if we have a syscall that will allocate beyond end-of-file
516            without changing EOF. */
517         ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
518
519         contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
520
521         if (ret == 0) {
522                 /* We changed the allocation size on disk, but not
523                    EOF - exactly as required. We're done ! */
524                 return 0;
525         }
526
527         len -= fsp->fsp_name->st.st_ex_size;
528         len /= 1024; /* Len is now number of 1k blocks needed. */
529         space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
530                                      &bsize, &dfree, &dsize);
531         if (space_avail == (uint64_t)-1) {
532                 return -1;
533         }
534
535         DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
536                   "needed blocks = %.0f, space avail = %.0f\n",
537                   fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
538                   (double)space_avail));
539
540         if (len > space_avail) {
541                 errno = ENOSPC;
542                 return -1;
543         }
544
545         return 0;
546 }
547
548 /****************************************************************************
549  A vfs set_filelen call.
550  set the length of a file from a filedescriptor.
551  Returns 0 on success, -1 on failure.
552 ****************************************************************************/
553
554 int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len)
555 {
556         int ret;
557
558         contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
559
560         DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
561                   fsp_str_dbg(fsp), (double)len));
562         flush_write_cache(fsp, SIZECHANGE_FLUSH);
563         if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
564                 set_filelen_write_cache(fsp, len);
565                 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
566                              FILE_NOTIFY_CHANGE_SIZE
567                              | FILE_NOTIFY_CHANGE_ATTRIBUTES,
568                              fsp->fsp_name->base_name);
569         }
570
571         contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
572
573         return ret;
574 }
575
576 /****************************************************************************
577  A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
578  fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
579  as this is also called from the default SMB_VFS_FTRUNCATE code.
580  Always extends the file size.
581  Returns 0 on success, errno on failure.
582 ****************************************************************************/
583
584 #define SPARSE_BUF_WRITE_SIZE (32*1024)
585
586 int vfs_slow_fallocate(files_struct *fsp, SMB_OFF_T offset, SMB_OFF_T len)
587 {
588         ssize_t pwrite_ret;
589         size_t total = 0;
590
591         if (!sparse_buf) {
592                 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
593                 if (!sparse_buf) {
594                         errno = ENOMEM;
595                         return ENOMEM;
596                 }
597         }
598
599         while (total < len) {
600                 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
601
602                 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
603                 if (pwrite_ret == -1) {
604                         DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
605                                   "%s failed with error %s\n",
606                                   fsp_str_dbg(fsp), strerror(errno)));
607                         return errno;
608                 }
609                 total += pwrite_ret;
610         }
611
612         return 0;
613 }
614
615 /****************************************************************************
616  A vfs fill sparse call.
617  Writes zeros from the end of file to len, if len is greater than EOF.
618  Used only by strict_sync.
619  Returns 0 on success, -1 on failure.
620 ****************************************************************************/
621
622 int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
623 {
624         int ret;
625         NTSTATUS status;
626         SMB_OFF_T offset;
627         size_t num_to_write;
628
629         status = vfs_stat_fsp(fsp);
630         if (!NT_STATUS_IS_OK(status)) {
631                 return -1;
632         }
633
634         if (len <= fsp->fsp_name->st.st_ex_size) {
635                 return 0;
636         }
637
638 #ifdef S_ISFIFO
639         if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
640                 return 0;
641         }
642 #endif
643
644         DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
645                   "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
646                   (double)fsp->fsp_name->st.st_ex_size, (double)len,
647                   (double)(len - fsp->fsp_name->st.st_ex_size)));
648
649         contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
650
651         flush_write_cache(fsp, SIZECHANGE_FLUSH);
652
653         offset = fsp->fsp_name->st.st_ex_size;
654         num_to_write = len - fsp->fsp_name->st.st_ex_size;
655
656         /* Only do this on non-stream file handles. */
657         if (fsp->base_fsp == NULL) {
658                 /* for allocation try fallocate first. This can fail on some
659                  * platforms e.g. when the filesystem doesn't support it and no
660                  * emulation is being done by the libc (like on AIX with JFS1). In that
661                  * case we do our own emulation. fallocate implementations can
662                  * return ENOTSUP or EINVAL in cases like that. */
663                 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
664                                 offset, num_to_write);
665                 if (ret == ENOSPC) {
666                         errno = ENOSPC;
667                         ret = -1;
668                         goto out;
669                 }
670                 if (ret == 0) {
671                         goto out;
672                 }
673                 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
674                         "error %d. Falling back to slow manual allocation\n", ret));
675         }
676
677         ret = vfs_slow_fallocate(fsp, offset, num_to_write);
678         if (ret != 0) {
679                 errno = ret;
680                 ret = -1;
681         }
682
683  out:
684
685         if (ret == 0) {
686                 set_filelen_write_cache(fsp, len);
687         }
688
689         contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
690         return ret;
691 }
692
693 /****************************************************************************
694  Transfer some data (n bytes) between two file_struct's.
695 ****************************************************************************/
696
697 static ssize_t vfs_read_fn(void *file, void *buf, size_t len)
698 {
699         struct files_struct *fsp = (struct files_struct *)file;
700
701         return SMB_VFS_READ(fsp, buf, len);
702 }
703
704 static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
705 {
706         struct files_struct *fsp = (struct files_struct *)file;
707
708         return SMB_VFS_WRITE(fsp, buf, len);
709 }
710
711 SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n)
712 {
713         return transfer_file_internal((void *)in, (void *)out, n,
714                                       vfs_read_fn, vfs_write_fn);
715 }
716
717 /*******************************************************************
718  A vfs_readdir wrapper which just returns the file name.
719 ********************************************************************/
720
721 const char *vfs_readdirname(connection_struct *conn, void *p,
722                             SMB_STRUCT_STAT *sbuf, char **talloced)
723 {
724         SMB_STRUCT_DIRENT *ptr= NULL;
725         const char *dname;
726         char *translated;
727         NTSTATUS status;
728
729         if (!p)
730                 return(NULL);
731
732         ptr = SMB_VFS_READDIR(conn, (SMB_STRUCT_DIR *)p, sbuf);
733         if (!ptr)
734                 return(NULL);
735
736         dname = ptr->d_name;
737
738
739 #ifdef NEXT2
740         if (telldir(p) < 0)
741                 return(NULL);
742 #endif
743
744 #ifdef HAVE_BROKEN_READDIR_NAME
745         /* using /usr/ucb/cc is BAD */
746         dname = dname - 2;
747 #endif
748
749         status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
750                                         talloc_tos(), &translated);
751         if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
752                 *talloced = NULL;
753                 return dname;
754         }
755         *talloced = translated;
756         if (!NT_STATUS_IS_OK(status)) {
757                 return NULL;
758         }
759         return translated;
760 }
761
762 /*******************************************************************
763  A wrapper for vfs_chdir().
764 ********************************************************************/
765
766 int vfs_ChDir(connection_struct *conn, const char *path)
767 {
768         int res;
769
770         if (!LastDir) {
771                 LastDir = SMB_STRDUP("");
772         }
773
774         if (strcsequal(path,"."))
775                 return(0);
776
777         if (*path == '/' && strcsequal(LastDir,path))
778                 return(0);
779
780         DEBUG(4,("vfs_ChDir to %s\n",path));
781
782         res = SMB_VFS_CHDIR(conn,path);
783         if (!res) {
784                 SAFE_FREE(LastDir);
785                 LastDir = SMB_STRDUP(path);
786         }
787         return(res);
788 }
789
790 /*******************************************************************
791  Return the absolute current directory path - given a UNIX pathname.
792  Note that this path is returned in DOS format, not UNIX
793  format. Note this can be called with conn == NULL.
794 ********************************************************************/
795
796 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
797 {
798         char *current_dir = NULL;
799         char *result = NULL;
800         DATA_BLOB cache_value;
801         struct file_id key;
802         struct smb_filename *smb_fname_dot = NULL;
803         struct smb_filename *smb_fname_full = NULL;
804         NTSTATUS status;
805
806         if (!lp_getwd_cache()) {
807                 goto nocache;
808         }
809
810         status = create_synthetic_smb_fname(ctx, ".", NULL, NULL,
811                                             &smb_fname_dot);
812         if (!NT_STATUS_IS_OK(status)) {
813                 errno = map_errno_from_nt_status(status);
814                 goto out;
815         }
816
817         if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
818                 /*
819                  * Known to fail for root: the directory may be NFS-mounted
820                  * and exported with root_squash (so has no root access).
821                  */
822                 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
823                          "(NFS problem ?)\n", strerror(errno) ));
824                 goto nocache;
825         }
826
827         key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
828
829         if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
830                              data_blob_const(&key, sizeof(key)),
831                              &cache_value)) {
832                 goto nocache;
833         }
834
835         SMB_ASSERT((cache_value.length > 0)
836                    && (cache_value.data[cache_value.length-1] == '\0'));
837
838         status = create_synthetic_smb_fname(ctx, (char *)cache_value.data,
839                                             NULL, NULL, &smb_fname_full);
840         if (!NT_STATUS_IS_OK(status)) {
841                 errno = map_errno_from_nt_status(status);
842                 goto out;
843         }
844
845         if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
846             (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
847             (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
848             (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
849                 /*
850                  * Ok, we're done
851                  */
852                 result = talloc_strdup(ctx, smb_fname_full->base_name);
853                 if (result == NULL) {
854                         errno = ENOMEM;
855                 }
856                 goto out;
857         }
858
859  nocache:
860
861         /*
862          * We don't have the information to hand so rely on traditional
863          * methods. The very slow getcwd, which spawns a process on some
864          * systems, or the not quite so bad getwd.
865          */
866
867         current_dir = SMB_VFS_GETWD(conn);
868         if (current_dir == NULL) {
869                 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
870                           strerror(errno)));
871                 goto out;
872         }
873
874         if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
875                 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
876
877                 memcache_add(smbd_memcache(), GETWD_CACHE,
878                              data_blob_const(&key, sizeof(key)),
879                              data_blob_const(current_dir,
880                                                 strlen(current_dir)+1));
881         }
882
883         result = talloc_strdup(ctx, current_dir);
884         if (result == NULL) {
885                 errno = ENOMEM;
886         }
887
888  out:
889         TALLOC_FREE(smb_fname_dot);
890         TALLOC_FREE(smb_fname_full);
891         SAFE_FREE(current_dir);
892         return result;
893 }
894
895 /*******************************************************************
896  Reduce a file name, removing .. elements and checking that
897  it is below dir in the heirachy. This uses realpath.
898  This function must run as root, and will return names
899  and valid stat structs that can be checked on open.
900 ********************************************************************/
901
902 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
903                         const char *fname,
904                         struct smb_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                                    const char *path,
1837                                    uint32_t *filter,
1838                                    uint32_t *subdir_filter,
1839                                    void (*callback)(struct sys_notify_context *ctx,
1840                                                     void *private_data,
1841                                                     struct notify_event *ev),
1842                                    void *private_data, void *handle_p)
1843 {
1844         VFS_FIND(notify_watch);
1845         return handle->fns->notify_watch_fn(handle, ctx, path,
1846                                             filter, subdir_filter, callback,
1847                                             private_data, handle_p);
1848 }
1849
1850 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
1851                          unsigned int flags)
1852 {
1853         VFS_FIND(chflags);
1854         return handle->fns->chflags_fn(handle, path, flags);
1855 }
1856
1857 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
1858                                            const SMB_STRUCT_STAT *sbuf)
1859 {
1860         VFS_FIND(file_id_create);
1861         return handle->fns->file_id_create_fn(handle, sbuf);
1862 }
1863
1864 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
1865                                  struct files_struct *fsp,
1866                                  const char *fname,
1867                                  TALLOC_CTX *mem_ctx,
1868                                  unsigned int *num_streams,
1869                                  struct stream_struct **streams)
1870 {
1871         VFS_FIND(streaminfo);
1872         return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
1873                                           num_streams, streams);
1874 }
1875
1876 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
1877                                    const char *path, const char *name,
1878                                    TALLOC_CTX *mem_ctx, char **found_name)
1879 {
1880         VFS_FIND(get_real_filename);
1881         return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
1882                                                  found_name);
1883 }
1884
1885 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
1886                                      const char *filename)
1887 {
1888         VFS_FIND(connectpath);
1889         return handle->fns->connectpath_fn(handle, filename);
1890 }
1891
1892 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
1893                               struct files_struct *fsp,
1894                               struct lock_struct *plock)
1895 {
1896         VFS_FIND(strict_lock);
1897         return handle->fns->strict_lock_fn(handle, fsp, plock);
1898 }
1899
1900 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
1901                                 struct files_struct *fsp,
1902                                 struct lock_struct *plock)
1903 {
1904         VFS_FIND(strict_unlock);
1905         handle->fns->strict_unlock_fn(handle, fsp, plock);
1906 }
1907
1908 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
1909                                      const char *name,
1910                                      enum vfs_translate_direction direction,
1911                                      TALLOC_CTX *mem_ctx,
1912                                      char **mapped_name)
1913 {
1914         VFS_FIND(translate_name);
1915         return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
1916                                               mapped_name);
1917 }
1918
1919 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
1920                             struct files_struct *fsp,
1921                             TALLOC_CTX *ctx,
1922                             uint32_t function,
1923                             uint16_t req_flags,
1924                             const uint8_t *in_data,
1925                             uint32_t in_len,
1926                             uint8_t **out_data,
1927                             uint32_t max_out_len,
1928                             uint32_t *out_len)
1929 {
1930         VFS_FIND(fsctl);
1931         return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags, 
1932                                      in_data, in_len, out_data, max_out_len, 
1933                                      out_len);
1934 }
1935
1936 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
1937                                   struct files_struct *fsp,
1938                                   uint32 security_info,
1939                                   struct security_descriptor **ppdesc)
1940 {
1941         VFS_FIND(fget_nt_acl);
1942         return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
1943                                            ppdesc);
1944 }
1945
1946 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
1947                                  const char *name,
1948                                  uint32 security_info,
1949                                  struct security_descriptor **ppdesc)
1950 {
1951         VFS_FIND(get_nt_acl);
1952         return handle->fns->get_nt_acl_fn(handle, name, security_info, ppdesc);
1953 }
1954
1955 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
1956                                   struct files_struct *fsp,
1957                                   uint32 security_info_sent,
1958                                   const struct security_descriptor *psd)
1959 {
1960         VFS_FIND(fset_nt_acl);
1961         return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent, 
1962                                            psd);
1963 }
1964
1965 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
1966                            mode_t mode)
1967 {
1968         VFS_FIND(chmod_acl);
1969         return handle->fns->chmod_acl_fn(handle, name, mode);
1970 }
1971
1972 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
1973                             struct files_struct *fsp, mode_t mode)
1974 {
1975         VFS_FIND(fchmod_acl);
1976         return handle->fns->fchmod_acl_fn(handle, fsp, mode);
1977 }
1978
1979 int smb_vfs_call_sys_acl_get_entry(struct vfs_handle_struct *handle,
1980                                    SMB_ACL_T theacl, int entry_id,
1981                                    SMB_ACL_ENTRY_T *entry_p)
1982 {
1983         VFS_FIND(sys_acl_get_entry);
1984         return handle->fns->sys_acl_get_entry_fn(handle, theacl, entry_id,
1985                                                  entry_p);
1986 }
1987
1988 int smb_vfs_call_sys_acl_get_tag_type(struct vfs_handle_struct *handle,
1989                                       SMB_ACL_ENTRY_T entry_d,
1990                                       SMB_ACL_TAG_T *tag_type_p)
1991 {
1992         VFS_FIND(sys_acl_get_tag_type);
1993         return handle->fns->sys_acl_get_tag_type_fn(handle, entry_d, 
1994                                                     tag_type_p);
1995 }
1996
1997 int smb_vfs_call_sys_acl_get_permset(struct vfs_handle_struct *handle,
1998                                      SMB_ACL_ENTRY_T entry_d,
1999                                      SMB_ACL_PERMSET_T *permset_p)
2000 {
2001         VFS_FIND(sys_acl_get_permset);
2002         return handle->fns->sys_acl_get_permset_fn(handle, entry_d, permset_p);
2003 }
2004
2005 void * smb_vfs_call_sys_acl_get_qualifier(struct vfs_handle_struct *handle,
2006                                           SMB_ACL_ENTRY_T entry_d)
2007 {
2008         VFS_FIND(sys_acl_get_qualifier);
2009         return handle->fns->sys_acl_get_qualifier_fn(handle, entry_d);
2010 }
2011
2012 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2013                                         const char *path_p,
2014                                         SMB_ACL_TYPE_T type)
2015 {
2016         VFS_FIND(sys_acl_get_file);
2017         return handle->fns->sys_acl_get_file_fn(handle, path_p, type);
2018 }
2019
2020 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2021                                       struct files_struct *fsp)
2022 {
2023         VFS_FIND(sys_acl_get_fd);
2024         return handle->fns->sys_acl_get_fd_fn(handle, fsp);
2025 }
2026
2027 int smb_vfs_call_sys_acl_clear_perms(struct vfs_handle_struct *handle,
2028                                      SMB_ACL_PERMSET_T permset)
2029 {
2030         VFS_FIND(sys_acl_clear_perms);
2031         return handle->fns->sys_acl_clear_perms_fn(handle, permset);
2032 }
2033
2034 int smb_vfs_call_sys_acl_add_perm(struct vfs_handle_struct *handle,
2035                                   SMB_ACL_PERMSET_T permset,
2036                                   SMB_ACL_PERM_T perm)
2037 {
2038         VFS_FIND(sys_acl_add_perm);
2039         return handle->fns->sys_acl_add_perm_fn(handle, permset, perm);
2040 }
2041
2042 char * smb_vfs_call_sys_acl_to_text(struct vfs_handle_struct *handle,
2043                                     SMB_ACL_T theacl, ssize_t *plen)
2044 {
2045         VFS_FIND(sys_acl_to_text);
2046         return handle->fns->sys_acl_to_text_fn(handle, theacl, plen);
2047 }
2048
2049 SMB_ACL_T smb_vfs_call_sys_acl_init(struct vfs_handle_struct *handle,
2050                                     int count)
2051 {
2052         VFS_FIND(sys_acl_init);
2053         return handle->fns->sys_acl_init_fn(handle, count);
2054 }
2055
2056 int smb_vfs_call_sys_acl_create_entry(struct vfs_handle_struct *handle,
2057                                       SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2058 {
2059         VFS_FIND(sys_acl_create_entry);
2060         return handle->fns->sys_acl_create_entry_fn(handle, pacl, pentry);
2061 }
2062
2063 int smb_vfs_call_sys_acl_set_tag_type(struct vfs_handle_struct *handle,
2064                                       SMB_ACL_ENTRY_T entry,
2065                                       SMB_ACL_TAG_T tagtype)
2066 {
2067         VFS_FIND(sys_acl_set_tag_type);
2068         return handle->fns->sys_acl_set_tag_type_fn(handle, entry, tagtype);
2069 }
2070
2071 int smb_vfs_call_sys_acl_set_qualifier(struct vfs_handle_struct *handle,
2072                                        SMB_ACL_ENTRY_T entry, void *qual)
2073 {
2074         VFS_FIND(sys_acl_set_qualifier);
2075         return handle->fns->sys_acl_set_qualifier_fn(handle, entry, qual);
2076 }
2077
2078 int smb_vfs_call_sys_acl_set_permset(struct vfs_handle_struct *handle,
2079                                      SMB_ACL_ENTRY_T entry,
2080                                      SMB_ACL_PERMSET_T permset)
2081 {
2082         VFS_FIND(sys_acl_set_permset);
2083         return handle->fns->sys_acl_set_permset_fn(handle, entry, permset);
2084 }
2085
2086 int smb_vfs_call_sys_acl_valid(struct vfs_handle_struct *handle,
2087                                SMB_ACL_T theacl)
2088 {
2089         VFS_FIND(sys_acl_valid);
2090         return handle->fns->sys_acl_valid_fn(handle, theacl);
2091 }
2092
2093 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2094                                   const char *name, SMB_ACL_TYPE_T acltype,
2095                                   SMB_ACL_T theacl)
2096 {
2097         VFS_FIND(sys_acl_set_file);
2098         return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2099 }
2100
2101 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2102                                 struct files_struct *fsp, SMB_ACL_T theacl)
2103 {
2104         VFS_FIND(sys_acl_set_fd);
2105         return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2106 }
2107
2108 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2109                                          const char *path)
2110 {
2111         VFS_FIND(sys_acl_delete_def_file);
2112         return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2113 }
2114
2115 int smb_vfs_call_sys_acl_get_perm(struct vfs_handle_struct *handle,
2116                                   SMB_ACL_PERMSET_T permset,
2117                                   SMB_ACL_PERM_T perm)
2118 {
2119         VFS_FIND(sys_acl_get_perm);
2120         return handle->fns->sys_acl_get_perm_fn(handle, permset, perm);
2121 }
2122
2123 int smb_vfs_call_sys_acl_free_text(struct vfs_handle_struct *handle,
2124                                    char *text)
2125 {
2126         VFS_FIND(sys_acl_free_text);
2127         return handle->fns->sys_acl_free_text_fn(handle, text);
2128 }
2129
2130 int smb_vfs_call_sys_acl_free_acl(struct vfs_handle_struct *handle,
2131                                   SMB_ACL_T posix_acl)
2132 {
2133         VFS_FIND(sys_acl_free_acl);
2134         return handle->fns->sys_acl_free_acl_fn(handle, posix_acl);
2135 }
2136
2137 int smb_vfs_call_sys_acl_free_qualifier(struct vfs_handle_struct *handle,
2138                                         void *qualifier, SMB_ACL_TAG_T tagtype)
2139 {
2140         VFS_FIND(sys_acl_free_qualifier);
2141         return handle->fns->sys_acl_free_qualifier_fn(handle, qualifier, 
2142                                                       tagtype);
2143 }
2144
2145 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2146                               const char *path, const char *name, void *value,
2147                               size_t size)
2148 {
2149         VFS_FIND(getxattr);
2150         return handle->fns->getxattr_fn(handle, path, name, value, size);
2151 }
2152
2153 ssize_t smb_vfs_call_lgetxattr(struct vfs_handle_struct *handle,
2154                                const char *path, const char *name, void *value,
2155                                size_t size)
2156 {
2157         VFS_FIND(lgetxattr);
2158         return handle->fns->lgetxattr_fn(handle, path, name, value, size);
2159 }
2160
2161 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2162                                struct files_struct *fsp, const char *name,
2163                                void *value, size_t size)
2164 {
2165         VFS_FIND(fgetxattr);
2166         return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2167 }
2168
2169 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2170                                const char *path, char *list, size_t size)
2171 {
2172         VFS_FIND(listxattr);
2173         return handle->fns->listxattr_fn(handle, path, list, size);
2174 }
2175
2176 ssize_t smb_vfs_call_llistxattr(struct vfs_handle_struct *handle,
2177                                 const char *path, char *list, size_t size)
2178 {
2179         VFS_FIND(llistxattr);
2180         return handle->fns->llistxattr_fn(handle, path, list, size);
2181 }
2182
2183 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2184                                 struct files_struct *fsp, char *list,
2185                                 size_t size)
2186 {
2187         VFS_FIND(flistxattr);
2188         return handle->fns->flistxattr_fn(handle, fsp, list, size);
2189 }
2190
2191 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2192                              const char *path, const char *name)
2193 {
2194         VFS_FIND(removexattr);
2195         return handle->fns->removexattr_fn(handle, path, name);
2196 }
2197
2198 int smb_vfs_call_lremovexattr(struct vfs_handle_struct *handle,
2199                               const char *path, const char *name)
2200 {
2201         VFS_FIND(lremovexattr);
2202         return handle->fns->lremovexattr_fn(handle, path, name);
2203 }
2204
2205 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2206                               struct files_struct *fsp, const char *name)
2207 {
2208         VFS_FIND(fremovexattr);
2209         return handle->fns->fremovexattr_fn(handle, fsp, name);
2210 }
2211
2212 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2213                           const char *name, const void *value, size_t size,
2214                           int flags)
2215 {
2216         VFS_FIND(setxattr);
2217         return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2218 }
2219
2220 int smb_vfs_call_lsetxattr(struct vfs_handle_struct *handle, const char *path,
2221                            const char *name, const void *value, size_t size,
2222                            int flags)
2223 {
2224         VFS_FIND(lsetxattr);
2225         return handle->fns->lsetxattr_fn(handle, path, name, value, size, 
2226                                          flags);
2227 }
2228
2229 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2230                            struct files_struct *fsp, const char *name,
2231                            const void *value, size_t size, int flags)
2232 {
2233         VFS_FIND(fsetxattr);
2234         return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2235 }
2236
2237 int smb_vfs_call_aio_read(struct vfs_handle_struct *handle,
2238                           struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2239 {
2240         VFS_FIND(aio_read);
2241         return handle->fns->aio_read_fn(handle, fsp, aiocb);
2242 }
2243
2244 int smb_vfs_call_aio_write(struct vfs_handle_struct *handle,
2245                            struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2246 {
2247         VFS_FIND(aio_write);
2248         return handle->fns->aio_write_fn(handle, fsp, aiocb);
2249 }
2250
2251 ssize_t smb_vfs_call_aio_return(struct vfs_handle_struct *handle,
2252                                 struct files_struct *fsp,
2253                                 SMB_STRUCT_AIOCB *aiocb)
2254 {
2255         VFS_FIND(aio_return);
2256         return handle->fns->aio_return_fn(handle, fsp, aiocb);
2257 }
2258
2259 int smb_vfs_call_aio_cancel(struct vfs_handle_struct *handle,
2260                             struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2261 {
2262         VFS_FIND(aio_cancel);
2263         return handle->fns->aio_cancel_fn(handle, fsp, aiocb);
2264 }
2265
2266 int smb_vfs_call_aio_error(struct vfs_handle_struct *handle,
2267                            struct files_struct *fsp,
2268                            SMB_STRUCT_AIOCB *aiocb)
2269 {
2270         VFS_FIND(aio_error);
2271         return handle->fns->aio_error_fn(handle, fsp, aiocb);
2272 }
2273
2274 int smb_vfs_call_aio_fsync(struct vfs_handle_struct *handle,
2275                            struct files_struct *fsp, int op,
2276                            SMB_STRUCT_AIOCB *aiocb)
2277 {
2278         VFS_FIND(aio_fsync);
2279         return handle->fns->aio_fsync_fn(handle, fsp, op, aiocb);
2280 }
2281
2282 int smb_vfs_call_aio_suspend(struct vfs_handle_struct *handle,
2283                              struct files_struct *fsp,
2284                              const SMB_STRUCT_AIOCB * const aiocb[], int n,
2285                              const struct timespec *timeout)
2286 {
2287         VFS_FIND(aio_suspend);
2288         return handle->fns->aio_suspend_fn(handle, fsp, aiocb, n, timeout);
2289 }
2290
2291 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2292                             struct files_struct *fsp)
2293 {
2294         VFS_FIND(aio_force);
2295         return handle->fns->aio_force_fn(handle, fsp);
2296 }
2297
2298 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2299                              const struct smb_filename *fname,
2300                              SMB_STRUCT_STAT *sbuf)
2301 {
2302         VFS_FIND(is_offline);
2303         return handle->fns->is_offline_fn(handle, fname, sbuf);
2304 }
2305
2306 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2307                              const struct smb_filename *fname)
2308 {
2309         VFS_FIND(set_offline);
2310         return handle->fns->set_offline_fn(handle, fname);
2311 }