wbinfo: Fix Coverity ID 242685 Resource leak
[Samba/gebeck_regimport.git] / source3 / smbd / vfs.c
blob2be6c54a8812c52ffad854b9f21eeb3a31de7843
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
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.
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.
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/>.
23 This work was sponsored by Optifacio Software Services, Inc.
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"
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_VFS
37 static_decl_vfs;
39 struct vfs_init_function_entry {
40 char *name;
41 struct vfs_init_function_entry *prev, *next;
42 const struct vfs_fn_pointers *fns;
45 /****************************************************************************
46 maintain the list of available backends
47 ****************************************************************************/
49 static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
51 struct vfs_init_function_entry *entry = backends;
53 DEBUG(10, ("vfs_find_backend_entry called for %s\n", name));
55 while(entry) {
56 if (strcmp(entry->name, name)==0) return entry;
57 entry = entry->next;
60 return NULL;
63 NTSTATUS smb_register_vfs(int version, const char *name,
64 const struct vfs_fn_pointers *fns)
66 struct vfs_init_function_entry *entry = backends;
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;
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;
82 if (vfs_find_backend_entry(name)) {
83 DEBUG(0,("VFS module %s already loaded!\n", name));
84 return NT_STATUS_OBJECT_NAME_COLLISION;
87 entry = SMB_XMALLOC_P(struct vfs_init_function_entry);
88 entry->name = smb_xstrdup(name);
89 entry->fns = fns;
91 DLIST_ADD(backends, entry);
92 DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
93 return NT_STATUS_OK;
96 /****************************************************************************
97 initialise default vfs hooks
98 ****************************************************************************/
100 static void vfs_init_default(connection_struct *conn)
102 DEBUG(3, ("Initialising default vfs hooks\n"));
103 vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME);
106 /****************************************************************************
107 initialise custom vfs hooks
108 ****************************************************************************/
110 bool vfs_init_custom(connection_struct *conn, const char *vfs_object)
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;
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;
124 if(!backends) {
125 static_init_vfs;
128 DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
130 module_path = smb_xstrdup(vfs_object);
132 p = strchr_m(module_path, ':');
134 if (p) {
135 *p = 0;
136 module_param = p+1;
137 trim_char(module_param, ' ', ' ');
140 trim_char(module_path, ' ', ' ');
142 module_name = smb_xstrdup(module_path);
144 if ((module_name[0] == '/') &&
145 (strcmp(module_path, DEFAULT_VFS_MODULE_NAME) != 0)) {
148 * Extract the module name from the path. Just use the base
149 * name of the last path component.
152 SAFE_FREE(module_name);
153 module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
155 p = strchr_m(module_name, '.');
157 if (p != NULL) {
158 *p = '\0';
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;
167 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
168 vfs_object));
170 status = smb_load_module("vfs", module_path);
171 if (!NT_STATUS_IS_OK(status)) {
172 DEBUG(0, ("error probing vfs module '%s': %s\n",
173 module_path, nt_errstr(status)));
174 goto fail;
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;
184 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
186 handle = talloc_zero(conn, vfs_handle_struct);
187 if (!handle) {
188 DEBUG(0,("TALLOC_ZERO() failed!\n"));
189 goto fail;
191 handle->conn = conn;
192 handle->fns = entry->fns;
193 if (module_param) {
194 handle->param = talloc_strdup(conn, module_param);
196 DLIST_ADD(conn->vfs_handles, handle);
198 SAFE_FREE(module_path);
199 SAFE_FREE(module_name);
200 return True;
202 fail:
203 SAFE_FREE(module_path);
204 SAFE_FREE(module_name);
205 return False;
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 ******************************************************************/
214 #define EXT_DATA_AREA(e) ((uint8 *)(e) + sizeof(struct vfs_fsp_data))
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))
220 struct vfs_fsp_data *ext;
221 void * ext_data;
223 /* Prevent VFS modules adding multiple extensions. */
224 if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
225 return ext_data;
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;
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);
241 void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
243 struct vfs_fsp_data *curr;
244 struct vfs_fsp_data *prev;
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;
255 if (curr->destroy) {
256 curr->destroy(EXT_DATA_AREA(curr));
258 TALLOC_FREE(curr);
259 return;
264 void *vfs_memctx_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
266 struct vfs_fsp_data *head;
268 for (head = fsp->vfs_extension; head; head = head->next) {
269 if (head->owner == handle) {
270 return head;
274 return NULL;
277 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
279 struct vfs_fsp_data *head;
281 head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
282 if (head != NULL) {
283 return EXT_DATA_AREA(head);
286 return NULL;
289 #undef EXT_DATA_AREA
291 /*****************************************************************
292 Generic VFS init.
293 ******************************************************************/
295 bool smbd_vfs_init(connection_struct *conn)
297 const char **vfs_objects;
298 unsigned int i = 0;
299 int j = 0;
301 /* Normal share - initialise with disk access functions */
302 vfs_init_default(conn);
303 vfs_objects = lp_vfs_objects(SNUM(conn));
305 /* Override VFS functions if 'vfs object' was not specified*/
306 if (!vfs_objects || !vfs_objects[0])
307 return True;
309 for (i=0; vfs_objects[i] ;) {
310 i++;
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;
319 return True;
322 /*******************************************************************
323 Check if a file exists in the vfs.
324 ********************************************************************/
326 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
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;
334 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
337 /****************************************************************************
338 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
339 ****************************************************************************/
341 ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
343 size_t total=0;
345 while (total < byte_count)
347 ssize_t ret = SMB_VFS_READ(fsp, buf + total,
348 byte_count - total);
350 if (ret == 0) return total;
351 if (ret == -1) {
352 if (errno == EINTR)
353 continue;
354 else
355 return -1;
357 total += ret;
359 return (ssize_t)total;
362 ssize_t vfs_pread_data(files_struct *fsp, char *buf,
363 size_t byte_count, off_t offset)
365 size_t total=0;
367 while (total < byte_count)
369 ssize_t ret = SMB_VFS_PREAD(fsp, buf + total,
370 byte_count - total, offset + total);
372 if (ret == 0) return total;
373 if (ret == -1) {
374 if (errno == EINTR)
375 continue;
376 else
377 return -1;
379 total += ret;
381 return (ssize_t)total;
384 /****************************************************************************
385 Write data to a fd on the vfs.
386 ****************************************************************************/
388 ssize_t vfs_write_data(struct smb_request *req,
389 files_struct *fsp,
390 const char *buffer,
391 size_t N)
393 size_t total=0;
394 ssize_t ret;
396 if (req && req->unread_bytes) {
397 SMB_ASSERT(req->unread_bytes == N);
398 /* VFS_RECVFILE must drain the socket
399 * before returning. */
400 req->unread_bytes = 0;
401 return SMB_VFS_RECVFILE(req->sconn->sock,
402 fsp,
403 (off_t)-1,
407 while (total < N) {
408 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
410 if (ret == -1)
411 return -1;
412 if (ret == 0)
413 return total;
415 total += ret;
417 return (ssize_t)total;
420 ssize_t vfs_pwrite_data(struct smb_request *req,
421 files_struct *fsp,
422 const char *buffer,
423 size_t N,
424 off_t offset)
426 size_t total=0;
427 ssize_t ret;
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,
440 while (total < N) {
441 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
442 offset + total);
444 if (ret == -1)
445 return -1;
446 if (ret == 0)
447 return total;
449 total += ret;
451 return (ssize_t)total;
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 ****************************************************************************/
459 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
461 int ret;
462 connection_struct *conn = fsp->conn;
463 uint64_t space_avail;
464 uint64_t bsize,dfree,dsize;
465 NTSTATUS status;
468 * Actually try and commit the space on disk....
471 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
472 fsp_str_dbg(fsp), (double)len));
474 if (((off_t)len) < 0) {
475 DEBUG(0,("vfs_allocate_file_space: %s negative len "
476 "requested.\n", fsp_str_dbg(fsp)));
477 errno = EINVAL;
478 return -1;
481 status = vfs_stat_fsp(fsp);
482 if (!NT_STATUS_IS_OK(status)) {
483 return -1;
486 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
487 return 0;
489 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
490 /* Shrink - use ftruncate. */
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));
496 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
498 flush_write_cache(fsp, SIZECHANGE_FLUSH);
499 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
500 set_filelen_write_cache(fsp, len);
503 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
505 return ret;
508 if (!lp_strict_allocate(SNUM(fsp->conn)))
509 return 0;
511 /* Grow - we need to test if we have enough space. */
513 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
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);
519 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
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;
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;
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));
540 if (len > space_avail) {
541 errno = ENOSPC;
542 return -1;
545 return 0;
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 ****************************************************************************/
554 int vfs_set_filelen(files_struct *fsp, off_t len)
556 int ret;
558 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
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);
571 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
573 return ret;
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 ****************************************************************************/
584 #define SPARSE_BUF_WRITE_SIZE (32*1024)
586 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
588 ssize_t pwrite_ret;
589 size_t total = 0;
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;
599 while (total < len) {
600 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
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;
609 total += pwrite_ret;
612 return 0;
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 ****************************************************************************/
622 int vfs_fill_sparse(files_struct *fsp, off_t len)
624 int ret;
625 NTSTATUS status;
626 off_t offset;
627 size_t num_to_write;
629 status = vfs_stat_fsp(fsp);
630 if (!NT_STATUS_IS_OK(status)) {
631 return -1;
634 if (len <= fsp->fsp_name->st.st_ex_size) {
635 return 0;
638 #ifdef S_ISFIFO
639 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
640 return 0;
642 #endif
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)));
649 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
651 flush_write_cache(fsp, SIZECHANGE_FLUSH);
653 offset = fsp->fsp_name->st.st_ex_size;
654 num_to_write = len - fsp->fsp_name->st.st_ex_size;
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;
670 if (ret == 0) {
671 goto out;
673 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
674 "error %d. Falling back to slow manual allocation\n", ret));
677 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
678 if (ret != 0) {
679 errno = ret;
680 ret = -1;
683 out:
685 if (ret == 0) {
686 set_filelen_write_cache(fsp, len);
689 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
690 return ret;
693 /****************************************************************************
694 Transfer some data (n bytes) between two file_struct's.
695 ****************************************************************************/
697 static ssize_t vfs_read_fn(void *file, void *buf, size_t len)
699 struct files_struct *fsp = (struct files_struct *)file;
701 return SMB_VFS_READ(fsp, buf, len);
704 static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
706 struct files_struct *fsp = (struct files_struct *)file;
708 return SMB_VFS_WRITE(fsp, buf, len);
711 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
713 return transfer_file_internal((void *)in, (void *)out, n,
714 vfs_read_fn, vfs_write_fn);
717 /*******************************************************************
718 A vfs_readdir wrapper which just returns the file name.
719 ********************************************************************/
721 const char *vfs_readdirname(connection_struct *conn, void *p,
722 SMB_STRUCT_STAT *sbuf, char **talloced)
724 struct dirent *ptr= NULL;
725 const char *dname;
726 char *translated;
727 NTSTATUS status;
729 if (!p)
730 return(NULL);
732 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
733 if (!ptr)
734 return(NULL);
736 dname = ptr->d_name;
739 #ifdef NEXT2
740 if (telldir(p) < 0)
741 return(NULL);
742 #endif
744 #ifdef HAVE_BROKEN_READDIR_NAME
745 /* using /usr/ucb/cc is BAD */
746 dname = dname - 2;
747 #endif
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;
755 *talloced = translated;
756 if (!NT_STATUS_IS_OK(status)) {
757 return NULL;
759 return translated;
762 /*******************************************************************
763 A wrapper for vfs_chdir().
764 ********************************************************************/
766 int vfs_ChDir(connection_struct *conn, const char *path)
768 int res;
770 if (!LastDir) {
771 LastDir = SMB_STRDUP("");
774 if (strcsequal(path,"."))
775 return(0);
777 if (*path == '/' && strcsequal(LastDir,path))
778 return(0);
780 DEBUG(4,("vfs_ChDir to %s\n",path));
782 res = SMB_VFS_CHDIR(conn,path);
783 if (!res) {
784 SAFE_FREE(LastDir);
785 LastDir = SMB_STRDUP(path);
787 return(res);
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 ********************************************************************/
796 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
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;
806 if (!lp_getwd_cache()) {
807 goto nocache;
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;
817 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
819 * Known to fail for root: the directory may be NFS-mounted
820 * and exported with root_squash (so has no root access).
822 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
823 "(NFS problem ?)\n", strerror(errno) ));
824 goto nocache;
827 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
829 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
830 data_blob_const(&key, sizeof(key)),
831 &cache_value)) {
832 goto nocache;
835 SMB_ASSERT((cache_value.length > 0)
836 && (cache_value.data[cache_value.length-1] == '\0'));
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;
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))) {
850 * Ok, we're done
852 result = talloc_strdup(ctx, smb_fname_full->base_name);
853 if (result == NULL) {
854 errno = ENOMEM;
856 goto out;
859 nocache:
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.
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;
874 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
875 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
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));
883 result = talloc_strdup(ctx, current_dir);
884 if (result == NULL) {
885 errno = ENOMEM;
888 out:
889 TALLOC_FREE(smb_fname_dot);
890 TALLOC_FREE(smb_fname_full);
891 SAFE_FREE(current_dir);
892 return result;
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 ********************************************************************/
902 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
903 const char *fname,
904 struct smb_request *smbreq)
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;
918 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
919 fname,
920 conn->connectpath));
923 priv_paths = talloc_zero(smbreq, struct privilege_paths);
924 if (!priv_paths) {
925 status = NT_STATUS_NO_MEMORY;
926 goto err;
929 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
930 status = NT_STATUS_NO_MEMORY;
931 goto err;
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);
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;
943 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
944 status = map_nt_error_from_unix(errno);
945 goto err;
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;
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;
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;
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;
974 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
975 priv_paths->parent_name.base_name,
976 resolved_name));
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;
986 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
987 status = map_nt_error_from_unix(errno);
988 goto err;
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;
1001 /* Ensure we're below the connect path. */
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;
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;
1023 /* Now ensure that the last component either doesn't
1024 exist, or is *NOT* a symlink. */
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;
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;
1049 smbreq->priv_paths = priv_paths;
1050 status = NT_STATUS_OK;
1052 err:
1054 if (saved_dir) {
1055 vfs_ChDir(conn, saved_dir);
1057 SAFE_FREE(resolved_name);
1058 if (!NT_STATUS_IS_OK(status)) {
1059 TALLOC_FREE(priv_paths);
1061 return status;
1064 /*******************************************************************
1065 Reduce a file name, removing .. elements and checking that
1066 it is below dir in the heirachy. This uses realpath.
1067 ********************************************************************/
1069 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1071 char *resolved_name = NULL;
1072 bool allow_symlinks = true;
1073 bool allow_widelinks = false;
1075 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1077 resolved_name = SMB_VFS_REALPATH(conn,fname);
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:
1088 TALLOC_CTX *ctx = talloc_tos();
1089 char *dir_name = NULL;
1090 const char *last_component = NULL;
1091 char *new_name = NULL;
1092 int ret;
1094 /* Last component didn't exist.
1095 Remove it and try and canonicalise
1096 the directory name. */
1097 if (!parent_dirname(ctx, fname,
1098 &dir_name,
1099 &last_component)) {
1100 return NT_STATUS_NO_MEMORY;
1103 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1104 if (!resolved_name) {
1105 NTSTATUS status = map_nt_error_from_unix(errno);
1107 if (errno == ENOENT || errno == ENOTDIR) {
1108 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1111 DEBUG(3,("check_reduce_name: "
1112 "couldn't get realpath for "
1113 "%s (%s)\n",
1114 fname,
1115 nt_errstr(status)));
1116 return status;
1118 ret = asprintf(&new_name, "%s/%s",
1119 resolved_name, last_component);
1120 SAFE_FREE(resolved_name);
1121 if (ret == -1) {
1122 return NT_STATUS_NO_MEMORY;
1124 resolved_name = new_name;
1125 break;
1127 default:
1128 DEBUG(3,("check_reduced_name: couldn't get "
1129 "realpath for %s\n", fname));
1130 return map_nt_error_from_unix(errno);
1134 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1135 resolved_name));
1137 if (*resolved_name != '/') {
1138 DEBUG(0,("check_reduced_name: realpath doesn't return "
1139 "absolute paths !\n"));
1140 SAFE_FREE(resolved_name);
1141 return NT_STATUS_OBJECT_NAME_INVALID;
1144 allow_widelinks = lp_widelinks(SNUM(conn));
1145 allow_symlinks = lp_symlinks(SNUM(conn));
1147 /* Common widelinks and symlinks checks. */
1148 if (!allow_widelinks || !allow_symlinks) {
1149 const char *conn_rootdir;
1150 size_t rootdir_len;
1152 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1153 if (conn_rootdir == NULL) {
1154 DEBUG(2, ("check_reduced_name: Could not get "
1155 "conn_rootdir\n"));
1156 SAFE_FREE(resolved_name);
1157 return NT_STATUS_ACCESS_DENIED;
1160 rootdir_len = strlen(conn_rootdir);
1161 if (strncmp(conn_rootdir, resolved_name,
1162 rootdir_len) != 0) {
1163 DEBUG(2, ("check_reduced_name: Bad access "
1164 "attempt: %s is a symlink outside the "
1165 "share path\n", fname));
1166 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1167 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1168 SAFE_FREE(resolved_name);
1169 return NT_STATUS_ACCESS_DENIED;
1172 /* Extra checks if all symlinks are disallowed. */
1173 if (!allow_symlinks) {
1174 /* fname can't have changed in resolved_path. */
1175 const char *p = &resolved_name[rootdir_len];
1177 /* *p can be '\0' if fname was "." */
1178 if (*p == '\0' && ISDOT(fname)) {
1179 goto out;
1182 if (*p != '/') {
1183 DEBUG(2, ("check_reduced_name: logic error (%c) "
1184 "in resolved_name: %s\n",
1186 fname));
1187 SAFE_FREE(resolved_name);
1188 return NT_STATUS_ACCESS_DENIED;
1191 p++;
1192 if (strcmp(fname, p)!=0) {
1193 DEBUG(2, ("check_reduced_name: Bad access "
1194 "attempt: %s is a symlink\n",
1195 fname));
1196 SAFE_FREE(resolved_name);
1197 return NT_STATUS_ACCESS_DENIED;
1202 out:
1204 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1205 resolved_name));
1206 SAFE_FREE(resolved_name);
1207 return NT_STATUS_OK;
1211 * XXX: This is temporary and there should be no callers of this once
1212 * smb_filename is plumbed through all path based operations.
1214 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1215 SMB_STRUCT_STAT *psbuf)
1217 struct smb_filename *smb_fname = NULL;
1218 NTSTATUS status;
1219 int ret;
1221 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1222 &smb_fname);
1223 if (!NT_STATUS_IS_OK(status)) {
1224 errno = map_errno_from_nt_status(status);
1225 return -1;
1228 if (lp_posix_pathnames()) {
1229 ret = SMB_VFS_LSTAT(conn, smb_fname);
1230 } else {
1231 ret = SMB_VFS_STAT(conn, smb_fname);
1234 if (ret != -1) {
1235 *psbuf = smb_fname->st;
1238 TALLOC_FREE(smb_fname);
1239 return ret;
1243 * XXX: This is temporary and there should be no callers of this once
1244 * smb_filename is plumbed through all path based operations.
1246 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1247 SMB_STRUCT_STAT *psbuf)
1249 struct smb_filename *smb_fname = NULL;
1250 NTSTATUS status;
1251 int ret;
1253 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1254 &smb_fname);
1255 if (!NT_STATUS_IS_OK(status)) {
1256 errno = map_errno_from_nt_status(status);
1257 return -1;
1260 ret = SMB_VFS_LSTAT(conn, smb_fname);
1261 if (ret != -1) {
1262 *psbuf = smb_fname->st;
1265 TALLOC_FREE(smb_fname);
1266 return ret;
1270 * Ensure LSTAT is called for POSIX paths.
1273 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1275 int ret;
1277 if(fsp->fh->fd == -1) {
1278 if (fsp->posix_open) {
1279 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1280 } else {
1281 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1283 if (ret == -1) {
1284 return map_nt_error_from_unix(errno);
1286 } else {
1287 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1288 return map_nt_error_from_unix(errno);
1291 return NT_STATUS_OK;
1295 * Initialize num_streams and streams, then call VFS op streaminfo
1297 NTSTATUS vfs_streaminfo(connection_struct *conn,
1298 struct files_struct *fsp,
1299 const char *fname,
1300 TALLOC_CTX *mem_ctx,
1301 unsigned int *num_streams,
1302 struct stream_struct **streams)
1304 *num_streams = 0;
1305 *streams = NULL;
1306 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1310 generate a file_id from a stat structure
1312 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1314 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1317 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1318 const char *service, const char *user)
1320 VFS_FIND(connect);
1321 return handle->fns->connect_fn(handle, service, user);
1324 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1326 VFS_FIND(disconnect);
1327 handle->fns->disconnect_fn(handle);
1330 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1331 const char *path, bool small_query,
1332 uint64_t *bsize, uint64_t *dfree,
1333 uint64_t *dsize)
1335 VFS_FIND(disk_free);
1336 return handle->fns->disk_free_fn(handle, path, small_query, bsize,
1337 dfree, dsize);
1340 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1341 enum SMB_QUOTA_TYPE qtype, unid_t id,
1342 SMB_DISK_QUOTA *qt)
1344 VFS_FIND(get_quota);
1345 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1348 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1349 enum SMB_QUOTA_TYPE qtype, unid_t id,
1350 SMB_DISK_QUOTA *qt)
1352 VFS_FIND(set_quota);
1353 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1356 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1357 struct files_struct *fsp,
1358 struct shadow_copy_data *shadow_copy_data,
1359 bool labels)
1361 VFS_FIND(get_shadow_copy_data);
1362 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1363 shadow_copy_data,
1364 labels);
1366 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1367 struct vfs_statvfs_struct *statbuf)
1369 VFS_FIND(statvfs);
1370 return handle->fns->statvfs_fn(handle, path, statbuf);
1373 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1374 enum timestamp_set_resolution *p_ts_res)
1376 VFS_FIND(fs_capabilities);
1377 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1380 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1381 struct dfs_GetDFSReferral *r)
1383 VFS_FIND(get_dfs_referrals);
1384 return handle->fns->get_dfs_referrals_fn(handle, r);
1387 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1388 const char *fname, const char *mask,
1389 uint32 attributes)
1391 VFS_FIND(opendir);
1392 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1395 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1396 struct files_struct *fsp,
1397 const char *mask,
1398 uint32 attributes)
1400 VFS_FIND(fdopendir);
1401 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1404 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1405 DIR *dirp,
1406 SMB_STRUCT_STAT *sbuf)
1408 VFS_FIND(readdir);
1409 return handle->fns->readdir_fn(handle, dirp, sbuf);
1412 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1413 DIR *dirp, long offset)
1415 VFS_FIND(seekdir);
1416 handle->fns->seekdir_fn(handle, dirp, offset);
1419 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1420 DIR *dirp)
1422 VFS_FIND(telldir);
1423 return handle->fns->telldir_fn(handle, dirp);
1426 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1427 DIR *dirp)
1429 VFS_FIND(rewind_dir);
1430 handle->fns->rewind_dir_fn(handle, dirp);
1433 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1434 mode_t mode)
1436 VFS_FIND(mkdir);
1437 return handle->fns->mkdir_fn(handle, path, mode);
1440 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1442 VFS_FIND(rmdir);
1443 return handle->fns->rmdir_fn(handle, path);
1446 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1447 DIR *dir)
1449 VFS_FIND(closedir);
1450 return handle->fns->closedir_fn(handle, dir);
1453 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1454 DIR *dirp)
1456 VFS_FIND(init_search_op);
1457 handle->fns->init_search_op_fn(handle, dirp);
1460 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1461 struct smb_filename *smb_fname, struct files_struct *fsp,
1462 int flags, mode_t mode)
1464 VFS_FIND(open);
1465 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1468 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1469 struct smb_request *req,
1470 uint16_t root_dir_fid,
1471 struct smb_filename *smb_fname,
1472 uint32_t access_mask,
1473 uint32_t share_access,
1474 uint32_t create_disposition,
1475 uint32_t create_options,
1476 uint32_t file_attributes,
1477 uint32_t oplock_request,
1478 uint64_t allocation_size,
1479 uint32_t private_flags,
1480 struct security_descriptor *sd,
1481 struct ea_list *ea_list,
1482 files_struct **result,
1483 int *pinfo)
1485 VFS_FIND(create_file);
1486 return handle->fns->create_file_fn(
1487 handle, req, root_dir_fid, smb_fname, access_mask,
1488 share_access, create_disposition, create_options,
1489 file_attributes, oplock_request, allocation_size,
1490 private_flags, sd, ea_list,
1491 result, pinfo);
1494 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1495 struct files_struct *fsp)
1497 VFS_FIND(close);
1498 return handle->fns->close_fn(handle, fsp);
1501 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1502 struct files_struct *fsp, void *data, size_t n)
1504 VFS_FIND(read);
1505 return handle->fns->read_fn(handle, fsp, data, n);
1508 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1509 struct files_struct *fsp, void *data, size_t n,
1510 off_t offset)
1512 VFS_FIND(pread);
1513 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1516 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1517 struct files_struct *fsp, const void *data,
1518 size_t n)
1520 VFS_FIND(write);
1521 return handle->fns->write_fn(handle, fsp, data, n);
1524 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1525 struct files_struct *fsp, const void *data,
1526 size_t n, off_t offset)
1528 VFS_FIND(pwrite);
1529 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1532 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1533 struct files_struct *fsp, off_t offset,
1534 int whence)
1536 VFS_FIND(lseek);
1537 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1540 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1541 files_struct *fromfsp, const DATA_BLOB *header,
1542 off_t offset, size_t count)
1544 VFS_FIND(sendfile);
1545 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1546 count);
1549 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1550 files_struct *tofsp, off_t offset,
1551 size_t count)
1553 VFS_FIND(recvfile);
1554 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1557 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1558 const struct smb_filename *smb_fname_src,
1559 const struct smb_filename *smb_fname_dst)
1561 VFS_FIND(rename);
1562 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1565 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1566 struct files_struct *fsp)
1568 VFS_FIND(fsync);
1569 return handle->fns->fsync_fn(handle, fsp);
1572 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1573 struct smb_filename *smb_fname)
1575 VFS_FIND(stat);
1576 return handle->fns->stat_fn(handle, smb_fname);
1579 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1580 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1582 VFS_FIND(fstat);
1583 return handle->fns->fstat_fn(handle, fsp, sbuf);
1586 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1587 struct smb_filename *smb_filename)
1589 VFS_FIND(lstat);
1590 return handle->fns->lstat_fn(handle, smb_filename);
1593 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1594 struct files_struct *fsp,
1595 const SMB_STRUCT_STAT *sbuf)
1597 VFS_FIND(get_alloc_size);
1598 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1601 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1602 const struct smb_filename *smb_fname)
1604 VFS_FIND(unlink);
1605 return handle->fns->unlink_fn(handle, smb_fname);
1608 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1609 mode_t mode)
1611 VFS_FIND(chmod);
1612 return handle->fns->chmod_fn(handle, path, mode);
1615 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1616 struct files_struct *fsp, mode_t mode)
1618 VFS_FIND(fchmod);
1619 return handle->fns->fchmod_fn(handle, fsp, mode);
1622 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1623 uid_t uid, gid_t gid)
1625 VFS_FIND(chown);
1626 return handle->fns->chown_fn(handle, path, uid, gid);
1629 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1630 struct files_struct *fsp, uid_t uid, gid_t gid)
1632 VFS_FIND(fchown);
1633 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1636 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1637 uid_t uid, gid_t gid)
1639 VFS_FIND(lchown);
1640 return handle->fns->lchown_fn(handle, path, uid, gid);
1643 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1645 int ret;
1646 bool as_root = false;
1647 const char *path;
1648 char *saved_dir = NULL;
1649 char *parent_dir = NULL;
1650 NTSTATUS status;
1652 if (fsp->fh->fd != -1) {
1653 /* Try fchown. */
1654 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1655 if (ret == 0) {
1656 return NT_STATUS_OK;
1658 if (ret == -1 && errno != ENOSYS) {
1659 return map_nt_error_from_unix(errno);
1663 as_root = (geteuid() == 0);
1665 if (as_root) {
1667 * We are being asked to chown as root. Make
1668 * sure we chdir() into the path to pin it,
1669 * and always act using lchown to ensure we
1670 * don't deref any symbolic links.
1672 const char *final_component = NULL;
1673 struct smb_filename local_fname;
1675 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1676 if (!saved_dir) {
1677 status = map_nt_error_from_unix(errno);
1678 DEBUG(0,("vfs_chown_fsp: failed to get "
1679 "current working directory. Error was %s\n",
1680 strerror(errno)));
1681 return status;
1684 if (!parent_dirname(talloc_tos(),
1685 fsp->fsp_name->base_name,
1686 &parent_dir,
1687 &final_component)) {
1688 return NT_STATUS_NO_MEMORY;
1691 /* cd into the parent dir to pin it. */
1692 ret = vfs_ChDir(fsp->conn, parent_dir);
1693 if (ret == -1) {
1694 return map_nt_error_from_unix(errno);
1697 ZERO_STRUCT(local_fname);
1698 local_fname.base_name = discard_const_p(char, final_component);
1700 /* Must use lstat here. */
1701 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1702 if (ret == -1) {
1703 status = map_nt_error_from_unix(errno);
1704 goto out;
1707 /* Ensure it matches the fsp stat. */
1708 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1709 status = NT_STATUS_ACCESS_DENIED;
1710 goto out;
1712 path = final_component;
1713 } else {
1714 path = fsp->fsp_name->base_name;
1717 if (fsp->posix_open || as_root) {
1718 ret = SMB_VFS_LCHOWN(fsp->conn,
1719 path,
1720 uid, gid);
1721 } else {
1722 ret = SMB_VFS_CHOWN(fsp->conn,
1723 path,
1724 uid, gid);
1727 if (ret == 0) {
1728 status = NT_STATUS_OK;
1729 } else {
1730 status = map_nt_error_from_unix(errno);
1733 out:
1735 if (as_root) {
1736 vfs_ChDir(fsp->conn,saved_dir);
1737 TALLOC_FREE(saved_dir);
1738 TALLOC_FREE(parent_dir);
1740 return status;
1743 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1745 VFS_FIND(chdir);
1746 return handle->fns->chdir_fn(handle, path);
1749 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
1751 VFS_FIND(getwd);
1752 return handle->fns->getwd_fn(handle);
1755 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
1756 const struct smb_filename *smb_fname,
1757 struct smb_file_time *ft)
1759 VFS_FIND(ntimes);
1760 return handle->fns->ntimes_fn(handle, smb_fname, ft);
1763 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
1764 struct files_struct *fsp, off_t offset)
1766 VFS_FIND(ftruncate);
1767 return handle->fns->ftruncate_fn(handle, fsp, offset);
1770 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
1771 struct files_struct *fsp,
1772 enum vfs_fallocate_mode mode,
1773 off_t offset,
1774 off_t len)
1776 VFS_FIND(fallocate);
1777 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
1780 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
1781 struct files_struct *fsp, uint32 share_mode,
1782 uint32_t access_mask)
1784 VFS_FIND(kernel_flock);
1785 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
1786 access_mask);
1789 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
1790 struct files_struct *fsp, int leasetype)
1792 VFS_FIND(linux_setlease);
1793 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
1796 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
1797 const char *newpath)
1799 VFS_FIND(symlink);
1800 return handle->fns->symlink_fn(handle, oldpath, newpath);
1803 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
1804 const char *path, char *buf, size_t bufsiz)
1806 VFS_FIND(readlink);
1807 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
1810 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
1811 const char *newpath)
1813 VFS_FIND(link);
1814 return handle->fns->link_fn(handle, oldpath, newpath);
1817 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
1818 mode_t mode, SMB_DEV_T dev)
1820 VFS_FIND(mknod);
1821 return handle->fns->mknod_fn(handle, path, mode, dev);
1824 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
1826 VFS_FIND(realpath);
1827 return handle->fns->realpath_fn(handle, path);
1830 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
1831 struct sys_notify_context *ctx,
1832 const char *path,
1833 uint32_t *filter,
1834 uint32_t *subdir_filter,
1835 void (*callback)(struct sys_notify_context *ctx,
1836 void *private_data,
1837 struct notify_event *ev),
1838 void *private_data, void *handle_p)
1840 VFS_FIND(notify_watch);
1841 return handle->fns->notify_watch_fn(handle, ctx, path,
1842 filter, subdir_filter, callback,
1843 private_data, handle_p);
1846 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
1847 unsigned int flags)
1849 VFS_FIND(chflags);
1850 return handle->fns->chflags_fn(handle, path, flags);
1853 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
1854 const SMB_STRUCT_STAT *sbuf)
1856 VFS_FIND(file_id_create);
1857 return handle->fns->file_id_create_fn(handle, sbuf);
1860 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
1861 struct files_struct *fsp,
1862 const char *fname,
1863 TALLOC_CTX *mem_ctx,
1864 unsigned int *num_streams,
1865 struct stream_struct **streams)
1867 VFS_FIND(streaminfo);
1868 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
1869 num_streams, streams);
1872 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
1873 const char *path, const char *name,
1874 TALLOC_CTX *mem_ctx, char **found_name)
1876 VFS_FIND(get_real_filename);
1877 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
1878 found_name);
1881 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
1882 const char *filename)
1884 VFS_FIND(connectpath);
1885 return handle->fns->connectpath_fn(handle, filename);
1888 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
1889 struct files_struct *fsp,
1890 struct lock_struct *plock)
1892 VFS_FIND(strict_lock);
1893 return handle->fns->strict_lock_fn(handle, fsp, plock);
1896 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
1897 struct files_struct *fsp,
1898 struct lock_struct *plock)
1900 VFS_FIND(strict_unlock);
1901 handle->fns->strict_unlock_fn(handle, fsp, plock);
1904 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
1905 const char *name,
1906 enum vfs_translate_direction direction,
1907 TALLOC_CTX *mem_ctx,
1908 char **mapped_name)
1910 VFS_FIND(translate_name);
1911 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
1912 mapped_name);
1915 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
1916 struct files_struct *fsp,
1917 TALLOC_CTX *ctx,
1918 uint32_t function,
1919 uint16_t req_flags,
1920 const uint8_t *in_data,
1921 uint32_t in_len,
1922 uint8_t **out_data,
1923 uint32_t max_out_len,
1924 uint32_t *out_len)
1926 VFS_FIND(fsctl);
1927 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
1928 in_data, in_len, out_data, max_out_len,
1929 out_len);
1932 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
1933 struct files_struct *fsp,
1934 uint32 security_info,
1935 struct security_descriptor **ppdesc)
1937 VFS_FIND(fget_nt_acl);
1938 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
1939 ppdesc);
1942 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
1943 const char *name,
1944 uint32 security_info,
1945 struct security_descriptor **ppdesc)
1947 VFS_FIND(get_nt_acl);
1948 return handle->fns->get_nt_acl_fn(handle, name, security_info, ppdesc);
1951 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
1952 struct files_struct *fsp,
1953 uint32 security_info_sent,
1954 const struct security_descriptor *psd)
1956 VFS_FIND(fset_nt_acl);
1957 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
1958 psd);
1961 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
1962 struct smb_filename *file,
1963 struct security_acl *sacl,
1964 uint32_t access_requested,
1965 uint32_t access_denied)
1967 VFS_FIND(audit_file);
1968 return handle->fns->audit_file_fn(handle,
1969 file,
1970 sacl,
1971 access_requested,
1972 access_denied);
1975 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
1976 mode_t mode)
1978 VFS_FIND(chmod_acl);
1979 return handle->fns->chmod_acl_fn(handle, name, mode);
1982 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
1983 struct files_struct *fsp, mode_t mode)
1985 VFS_FIND(fchmod_acl);
1986 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
1989 int smb_vfs_call_sys_acl_get_entry(struct vfs_handle_struct *handle,
1990 SMB_ACL_T theacl, int entry_id,
1991 SMB_ACL_ENTRY_T *entry_p)
1993 VFS_FIND(sys_acl_get_entry);
1994 return handle->fns->sys_acl_get_entry_fn(handle, theacl, entry_id,
1995 entry_p);
1998 int smb_vfs_call_sys_acl_get_tag_type(struct vfs_handle_struct *handle,
1999 SMB_ACL_ENTRY_T entry_d,
2000 SMB_ACL_TAG_T *tag_type_p)
2002 VFS_FIND(sys_acl_get_tag_type);
2003 return handle->fns->sys_acl_get_tag_type_fn(handle, entry_d,
2004 tag_type_p);
2007 int smb_vfs_call_sys_acl_get_permset(struct vfs_handle_struct *handle,
2008 SMB_ACL_ENTRY_T entry_d,
2009 SMB_ACL_PERMSET_T *permset_p)
2011 VFS_FIND(sys_acl_get_permset);
2012 return handle->fns->sys_acl_get_permset_fn(handle, entry_d, permset_p);
2015 void * smb_vfs_call_sys_acl_get_qualifier(struct vfs_handle_struct *handle,
2016 SMB_ACL_ENTRY_T entry_d)
2018 VFS_FIND(sys_acl_get_qualifier);
2019 return handle->fns->sys_acl_get_qualifier_fn(handle, entry_d);
2022 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2023 const char *path_p,
2024 SMB_ACL_TYPE_T type)
2026 VFS_FIND(sys_acl_get_file);
2027 return handle->fns->sys_acl_get_file_fn(handle, path_p, type);
2030 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2031 struct files_struct *fsp)
2033 VFS_FIND(sys_acl_get_fd);
2034 return handle->fns->sys_acl_get_fd_fn(handle, fsp);
2037 int smb_vfs_call_sys_acl_clear_perms(struct vfs_handle_struct *handle,
2038 SMB_ACL_PERMSET_T permset)
2040 VFS_FIND(sys_acl_clear_perms);
2041 return handle->fns->sys_acl_clear_perms_fn(handle, permset);
2044 int smb_vfs_call_sys_acl_add_perm(struct vfs_handle_struct *handle,
2045 SMB_ACL_PERMSET_T permset,
2046 SMB_ACL_PERM_T perm)
2048 VFS_FIND(sys_acl_add_perm);
2049 return handle->fns->sys_acl_add_perm_fn(handle, permset, perm);
2052 char * smb_vfs_call_sys_acl_to_text(struct vfs_handle_struct *handle,
2053 SMB_ACL_T theacl, ssize_t *plen)
2055 VFS_FIND(sys_acl_to_text);
2056 return handle->fns->sys_acl_to_text_fn(handle, theacl, plen);
2059 SMB_ACL_T smb_vfs_call_sys_acl_init(struct vfs_handle_struct *handle,
2060 int count)
2062 VFS_FIND(sys_acl_init);
2063 return handle->fns->sys_acl_init_fn(handle, count);
2066 int smb_vfs_call_sys_acl_create_entry(struct vfs_handle_struct *handle,
2067 SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2069 VFS_FIND(sys_acl_create_entry);
2070 return handle->fns->sys_acl_create_entry_fn(handle, pacl, pentry);
2073 int smb_vfs_call_sys_acl_set_tag_type(struct vfs_handle_struct *handle,
2074 SMB_ACL_ENTRY_T entry,
2075 SMB_ACL_TAG_T tagtype)
2077 VFS_FIND(sys_acl_set_tag_type);
2078 return handle->fns->sys_acl_set_tag_type_fn(handle, entry, tagtype);
2081 int smb_vfs_call_sys_acl_set_qualifier(struct vfs_handle_struct *handle,
2082 SMB_ACL_ENTRY_T entry, void *qual)
2084 VFS_FIND(sys_acl_set_qualifier);
2085 return handle->fns->sys_acl_set_qualifier_fn(handle, entry, qual);
2088 int smb_vfs_call_sys_acl_set_permset(struct vfs_handle_struct *handle,
2089 SMB_ACL_ENTRY_T entry,
2090 SMB_ACL_PERMSET_T permset)
2092 VFS_FIND(sys_acl_set_permset);
2093 return handle->fns->sys_acl_set_permset_fn(handle, entry, permset);
2096 int smb_vfs_call_sys_acl_valid(struct vfs_handle_struct *handle,
2097 SMB_ACL_T theacl)
2099 VFS_FIND(sys_acl_valid);
2100 return handle->fns->sys_acl_valid_fn(handle, theacl);
2103 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2104 const char *name, SMB_ACL_TYPE_T acltype,
2105 SMB_ACL_T theacl)
2107 VFS_FIND(sys_acl_set_file);
2108 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2111 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2112 struct files_struct *fsp, SMB_ACL_T theacl)
2114 VFS_FIND(sys_acl_set_fd);
2115 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2118 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2119 const char *path)
2121 VFS_FIND(sys_acl_delete_def_file);
2122 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2125 int smb_vfs_call_sys_acl_get_perm(struct vfs_handle_struct *handle,
2126 SMB_ACL_PERMSET_T permset,
2127 SMB_ACL_PERM_T perm)
2129 VFS_FIND(sys_acl_get_perm);
2130 return handle->fns->sys_acl_get_perm_fn(handle, permset, perm);
2133 int smb_vfs_call_sys_acl_free_text(struct vfs_handle_struct *handle,
2134 char *text)
2136 VFS_FIND(sys_acl_free_text);
2137 return handle->fns->sys_acl_free_text_fn(handle, text);
2140 int smb_vfs_call_sys_acl_free_acl(struct vfs_handle_struct *handle,
2141 SMB_ACL_T posix_acl)
2143 VFS_FIND(sys_acl_free_acl);
2144 return handle->fns->sys_acl_free_acl_fn(handle, posix_acl);
2147 int smb_vfs_call_sys_acl_free_qualifier(struct vfs_handle_struct *handle,
2148 void *qualifier, SMB_ACL_TAG_T tagtype)
2150 VFS_FIND(sys_acl_free_qualifier);
2151 return handle->fns->sys_acl_free_qualifier_fn(handle, qualifier,
2152 tagtype);
2155 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2156 const char *path, const char *name, void *value,
2157 size_t size)
2159 VFS_FIND(getxattr);
2160 return handle->fns->getxattr_fn(handle, path, name, value, size);
2163 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2164 struct files_struct *fsp, const char *name,
2165 void *value, size_t size)
2167 VFS_FIND(fgetxattr);
2168 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2171 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2172 const char *path, char *list, size_t size)
2174 VFS_FIND(listxattr);
2175 return handle->fns->listxattr_fn(handle, path, list, size);
2178 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2179 struct files_struct *fsp, char *list,
2180 size_t size)
2182 VFS_FIND(flistxattr);
2183 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2186 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2187 const char *path, const char *name)
2189 VFS_FIND(removexattr);
2190 return handle->fns->removexattr_fn(handle, path, name);
2193 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2194 struct files_struct *fsp, const char *name)
2196 VFS_FIND(fremovexattr);
2197 return handle->fns->fremovexattr_fn(handle, fsp, name);
2200 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2201 const char *name, const void *value, size_t size,
2202 int flags)
2204 VFS_FIND(setxattr);
2205 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2208 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2209 struct files_struct *fsp, const char *name,
2210 const void *value, size_t size, int flags)
2212 VFS_FIND(fsetxattr);
2213 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2216 int smb_vfs_call_aio_read(struct vfs_handle_struct *handle,
2217 struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2219 VFS_FIND(aio_read);
2220 return handle->fns->aio_read_fn(handle, fsp, aiocb);
2223 int smb_vfs_call_aio_write(struct vfs_handle_struct *handle,
2224 struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2226 VFS_FIND(aio_write);
2227 return handle->fns->aio_write_fn(handle, fsp, aiocb);
2230 ssize_t smb_vfs_call_aio_return(struct vfs_handle_struct *handle,
2231 struct files_struct *fsp,
2232 SMB_STRUCT_AIOCB *aiocb)
2234 VFS_FIND(aio_return);
2235 return handle->fns->aio_return_fn(handle, fsp, aiocb);
2238 int smb_vfs_call_aio_cancel(struct vfs_handle_struct *handle,
2239 struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2241 VFS_FIND(aio_cancel);
2242 return handle->fns->aio_cancel_fn(handle, fsp, aiocb);
2245 int smb_vfs_call_aio_error(struct vfs_handle_struct *handle,
2246 struct files_struct *fsp,
2247 SMB_STRUCT_AIOCB *aiocb)
2249 VFS_FIND(aio_error);
2250 return handle->fns->aio_error_fn(handle, fsp, aiocb);
2253 int smb_vfs_call_aio_fsync(struct vfs_handle_struct *handle,
2254 struct files_struct *fsp, int op,
2255 SMB_STRUCT_AIOCB *aiocb)
2257 VFS_FIND(aio_fsync);
2258 return handle->fns->aio_fsync_fn(handle, fsp, op, aiocb);
2261 int smb_vfs_call_aio_suspend(struct vfs_handle_struct *handle,
2262 struct files_struct *fsp,
2263 const SMB_STRUCT_AIOCB * const aiocb[], int n,
2264 const struct timespec *timeout)
2266 VFS_FIND(aio_suspend);
2267 return handle->fns->aio_suspend_fn(handle, fsp, aiocb, n, timeout);
2270 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2271 struct files_struct *fsp)
2273 VFS_FIND(aio_force);
2274 return handle->fns->aio_force_fn(handle, fsp);
2277 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2278 const struct smb_filename *fname,
2279 SMB_STRUCT_STAT *sbuf)
2281 VFS_FIND(is_offline);
2282 return handle->fns->is_offline_fn(handle, fname, sbuf);
2285 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2286 const struct smb_filename *fname)
2288 VFS_FIND(set_offline);
2289 return handle->fns->set_offline_fn(handle, fname);