2 Unix SMB/Netbios implementation.
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.
27 #include "system/filesys.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "../lib/util/memcache.h"
31 #include "transfer_file.h"
33 #include "lib/util/tevent_unix.h"
36 #define DBGC_CLASS DBGC_VFS
41 struct vfs_fsp_data *next;
42 struct vfs_handle_struct *owner;
43 void (*destroy)(void *p_data);
45 /* NOTE: This structure contains four pointers so that we can guarantee
46 * that the end of the structure is always both 4-byte and 8-byte aligned.
50 struct vfs_init_function_entry {
52 struct vfs_init_function_entry *prev, *next;
53 const struct vfs_fn_pointers *fns;
56 /****************************************************************************
57 maintain the list of available backends
58 ****************************************************************************/
60 static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
62 struct vfs_init_function_entry *entry = backends;
64 DEBUG(10, ("vfs_find_backend_entry called for %s\n", name));
67 if (strcmp(entry->name, name)==0) return entry;
74 NTSTATUS smb_register_vfs(int version, const char *name,
75 const struct vfs_fn_pointers *fns)
77 struct vfs_init_function_entry *entry = backends;
79 if ((version != SMB_VFS_INTERFACE_VERSION)) {
80 DEBUG(0, ("Failed to register vfs module.\n"
81 "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
82 "current SMB_VFS_INTERFACE_VERSION is %d.\n"
83 "Please recompile against the current Samba Version!\n",
84 version, SMB_VFS_INTERFACE_VERSION));
85 return NT_STATUS_OBJECT_TYPE_MISMATCH;
88 if (!name || !name[0]) {
89 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
90 return NT_STATUS_INVALID_PARAMETER;
93 if (vfs_find_backend_entry(name)) {
94 DEBUG(0,("VFS module %s already loaded!\n", name));
95 return NT_STATUS_OBJECT_NAME_COLLISION;
98 entry = SMB_XMALLOC_P(struct vfs_init_function_entry);
99 entry->name = smb_xstrdup(name);
102 DLIST_ADD(backends, entry);
103 DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
107 /****************************************************************************
108 initialise default vfs hooks
109 ****************************************************************************/
111 static void vfs_init_default(connection_struct *conn)
113 DEBUG(3, ("Initialising default vfs hooks\n"));
114 vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME);
117 /****************************************************************************
118 initialise custom vfs hooks
119 ****************************************************************************/
121 bool vfs_init_custom(connection_struct *conn, const char *vfs_object)
123 char *module_path = NULL;
124 char *module_name = NULL;
125 char *module_param = NULL, *p;
126 vfs_handle_struct *handle;
127 const struct vfs_init_function_entry *entry;
129 if (!conn||!vfs_object||!vfs_object[0]) {
130 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
131 "empty vfs_object!\n"));
136 static_init_vfs(NULL);
139 DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
141 module_path = smb_xstrdup(vfs_object);
143 p = strchr_m(module_path, ':');
148 trim_char(module_param, ' ', ' ');
151 trim_char(module_path, ' ', ' ');
153 module_name = smb_xstrdup(module_path);
155 if ((module_name[0] == '/') &&
156 (strcmp(module_path, DEFAULT_VFS_MODULE_NAME) != 0)) {
159 * Extract the module name from the path. Just use the base
160 * name of the last path component.
163 SAFE_FREE(module_name);
164 module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
166 p = strchr_m(module_name, '.');
173 /* First, try to load the module with the new module system */
174 entry = vfs_find_backend_entry(module_name);
178 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
181 status = smb_load_module("vfs", module_path);
182 if (!NT_STATUS_IS_OK(status)) {
183 DEBUG(0, ("error probing vfs module '%s': %s\n",
184 module_path, nt_errstr(status)));
188 entry = vfs_find_backend_entry(module_name);
190 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
195 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
197 handle = talloc_zero(conn, vfs_handle_struct);
199 DEBUG(0,("TALLOC_ZERO() failed!\n"));
203 handle->fns = entry->fns;
205 handle->param = talloc_strdup(conn, module_param);
207 DLIST_ADD(conn->vfs_handles, handle);
209 SAFE_FREE(module_path);
210 SAFE_FREE(module_name);
214 SAFE_FREE(module_path);
215 SAFE_FREE(module_name);
219 /*****************************************************************
220 Allow VFS modules to extend files_struct with VFS-specific state.
221 This will be ok for small numbers of extensions, but might need to
222 be refactored if it becomes more widely used.
223 ******************************************************************/
225 #define EXT_DATA_AREA(e) ((uint8_t *)(e) + sizeof(struct vfs_fsp_data))
227 void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle,
228 files_struct *fsp, size_t ext_size,
229 void (*destroy_fn)(void *p_data))
231 struct vfs_fsp_data *ext;
234 /* Prevent VFS modules adding multiple extensions. */
235 if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
239 ext = (struct vfs_fsp_data *)TALLOC_ZERO(
240 handle->conn, sizeof(struct vfs_fsp_data) + ext_size);
246 ext->next = fsp->vfs_extension;
247 ext->destroy = destroy_fn;
248 fsp->vfs_extension = ext;
249 return EXT_DATA_AREA(ext);
252 void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
254 struct vfs_fsp_data *curr;
255 struct vfs_fsp_data *prev;
257 for (curr = fsp->vfs_extension, prev = NULL;
259 prev = curr, curr = curr->next) {
260 if (curr->owner == handle) {
262 prev->next = curr->next;
264 fsp->vfs_extension = curr->next;
267 curr->destroy(EXT_DATA_AREA(curr));
275 void vfs_remove_all_fsp_extensions(files_struct *fsp)
277 struct vfs_fsp_data *curr;
278 struct vfs_fsp_data *next;
280 for (curr = fsp->vfs_extension; curr; curr = next) {
283 fsp->vfs_extension = next;
286 curr->destroy(EXT_DATA_AREA(curr));
292 void *vfs_memctx_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
294 struct vfs_fsp_data *head;
296 for (head = fsp->vfs_extension; head; head = head->next) {
297 if (head->owner == handle) {
305 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
307 struct vfs_fsp_data *head;
309 head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
311 return EXT_DATA_AREA(head);
320 * Ensure this module catches all VFS functions.
323 void smb_vfs_assert_all_fns(const struct vfs_fn_pointers* fns,
326 bool missing_fn = false;
328 const uintptr_t *end = (const uintptr_t *)(fns + 1);
330 for (idx = 0; ((const uintptr_t *)fns + idx) < end; idx++) {
331 if (*((const uintptr_t *)fns + idx) == 0) {
332 DBG_ERR("VFS function at index %d not implemented "
333 "in module %s\n", idx, module);
339 smb_panic("Required VFS function not implemented in module.\n");
343 void smb_vfs_assert_all_fns(const struct vfs_fn_pointers* fns,
349 /*****************************************************************
351 ******************************************************************/
353 bool smbd_vfs_init(connection_struct *conn)
355 const char **vfs_objects;
359 /* Normal share - initialise with disk access functions */
360 vfs_init_default(conn);
362 /* No need to load vfs modules for printer connections */
367 vfs_objects = lp_vfs_objects(SNUM(conn));
369 /* Override VFS functions if 'vfs object' was not specified*/
370 if (!vfs_objects || !vfs_objects[0])
373 for (i=0; vfs_objects[i] ;) {
377 for (j=i-1; j >= 0; j--) {
378 if (!vfs_init_custom(conn, vfs_objects[j])) {
379 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
386 /*******************************************************************
387 Check if a file exists in the vfs.
388 ********************************************************************/
390 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
392 /* Only return OK if stat was successful and S_ISREG */
393 if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
394 S_ISREG(smb_fname->st.st_ex_mode)) {
398 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
401 ssize_t vfs_pwrite_data(struct smb_request *req,
410 if (req && req->unread_bytes) {
411 int sockfd = req->xconn->transport.sock;
412 SMB_ASSERT(req->unread_bytes == N);
413 /* VFS_RECVFILE must drain the socket
414 * before returning. */
415 req->unread_bytes = 0;
417 * Leave the socket non-blocking and
418 * use SMB_VFS_RECVFILE. If it returns
419 * EAGAIN || EWOULDBLOCK temporarily set
420 * the socket blocking and retry
424 ret = SMB_VFS_RECVFILE(sockfd,
428 if (ret == 0 || (ret == -1 &&
430 errno == EWOULDBLOCK))) {
432 /* Ensure the socket is blocking. */
433 old_flags = fcntl(sockfd, F_GETFL, 0);
434 if (set_blocking(sockfd, true) == -1) {
437 ret = SMB_VFS_RECVFILE(sockfd,
441 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
448 return (ssize_t)total;
450 /* Any other error case. */
456 return (ssize_t)total;
460 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
470 return (ssize_t)total;
472 /****************************************************************************
473 An allocate file space call using the vfs interface.
474 Allocates space for a file from a filedescriptor.
475 Returns 0 on success, -1 on failure.
476 ****************************************************************************/
478 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
481 connection_struct *conn = fsp->conn;
482 uint64_t space_avail;
483 uint64_t bsize,dfree,dsize;
487 * Actually try and commit the space on disk....
490 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
491 fsp_str_dbg(fsp), (double)len));
493 if (((off_t)len) < 0) {
494 DEBUG(0,("vfs_allocate_file_space: %s negative len "
495 "requested.\n", fsp_str_dbg(fsp)));
500 status = vfs_stat_fsp(fsp);
501 if (!NT_STATUS_IS_OK(status)) {
505 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
508 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
509 /* Shrink - use ftruncate. */
511 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
512 "size %.0f\n", fsp_str_dbg(fsp),
513 (double)fsp->fsp_name->st.st_ex_size));
515 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
517 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
518 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
519 set_filelen_write_cache(fsp, len);
522 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
527 /* Grow - we need to test if we have enough space. */
529 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
531 if (lp_strict_allocate(SNUM(fsp->conn))) {
532 /* See if we have a syscall that will allocate beyond
533 end-of-file without changing EOF. */
534 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_FL_KEEP_SIZE,
540 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
543 /* We changed the allocation size on disk, but not
544 EOF - exactly as required. We're done ! */
548 if (ret == -1 && errno == ENOSPC) {
552 len -= fsp->fsp_name->st.st_ex_size;
553 len /= 1024; /* Len is now number of 1k blocks needed. */
555 get_dfree_info(conn, fsp->fsp_name, &bsize, &dfree, &dsize);
556 if (space_avail == (uint64_t)-1) {
560 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
561 "needed blocks = %.0f, space avail = %.0f\n",
562 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
563 (double)space_avail));
565 if (len > space_avail) {
573 /****************************************************************************
574 A vfs set_filelen call.
575 set the length of a file from a filedescriptor.
576 Returns 0 on success, -1 on failure.
577 ****************************************************************************/
579 int vfs_set_filelen(files_struct *fsp, off_t len)
583 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
585 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
586 fsp_str_dbg(fsp), (double)len));
587 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
588 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
589 set_filelen_write_cache(fsp, len);
590 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
591 FILE_NOTIFY_CHANGE_SIZE
592 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
593 fsp->fsp_name->base_name);
596 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
601 /****************************************************************************
602 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
603 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
604 as this is also called from the default SMB_VFS_FTRUNCATE code.
605 Always extends the file size.
606 Returns 0 on success, -1 on failure.
607 ****************************************************************************/
609 #define SPARSE_BUF_WRITE_SIZE (32*1024)
611 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
617 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
624 while (total < len) {
625 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
627 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
628 if (pwrite_ret == -1) {
629 int saved_errno = errno;
630 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
631 "%s failed with error %s\n",
632 fsp_str_dbg(fsp), strerror(saved_errno)));
642 /****************************************************************************
643 A vfs fill sparse call.
644 Writes zeros from the end of file to len, if len is greater than EOF.
645 Used only by strict_sync.
646 Returns 0 on success, -1 on failure.
647 ****************************************************************************/
649 int vfs_fill_sparse(files_struct *fsp, off_t len)
656 status = vfs_stat_fsp(fsp);
657 if (!NT_STATUS_IS_OK(status)) {
661 if (len <= fsp->fsp_name->st.st_ex_size) {
666 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
671 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
672 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
673 (double)fsp->fsp_name->st.st_ex_size, (double)len,
674 (double)(len - fsp->fsp_name->st.st_ex_size)));
676 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
678 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
680 offset = fsp->fsp_name->st.st_ex_size;
681 num_to_write = len - fsp->fsp_name->st.st_ex_size;
683 /* Only do this on non-stream file handles. */
684 if (fsp->base_fsp == NULL) {
685 /* for allocation try fallocate first. This can fail on some
686 * platforms e.g. when the filesystem doesn't support it and no
687 * emulation is being done by the libc (like on AIX with JFS1). In that
688 * case we do our own emulation. fallocate implementations can
689 * return ENOTSUP or EINVAL in cases like that. */
690 ret = SMB_VFS_FALLOCATE(fsp, 0, offset, num_to_write);
691 if (ret == -1 && errno == ENOSPC) {
697 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
698 "error %d. Falling back to slow manual allocation\n", ret));
701 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
706 set_filelen_write_cache(fsp, len);
709 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
713 /****************************************************************************
714 Transfer some data (n bytes) between two file_struct's.
715 ****************************************************************************/
717 static ssize_t vfs_pread_fn(void *file, void *buf, size_t len, off_t offset)
719 struct files_struct *fsp = (struct files_struct *)file;
721 return SMB_VFS_PREAD(fsp, buf, len, offset);
724 static ssize_t vfs_pwrite_fn(void *file, const void *buf, size_t len, off_t offset)
726 struct files_struct *fsp = (struct files_struct *)file;
728 return SMB_VFS_PWRITE(fsp, buf, len, offset);
731 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
733 return transfer_file_internal((void *)in, (void *)out, n,
734 vfs_pread_fn, vfs_pwrite_fn);
737 /*******************************************************************
738 A vfs_readdir wrapper which just returns the file name.
739 ********************************************************************/
741 const char *vfs_readdirname(connection_struct *conn, void *p,
742 SMB_STRUCT_STAT *sbuf, char **talloced)
744 struct dirent *ptr= NULL;
752 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
764 #ifdef HAVE_BROKEN_READDIR_NAME
765 /* using /usr/ucb/cc is BAD */
769 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
770 talloc_tos(), &translated);
771 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
775 *talloced = translated;
776 if (!NT_STATUS_IS_OK(status)) {
782 /*******************************************************************
783 A wrapper for vfs_chdir().
784 ********************************************************************/
786 int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
790 struct smb_filename *old_cwd = conn->cwd_fname;
793 LastDir = SMB_STRDUP("");
796 if (ISDOT(smb_fname->base_name)) {
800 if (*smb_fname->base_name == '/' &&
801 strcsequal(LastDir,smb_fname->base_name)) {
805 DEBUG(4,("vfs_ChDir to %s\n", smb_fname->base_name));
807 ret = SMB_VFS_CHDIR(conn, smb_fname);
813 * Always replace conn->cwd_fname. We
814 * don't know if it's been modified by
815 * VFS modules in the stack.
819 conn->cwd_fname = vfs_GetWd(conn, conn);
820 if (conn->cwd_fname == NULL) {
822 * vfs_GetWd() failed.
823 * We must be able to read cwd.
824 * Return to original directory
829 if (old_cwd == NULL) {
831 * Failed on the very first chdir()+getwd()
832 * for this connection. We can't
835 smb_panic("conn->cwd getwd failed\n");
839 /* Restore original conn->cwd_fname. */
840 conn->cwd_fname = old_cwd;
842 /* Return to the previous $cwd. */
843 ret = SMB_VFS_CHDIR(conn, conn->cwd_fname);
845 smb_panic("conn->cwd getwd failed\n");
850 /* And fail the chdir(). */
854 /* vfs_GetWd() succeeded. */
855 /* Replace global cache. */
857 LastDir = SMB_STRDUP(smb_fname->base_name);
859 DEBUG(4,("vfs_ChDir got %s\n", conn->cwd_fname->base_name));
861 TALLOC_FREE(old_cwd);
862 if (saved_errno != 0) {
868 /*******************************************************************
869 Return the absolute current directory path - given a UNIX pathname.
870 Note that this path is returned in DOS format, not UNIX
871 format. Note this can be called with conn == NULL.
872 ********************************************************************/
874 struct smb_filename *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
876 struct smb_filename *current_dir_fname = NULL;
878 struct smb_filename *smb_fname_dot = NULL;
879 struct smb_filename *smb_fname_full = NULL;
880 struct smb_filename *result = NULL;
882 if (!lp_getwd_cache()) {
886 smb_fname_dot = synthetic_smb_fname(ctx, ".", NULL, NULL, 0);
887 if (smb_fname_dot == NULL) {
892 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
894 * Known to fail for root: the directory may be NFS-mounted
895 * and exported with root_squash (so has no root access).
897 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
898 "(NFS problem ?)\n", strerror(errno) ));
902 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
904 smb_fname_full = (struct smb_filename *)memcache_lookup_talloc(
907 data_blob_const(&key, sizeof(key)));
909 if (smb_fname_full == NULL) {
913 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
914 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
915 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
916 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
919 * Note: smb_fname_full is owned by smbd_memcache()
920 * so we must make a copy to return.
922 result = cp_smb_filename(ctx, smb_fname_full);
923 if (result == NULL) {
932 * We don't have the information to hand so rely on traditional
933 * methods. The very slow getcwd, which spawns a process on some
934 * systems, or the not quite so bad getwd.
937 current_dir_fname = SMB_VFS_GETWD(conn, ctx);
938 if (current_dir_fname == NULL) {
939 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
944 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
945 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
948 * smbd_memcache() will own current_dir_fname after the
949 * memcache_add_talloc call, so we must make
950 * a copy on ctx to return.
952 result = cp_smb_filename(ctx, current_dir_fname);
953 if (result == NULL) {
958 * Ensure the memory going into the cache
959 * doesn't have a destructor so it can be
962 talloc_set_destructor(current_dir_fname, NULL);
964 memcache_add_talloc(smbd_memcache(),
966 data_blob_const(&key, sizeof(key)),
968 /* current_dir_fname is now == NULL here. */
970 /* current_dir_fname is already allocated on ctx. */
971 result = current_dir_fname;
975 TALLOC_FREE(smb_fname_dot);
977 * Don't free current_dir_fname here. It's either been moved
978 * to the memcache or is being returned in result.
983 /*******************************************************************
984 Reduce a file name, removing .. elements and checking that
985 it is below dir in the heirachy. This uses realpath.
986 This function must run as root, and will return names
987 and valid stat structs that can be checked on open.
988 ********************************************************************/
990 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
991 const struct smb_filename *smb_fname,
992 struct smb_request *smbreq)
995 TALLOC_CTX *ctx = talloc_tos();
996 const char *conn_rootdir;
998 char *dir_name = NULL;
999 char *resolved_name = NULL;
1000 const char *last_component = NULL;
1001 struct smb_filename *resolved_fname = NULL;
1002 struct smb_filename *saved_dir_fname = NULL;
1003 struct smb_filename *smb_fname_cwd = NULL;
1004 struct privilege_paths *priv_paths = NULL;
1007 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
1008 smb_fname->base_name,
1009 conn->connectpath));
1012 priv_paths = talloc_zero(smbreq, struct privilege_paths);
1014 status = NT_STATUS_NO_MEMORY;
1018 if (!parent_dirname(ctx, smb_fname->base_name,
1019 &dir_name, &last_component)) {
1020 status = NT_STATUS_NO_MEMORY;
1024 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
1025 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
1027 if (priv_paths->parent_name.base_name == NULL ||
1028 priv_paths->file_name.base_name == NULL) {
1029 status = NT_STATUS_NO_MEMORY;
1033 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
1034 status = map_nt_error_from_unix(errno);
1037 /* Remember where we were. */
1038 saved_dir_fname = vfs_GetWd(ctx, conn);
1039 if (!saved_dir_fname) {
1040 status = map_nt_error_from_unix(errno);
1044 if (vfs_ChDir(conn, &priv_paths->parent_name) == -1) {
1045 status = map_nt_error_from_unix(errno);
1049 smb_fname_cwd = synthetic_smb_fname(talloc_tos(), ".", NULL, NULL, 0);
1050 if (smb_fname_cwd == NULL) {
1051 status = NT_STATUS_NO_MEMORY;
1055 /* Get the absolute path of the parent directory. */
1056 resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname_cwd);
1057 if (resolved_fname == NULL) {
1058 status = map_nt_error_from_unix(errno);
1061 resolved_name = resolved_fname->base_name;
1063 if (*resolved_name != '/') {
1064 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1065 "doesn't return absolute paths !\n"));
1066 status = NT_STATUS_OBJECT_NAME_INVALID;
1070 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1071 priv_paths->parent_name.base_name,
1074 /* Now check the stat value is the same. */
1075 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1076 status = map_nt_error_from_unix(errno);
1080 /* Ensure we're pointing at the same place. */
1081 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1082 DEBUG(0,("check_reduced_name_with_privilege: "
1083 "device/inode/uid/gid on directory %s changed. "
1084 "Denying access !\n",
1085 priv_paths->parent_name.base_name));
1086 status = NT_STATUS_ACCESS_DENIED;
1090 /* Ensure we're below the connect path. */
1092 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
1093 if (conn_rootdir == NULL) {
1094 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1096 status = NT_STATUS_ACCESS_DENIED;
1100 rootdir_len = strlen(conn_rootdir);
1103 * In the case of rootdir_len == 1, we know that conn_rootdir is
1104 * "/", and we also know that resolved_name starts with a slash.
1105 * So, in this corner case, resolved_name is automatically a
1106 * sub-directory of the conn_rootdir. Thus we can skip the string
1107 * comparison and the next character checks (which are even
1108 * wrong in this case).
1110 if (rootdir_len != 1) {
1113 matched = (strncmp(conn_rootdir, resolved_name,
1116 if (!matched || (resolved_name[rootdir_len] != '/' &&
1117 resolved_name[rootdir_len] != '\0')) {
1118 DEBUG(2, ("check_reduced_name_with_privilege: Bad "
1119 "access attempt: %s is a symlink outside the "
1122 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1123 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1124 status = NT_STATUS_ACCESS_DENIED;
1129 /* Now ensure that the last component either doesn't
1130 exist, or is *NOT* a symlink. */
1132 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1134 /* Errno must be ENOENT for this be ok. */
1135 if (errno != ENOENT) {
1136 status = map_nt_error_from_unix(errno);
1137 DEBUG(2, ("check_reduced_name_with_privilege: "
1138 "LSTAT on %s failed with %s\n",
1139 priv_paths->file_name.base_name,
1140 nt_errstr(status)));
1145 if (VALID_STAT(priv_paths->file_name.st) &&
1146 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1147 DEBUG(2, ("check_reduced_name_with_privilege: "
1148 "Last component %s is a symlink. Denying"
1150 priv_paths->file_name.base_name));
1151 status = NT_STATUS_ACCESS_DENIED;
1155 smbreq->priv_paths = priv_paths;
1156 status = NT_STATUS_OK;
1160 if (saved_dir_fname != NULL) {
1161 vfs_ChDir(conn, saved_dir_fname);
1162 TALLOC_FREE(saved_dir_fname);
1164 TALLOC_FREE(resolved_fname);
1165 if (!NT_STATUS_IS_OK(status)) {
1166 TALLOC_FREE(priv_paths);
1168 TALLOC_FREE(dir_name);
1172 /*******************************************************************
1173 Reduce a file name, removing .. elements and checking that
1174 it is below dir in the heirachy. This uses realpath.
1176 If cwd_name == NULL then fname is a client given path relative
1177 to the root path of the share.
1179 If cwd_name != NULL then fname is a client given path relative
1180 to cwd_name. cwd_name is relative to the root path of the share.
1181 ********************************************************************/
1183 NTSTATUS check_reduced_name(connection_struct *conn,
1184 const struct smb_filename *cwd_fname,
1185 const struct smb_filename *smb_fname)
1187 TALLOC_CTX *ctx = talloc_tos();
1188 const char *cwd_name = cwd_fname ? cwd_fname->base_name : NULL;
1189 const char *fname = smb_fname->base_name;
1190 struct smb_filename *resolved_fname;
1191 char *resolved_name = NULL;
1192 char *new_fname = NULL;
1193 bool allow_symlinks = true;
1194 bool allow_widelinks = false;
1196 DBG_DEBUG("check_reduced_name [%s] [%s]\n", fname, conn->connectpath);
1198 resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname);
1200 if (resolved_fname == NULL) {
1203 DEBUG(3,("check_reduced_name: Component not a "
1204 "directory in getting realpath for "
1206 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1209 char *dir_name = NULL;
1210 struct smb_filename dir_fname = {0};
1211 const char *last_component = NULL;
1213 /* Last component didn't exist.
1214 Remove it and try and canonicalise
1215 the directory name. */
1216 if (!parent_dirname(ctx, fname,
1219 return NT_STATUS_NO_MEMORY;
1222 dir_fname = (struct smb_filename)
1223 { .base_name = dir_name };
1224 resolved_fname = SMB_VFS_REALPATH(conn,
1227 if (resolved_fname == NULL) {
1228 NTSTATUS status = map_nt_error_from_unix(errno);
1230 if (errno == ENOENT || errno == ENOTDIR) {
1231 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1234 DEBUG(3,("check_reduce_name: "
1235 "couldn't get realpath for "
1238 nt_errstr(status)));
1241 resolved_name = talloc_asprintf(ctx,
1243 resolved_fname->base_name,
1245 if (resolved_name == NULL) {
1246 return NT_STATUS_NO_MEMORY;
1251 DEBUG(3,("check_reduced_name: couldn't get "
1252 "realpath for %s\n", fname));
1253 return map_nt_error_from_unix(errno);
1256 resolved_name = resolved_fname->base_name;
1259 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1262 if (*resolved_name != '/') {
1263 DEBUG(0,("check_reduced_name: realpath doesn't return "
1264 "absolute paths !\n"));
1265 TALLOC_FREE(resolved_fname);
1266 return NT_STATUS_OBJECT_NAME_INVALID;
1269 allow_widelinks = lp_widelinks(SNUM(conn));
1270 allow_symlinks = lp_follow_symlinks(SNUM(conn));
1272 /* Common widelinks and symlinks checks. */
1273 if (!allow_widelinks || !allow_symlinks) {
1274 const char *conn_rootdir;
1277 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
1278 if (conn_rootdir == NULL) {
1279 DEBUG(2, ("check_reduced_name: Could not get "
1281 TALLOC_FREE(resolved_fname);
1282 return NT_STATUS_ACCESS_DENIED;
1285 rootdir_len = strlen(conn_rootdir);
1288 * In the case of rootdir_len == 1, we know that
1289 * conn_rootdir is "/", and we also know that
1290 * resolved_name starts with a slash. So, in this
1291 * corner case, resolved_name is automatically a
1292 * sub-directory of the conn_rootdir. Thus we can skip
1293 * the string comparison and the next character checks
1294 * (which are even wrong in this case).
1296 if (rootdir_len != 1) {
1299 matched = (strncmp(conn_rootdir, resolved_name,
1301 if (!matched || (resolved_name[rootdir_len] != '/' &&
1302 resolved_name[rootdir_len] != '\0')) {
1303 DEBUG(2, ("check_reduced_name: Bad access "
1304 "attempt: %s is a symlink outside the "
1305 "share path\n", fname));
1306 DEBUGADD(2, ("conn_rootdir =%s\n",
1308 DEBUGADD(2, ("resolved_name=%s\n",
1310 TALLOC_FREE(resolved_fname);
1311 return NT_STATUS_ACCESS_DENIED;
1315 /* Extra checks if all symlinks are disallowed. */
1316 if (!allow_symlinks) {
1317 /* fname can't have changed in resolved_path. */
1318 const char *p = &resolved_name[rootdir_len];
1321 * UNIX filesystem semantics, names consisting
1322 * only of "." or ".." CANNOT be symlinks.
1324 if (ISDOT(fname) || ISDOTDOT(fname)) {
1329 DEBUG(2, ("check_reduced_name: logic error (%c) "
1330 "in resolved_name: %s\n",
1333 TALLOC_FREE(resolved_fname);
1334 return NT_STATUS_ACCESS_DENIED;
1340 * If cwd_name is present and not ".",
1341 * then fname is relative to that, not
1342 * the root of the share. Make sure the
1343 * path we check is the one the client
1344 * sent (cwd_name+fname).
1346 if (cwd_name != NULL && !ISDOT(cwd_name)) {
1347 new_fname = talloc_asprintf(ctx,
1351 if (new_fname == NULL) {
1352 TALLOC_FREE(resolved_fname);
1353 return NT_STATUS_NO_MEMORY;
1358 if (strcmp(fname, p)!=0) {
1359 DEBUG(2, ("check_reduced_name: Bad access "
1360 "attempt: %s is a symlink to %s\n",
1362 TALLOC_FREE(resolved_fname);
1363 TALLOC_FREE(new_fname);
1364 return NT_STATUS_ACCESS_DENIED;
1371 DBG_INFO("%s reduced to %s\n", fname, resolved_name);
1372 TALLOC_FREE(resolved_fname);
1373 TALLOC_FREE(new_fname);
1374 return NT_STATUS_OK;
1378 * XXX: This is temporary and there should be no callers of this once
1379 * smb_filename is plumbed through all path based operations.
1381 * Called when we know stream name parsing has already been done.
1383 int vfs_stat_smb_basename(struct connection_struct *conn,
1384 const struct smb_filename *smb_fname_in,
1385 SMB_STRUCT_STAT *psbuf)
1387 struct smb_filename smb_fname = {
1388 .base_name = discard_const_p(char, smb_fname_in->base_name),
1389 .flags = smb_fname_in->flags
1393 if (smb_fname.flags & SMB_FILENAME_POSIX_PATH) {
1394 ret = SMB_VFS_LSTAT(conn, &smb_fname);
1396 ret = SMB_VFS_STAT(conn, &smb_fname);
1400 *psbuf = smb_fname.st;
1406 * Ensure LSTAT is called for POSIX paths.
1409 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1413 if(fsp->fh->fd == -1) {
1414 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1415 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1417 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1420 return map_nt_error_from_unix(errno);
1423 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1424 return map_nt_error_from_unix(errno);
1427 return NT_STATUS_OK;
1431 * Initialize num_streams and streams, then call VFS op streaminfo
1433 NTSTATUS vfs_streaminfo(connection_struct *conn,
1434 struct files_struct *fsp,
1435 const struct smb_filename *smb_fname,
1436 TALLOC_CTX *mem_ctx,
1437 unsigned int *num_streams,
1438 struct stream_struct **streams)
1442 return SMB_VFS_STREAMINFO(conn,
1451 generate a file_id from a stat structure
1453 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1455 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1458 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1459 const char *service, const char *user)
1462 return handle->fns->connect_fn(handle, service, user);
1465 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1467 VFS_FIND(disconnect);
1468 handle->fns->disconnect_fn(handle);
1471 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1472 const struct smb_filename *smb_fname,
1477 VFS_FIND(disk_free);
1478 return handle->fns->disk_free_fn(handle, smb_fname,
1479 bsize, dfree, dsize);
1482 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1483 const struct smb_filename *smb_fname,
1484 enum SMB_QUOTA_TYPE qtype,
1488 VFS_FIND(get_quota);
1489 return handle->fns->get_quota_fn(handle, smb_fname, qtype, id, qt);
1492 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1493 enum SMB_QUOTA_TYPE qtype, unid_t id,
1496 VFS_FIND(set_quota);
1497 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1500 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1501 struct files_struct *fsp,
1502 struct shadow_copy_data *shadow_copy_data,
1505 VFS_FIND(get_shadow_copy_data);
1506 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1510 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle,
1511 const struct smb_filename *smb_fname,
1512 struct vfs_statvfs_struct *statbuf)
1515 return handle->fns->statvfs_fn(handle, smb_fname, statbuf);
1518 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1519 enum timestamp_set_resolution *p_ts_res)
1521 VFS_FIND(fs_capabilities);
1522 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1525 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1526 struct dfs_GetDFSReferral *r)
1528 VFS_FIND(get_dfs_referrals);
1529 return handle->fns->get_dfs_referrals_fn(handle, r);
1532 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1533 const struct smb_filename *smb_fname,
1535 uint32_t attributes)
1538 return handle->fns->opendir_fn(handle, smb_fname, mask, attributes);
1541 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1542 struct files_struct *fsp,
1544 uint32_t attributes)
1546 VFS_FIND(fdopendir);
1547 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1550 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1552 SMB_STRUCT_STAT *sbuf)
1555 return handle->fns->readdir_fn(handle, dirp, sbuf);
1558 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1559 DIR *dirp, long offset)
1562 handle->fns->seekdir_fn(handle, dirp, offset);
1565 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1569 return handle->fns->telldir_fn(handle, dirp);
1572 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1575 VFS_FIND(rewind_dir);
1576 handle->fns->rewind_dir_fn(handle, dirp);
1579 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle,
1580 const struct smb_filename *smb_fname,
1584 return handle->fns->mkdir_fn(handle, smb_fname, mode);
1587 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle,
1588 const struct smb_filename *smb_fname)
1591 return handle->fns->rmdir_fn(handle, smb_fname);
1594 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1598 return handle->fns->closedir_fn(handle, dir);
1601 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1602 struct smb_filename *smb_fname, struct files_struct *fsp,
1603 int flags, mode_t mode)
1606 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1609 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1610 struct smb_request *req,
1611 uint16_t root_dir_fid,
1612 struct smb_filename *smb_fname,
1613 uint32_t access_mask,
1614 uint32_t share_access,
1615 uint32_t create_disposition,
1616 uint32_t create_options,
1617 uint32_t file_attributes,
1618 uint32_t oplock_request,
1619 struct smb2_lease *lease,
1620 uint64_t allocation_size,
1621 uint32_t private_flags,
1622 struct security_descriptor *sd,
1623 struct ea_list *ea_list,
1624 files_struct **result,
1626 const struct smb2_create_blobs *in_context_blobs,
1627 struct smb2_create_blobs *out_context_blobs)
1629 VFS_FIND(create_file);
1630 return handle->fns->create_file_fn(
1631 handle, req, root_dir_fid, smb_fname, access_mask,
1632 share_access, create_disposition, create_options,
1633 file_attributes, oplock_request, lease, allocation_size,
1634 private_flags, sd, ea_list,
1635 result, pinfo, in_context_blobs, out_context_blobs);
1638 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1639 struct files_struct *fsp)
1642 return handle->fns->close_fn(handle, fsp);
1645 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1646 struct files_struct *fsp, void *data, size_t n,
1650 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1653 struct smb_vfs_call_pread_state {
1654 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1656 struct vfs_aio_state vfs_aio_state;
1659 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1661 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1662 TALLOC_CTX *mem_ctx,
1663 struct tevent_context *ev,
1664 struct files_struct *fsp,
1666 size_t n, off_t offset)
1668 struct tevent_req *req, *subreq;
1669 struct smb_vfs_call_pread_state *state;
1671 req = tevent_req_create(mem_ctx, &state,
1672 struct smb_vfs_call_pread_state);
1676 VFS_FIND(pread_send);
1677 state->recv_fn = handle->fns->pread_recv_fn;
1679 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1681 if (tevent_req_nomem(subreq, req)) {
1682 return tevent_req_post(req, ev);
1684 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1688 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1690 struct tevent_req *req = tevent_req_callback_data(
1691 subreq, struct tevent_req);
1692 struct smb_vfs_call_pread_state *state = tevent_req_data(
1693 req, struct smb_vfs_call_pread_state);
1695 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1696 TALLOC_FREE(subreq);
1697 if (state->retval == -1) {
1698 tevent_req_error(req, state->vfs_aio_state.error);
1701 tevent_req_done(req);
1704 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req,
1705 struct vfs_aio_state *vfs_aio_state)
1707 struct smb_vfs_call_pread_state *state = tevent_req_data(
1708 req, struct smb_vfs_call_pread_state);
1710 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1711 tevent_req_received(req);
1714 *vfs_aio_state = state->vfs_aio_state;
1715 tevent_req_received(req);
1716 return state->retval;
1719 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1720 struct files_struct *fsp, const void *data,
1721 size_t n, off_t offset)
1724 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1727 struct smb_vfs_call_pwrite_state {
1728 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1730 struct vfs_aio_state vfs_aio_state;
1733 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1735 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1736 TALLOC_CTX *mem_ctx,
1737 struct tevent_context *ev,
1738 struct files_struct *fsp,
1740 size_t n, off_t offset)
1742 struct tevent_req *req, *subreq;
1743 struct smb_vfs_call_pwrite_state *state;
1745 req = tevent_req_create(mem_ctx, &state,
1746 struct smb_vfs_call_pwrite_state);
1750 VFS_FIND(pwrite_send);
1751 state->recv_fn = handle->fns->pwrite_recv_fn;
1753 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1755 if (tevent_req_nomem(subreq, req)) {
1756 return tevent_req_post(req, ev);
1758 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1762 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1764 struct tevent_req *req = tevent_req_callback_data(
1765 subreq, struct tevent_req);
1766 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1767 req, struct smb_vfs_call_pwrite_state);
1769 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1770 TALLOC_FREE(subreq);
1771 if (state->retval == -1) {
1772 tevent_req_error(req, state->vfs_aio_state.error);
1775 tevent_req_done(req);
1778 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req,
1779 struct vfs_aio_state *vfs_aio_state)
1781 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1782 req, struct smb_vfs_call_pwrite_state);
1784 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1787 *vfs_aio_state = state->vfs_aio_state;
1788 return state->retval;
1791 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1792 struct files_struct *fsp, off_t offset,
1796 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1799 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1800 files_struct *fromfsp, const DATA_BLOB *header,
1801 off_t offset, size_t count)
1804 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1808 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1809 files_struct *tofsp, off_t offset,
1813 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1816 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1817 const struct smb_filename *smb_fname_src,
1818 const struct smb_filename *smb_fname_dst)
1821 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1824 struct smb_vfs_call_fsync_state {
1825 int (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1827 struct vfs_aio_state vfs_aio_state;
1830 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1832 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1833 TALLOC_CTX *mem_ctx,
1834 struct tevent_context *ev,
1835 struct files_struct *fsp)
1837 struct tevent_req *req, *subreq;
1838 struct smb_vfs_call_fsync_state *state;
1840 req = tevent_req_create(mem_ctx, &state,
1841 struct smb_vfs_call_fsync_state);
1845 VFS_FIND(fsync_send);
1846 state->recv_fn = handle->fns->fsync_recv_fn;
1848 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1849 if (tevent_req_nomem(subreq, req)) {
1850 return tevent_req_post(req, ev);
1852 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1856 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1858 struct tevent_req *req = tevent_req_callback_data(
1859 subreq, struct tevent_req);
1860 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1861 req, struct smb_vfs_call_fsync_state);
1863 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1864 TALLOC_FREE(subreq);
1865 if (state->retval == -1) {
1866 tevent_req_error(req, state->vfs_aio_state.error);
1869 tevent_req_done(req);
1872 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state)
1874 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1875 req, struct smb_vfs_call_fsync_state);
1877 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1880 *vfs_aio_state = state->vfs_aio_state;
1881 return state->retval;
1885 * Synchronous version of fsync, built from backend
1886 * async VFS primitives. Uses a temporary sub-event
1887 * context (NOT NESTED).
1890 int smb_vfs_fsync_sync(files_struct *fsp)
1892 TALLOC_CTX *frame = talloc_stackframe();
1893 struct tevent_req *req = NULL;
1894 struct vfs_aio_state aio_state = { 0 };
1897 struct tevent_context *ev = samba_tevent_context_init(frame);
1903 req = SMB_VFS_FSYNC_SEND(talloc_tos(), ev, fsp);
1908 ok = tevent_req_poll(req, ev);
1913 ret = SMB_VFS_FSYNC_RECV(req, &aio_state);
1918 if (aio_state.error != 0) {
1919 errno = aio_state.error;
1924 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1925 struct smb_filename *smb_fname)
1928 return handle->fns->stat_fn(handle, smb_fname);
1931 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1932 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1935 return handle->fns->fstat_fn(handle, fsp, sbuf);
1938 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1939 struct smb_filename *smb_filename)
1942 return handle->fns->lstat_fn(handle, smb_filename);
1945 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1946 struct files_struct *fsp,
1947 const SMB_STRUCT_STAT *sbuf)
1949 VFS_FIND(get_alloc_size);
1950 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1953 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1954 const struct smb_filename *smb_fname)
1957 return handle->fns->unlink_fn(handle, smb_fname);
1960 int smb_vfs_call_chmod(struct vfs_handle_struct *handle,
1961 const struct smb_filename *smb_fname,
1965 return handle->fns->chmod_fn(handle, smb_fname, mode);
1968 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1969 struct files_struct *fsp, mode_t mode)
1972 return handle->fns->fchmod_fn(handle, fsp, mode);
1975 int smb_vfs_call_chown(struct vfs_handle_struct *handle,
1976 const struct smb_filename *smb_fname,
1981 return handle->fns->chown_fn(handle, smb_fname, uid, gid);
1984 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1985 struct files_struct *fsp, uid_t uid, gid_t gid)
1988 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1991 int smb_vfs_call_lchown(struct vfs_handle_struct *handle,
1992 const struct smb_filename *smb_fname,
1997 return handle->fns->lchown_fn(handle, smb_fname, uid, gid);
2000 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
2003 bool as_root = false;
2006 if (fsp->fh->fd != -1) {
2008 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
2010 return NT_STATUS_OK;
2012 if (ret == -1 && errno != ENOSYS) {
2013 return map_nt_error_from_unix(errno);
2017 as_root = (geteuid() == 0);
2021 * We are being asked to chown as root. Make
2022 * sure we chdir() into the path to pin it,
2023 * and always act using lchown to ensure we
2024 * don't deref any symbolic links.
2026 char *parent_dir = NULL;
2027 const char *final_component = NULL;
2028 struct smb_filename *local_smb_fname = NULL;
2029 struct smb_filename parent_dir_fname = {0};
2030 struct smb_filename *saved_dir_fname = NULL;
2032 saved_dir_fname = vfs_GetWd(talloc_tos(),fsp->conn);
2033 if (!saved_dir_fname) {
2034 status = map_nt_error_from_unix(errno);
2035 DEBUG(0,("vfs_chown_fsp: failed to get "
2036 "current working directory. Error was %s\n",
2041 if (!parent_dirname(talloc_tos(),
2042 fsp->fsp_name->base_name,
2044 &final_component)) {
2045 return NT_STATUS_NO_MEMORY;
2048 parent_dir_fname = (struct smb_filename) {
2049 .base_name = parent_dir,
2050 .flags = fsp->fsp_name->flags
2053 /* cd into the parent dir to pin it. */
2054 ret = vfs_ChDir(fsp->conn, &parent_dir_fname);
2056 return map_nt_error_from_unix(errno);
2059 local_smb_fname = synthetic_smb_fname(talloc_tos(),
2063 fsp->fsp_name->flags);
2064 if (local_smb_fname == NULL) {
2065 status = NT_STATUS_NO_MEMORY;
2069 /* Must use lstat here. */
2070 ret = SMB_VFS_LSTAT(fsp->conn, local_smb_fname);
2072 status = map_nt_error_from_unix(errno);
2076 /* Ensure it matches the fsp stat. */
2077 if (!check_same_stat(&local_smb_fname->st,
2078 &fsp->fsp_name->st)) {
2079 status = NT_STATUS_ACCESS_DENIED;
2083 ret = SMB_VFS_LCHOWN(fsp->conn,
2088 status = NT_STATUS_OK;
2090 status = map_nt_error_from_unix(errno);
2095 vfs_ChDir(fsp->conn, saved_dir_fname);
2096 TALLOC_FREE(local_smb_fname);
2097 TALLOC_FREE(saved_dir_fname);
2098 TALLOC_FREE(parent_dir);
2103 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
2104 ret = SMB_VFS_LCHOWN(fsp->conn,
2108 ret = SMB_VFS_CHOWN(fsp->conn,
2114 status = NT_STATUS_OK;
2116 status = map_nt_error_from_unix(errno);
2121 int smb_vfs_call_chdir(struct vfs_handle_struct *handle,
2122 const struct smb_filename *smb_fname)
2125 return handle->fns->chdir_fn(handle, smb_fname);
2128 struct smb_filename *smb_vfs_call_getwd(struct vfs_handle_struct *handle,
2132 return handle->fns->getwd_fn(handle, ctx);
2135 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
2136 const struct smb_filename *smb_fname,
2137 struct smb_file_time *ft)
2140 return handle->fns->ntimes_fn(handle, smb_fname, ft);
2143 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2144 struct files_struct *fsp, off_t offset)
2146 VFS_FIND(ftruncate);
2147 return handle->fns->ftruncate_fn(handle, fsp, offset);
2150 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2151 struct files_struct *fsp,
2156 VFS_FIND(fallocate);
2157 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2160 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2161 struct files_struct *fsp, uint32_t share_mode,
2162 uint32_t access_mask)
2164 VFS_FIND(kernel_flock);
2165 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2169 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2170 struct files_struct *fsp, int leasetype)
2172 VFS_FIND(linux_setlease);
2173 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2176 int smb_vfs_call_symlink(struct vfs_handle_struct *handle,
2177 const char *link_target,
2178 const struct smb_filename *new_smb_fname)
2181 return handle->fns->symlink_fn(handle, link_target, new_smb_fname);
2184 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2185 const struct smb_filename *smb_fname,
2190 return handle->fns->readlink_fn(handle, smb_fname, buf, bufsiz);
2193 int smb_vfs_call_link(struct vfs_handle_struct *handle,
2194 const struct smb_filename *old_smb_fname,
2195 const struct smb_filename *new_smb_fname)
2198 return handle->fns->link_fn(handle, old_smb_fname, new_smb_fname);
2201 int smb_vfs_call_mknod(struct vfs_handle_struct *handle,
2202 const struct smb_filename *smb_fname,
2207 return handle->fns->mknod_fn(handle, smb_fname, mode, dev);
2210 struct smb_filename *smb_vfs_call_realpath(struct vfs_handle_struct *handle,
2212 const struct smb_filename *smb_fname)
2215 return handle->fns->realpath_fn(handle, ctx, smb_fname);
2218 int smb_vfs_call_chflags(struct vfs_handle_struct *handle,
2219 const struct smb_filename *smb_fname,
2223 return handle->fns->chflags_fn(handle, smb_fname, flags);
2226 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2227 const SMB_STRUCT_STAT *sbuf)
2229 VFS_FIND(file_id_create);
2230 return handle->fns->file_id_create_fn(handle, sbuf);
2233 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2234 struct files_struct *fsp,
2235 const struct smb_filename *smb_fname,
2236 TALLOC_CTX *mem_ctx,
2237 unsigned int *num_streams,
2238 struct stream_struct **streams)
2240 VFS_FIND(streaminfo);
2241 return handle->fns->streaminfo_fn(handle, fsp, smb_fname, mem_ctx,
2242 num_streams, streams);
2245 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2246 const char *path, const char *name,
2247 TALLOC_CTX *mem_ctx, char **found_name)
2249 VFS_FIND(get_real_filename);
2250 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2254 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2255 const struct smb_filename *smb_fname)
2257 VFS_FIND(connectpath);
2258 return handle->fns->connectpath_fn(handle, smb_fname);
2261 bool smb_vfs_call_strict_lock_check(struct vfs_handle_struct *handle,
2262 struct files_struct *fsp,
2263 struct lock_struct *plock)
2265 VFS_FIND(strict_lock_check);
2266 return handle->fns->strict_lock_check_fn(handle, fsp, plock);
2269 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2271 enum vfs_translate_direction direction,
2272 TALLOC_CTX *mem_ctx,
2275 VFS_FIND(translate_name);
2276 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2280 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2281 struct files_struct *fsp,
2285 const uint8_t *in_data,
2288 uint32_t max_out_len,
2292 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2293 in_data, in_len, out_data, max_out_len,
2297 NTSTATUS smb_vfs_call_get_dos_attributes(struct vfs_handle_struct *handle,
2298 struct smb_filename *smb_fname,
2301 VFS_FIND(get_dos_attributes);
2302 return handle->fns->get_dos_attributes_fn(handle, smb_fname, dosmode);
2305 NTSTATUS smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct *handle,
2306 struct files_struct *fsp,
2309 VFS_FIND(fget_dos_attributes);
2310 return handle->fns->fget_dos_attributes_fn(handle, fsp, dosmode);
2313 NTSTATUS smb_vfs_call_set_dos_attributes(struct vfs_handle_struct *handle,
2314 const struct smb_filename *smb_fname,
2317 VFS_FIND(set_dos_attributes);
2318 return handle->fns->set_dos_attributes_fn(handle, smb_fname, dosmode);
2321 NTSTATUS smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct *handle,
2322 struct files_struct *fsp,
2325 VFS_FIND(set_dos_attributes);
2326 return handle->fns->fset_dos_attributes_fn(handle, fsp, dosmode);
2329 struct tevent_req *smb_vfs_call_offload_read_send(TALLOC_CTX *mem_ctx,
2330 struct tevent_context *ev,
2331 struct vfs_handle_struct *handle,
2332 struct files_struct *fsp,
2338 VFS_FIND(offload_read_send);
2339 return handle->fns->offload_read_send_fn(mem_ctx, ev, handle,
2341 ttl, offset, to_copy);
2344 NTSTATUS smb_vfs_call_offload_read_recv(struct tevent_req *req,
2345 struct vfs_handle_struct *handle,
2346 TALLOC_CTX *mem_ctx,
2347 DATA_BLOB *token_blob)
2349 VFS_FIND(offload_read_recv);
2350 return handle->fns->offload_read_recv_fn(req, handle, mem_ctx, token_blob);
2353 struct tevent_req *smb_vfs_call_offload_write_send(struct vfs_handle_struct *handle,
2354 TALLOC_CTX *mem_ctx,
2355 struct tevent_context *ev,
2358 off_t transfer_offset,
2359 struct files_struct *dest_fsp,
2363 VFS_FIND(offload_write_send);
2364 return handle->fns->offload_write_send_fn(handle, mem_ctx, ev, fsctl,
2365 token, transfer_offset,
2366 dest_fsp, dest_off, num);
2369 NTSTATUS smb_vfs_call_offload_write_recv(struct vfs_handle_struct *handle,
2370 struct tevent_req *req,
2373 VFS_FIND(offload_write_recv);
2374 return handle->fns->offload_write_recv_fn(handle, req, copied);
2377 NTSTATUS smb_vfs_call_get_compression(vfs_handle_struct *handle,
2378 TALLOC_CTX *mem_ctx,
2379 struct files_struct *fsp,
2380 struct smb_filename *smb_fname,
2381 uint16_t *_compression_fmt)
2383 VFS_FIND(get_compression);
2384 return handle->fns->get_compression_fn(handle, mem_ctx, fsp, smb_fname,
2388 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2389 TALLOC_CTX *mem_ctx,
2390 struct files_struct *fsp,
2391 uint16_t compression_fmt)
2393 VFS_FIND(set_compression);
2394 return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2398 NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
2399 TALLOC_CTX *mem_ctx,
2400 const char *service_path,
2403 VFS_FIND(snap_check_path);
2404 return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path,
2408 NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle,
2409 TALLOC_CTX *mem_ctx,
2410 const char *base_volume,
2416 VFS_FIND(snap_create);
2417 return handle->fns->snap_create_fn(handle, mem_ctx, base_volume, tstamp,
2418 rw, base_path, snap_path);
2421 NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle,
2422 TALLOC_CTX *mem_ctx,
2426 VFS_FIND(snap_delete);
2427 return handle->fns->snap_delete_fn(handle, mem_ctx, base_path,
2431 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2432 struct files_struct *fsp,
2433 uint32_t security_info,
2434 TALLOC_CTX *mem_ctx,
2435 struct security_descriptor **ppdesc)
2437 VFS_FIND(fget_nt_acl);
2438 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2442 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2443 const struct smb_filename *smb_fname,
2444 uint32_t security_info,
2445 TALLOC_CTX *mem_ctx,
2446 struct security_descriptor **ppdesc)
2448 VFS_FIND(get_nt_acl);
2449 return handle->fns->get_nt_acl_fn(handle,
2456 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2457 struct files_struct *fsp,
2458 uint32_t security_info_sent,
2459 const struct security_descriptor *psd)
2461 VFS_FIND(fset_nt_acl);
2462 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2466 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2467 struct smb_filename *file,
2468 struct security_acl *sacl,
2469 uint32_t access_requested,
2470 uint32_t access_denied)
2472 VFS_FIND(audit_file);
2473 return handle->fns->audit_file_fn(handle,
2480 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2481 const struct smb_filename *smb_fname,
2482 SMB_ACL_TYPE_T type,
2483 TALLOC_CTX *mem_ctx)
2485 VFS_FIND(sys_acl_get_file);
2486 return handle->fns->sys_acl_get_file_fn(handle, smb_fname, type, mem_ctx);
2489 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2490 struct files_struct *fsp,
2491 TALLOC_CTX *mem_ctx)
2493 VFS_FIND(sys_acl_get_fd);
2494 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2497 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2498 const struct smb_filename *smb_fname,
2499 TALLOC_CTX *mem_ctx,
2500 char **blob_description,
2503 VFS_FIND(sys_acl_blob_get_file);
2504 return handle->fns->sys_acl_blob_get_file_fn(handle, smb_fname,
2505 mem_ctx, blob_description, blob);
2508 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2509 struct files_struct *fsp,
2510 TALLOC_CTX *mem_ctx,
2511 char **blob_description,
2514 VFS_FIND(sys_acl_blob_get_fd);
2515 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2518 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2519 const struct smb_filename *smb_fname,
2520 SMB_ACL_TYPE_T acltype,
2523 VFS_FIND(sys_acl_set_file);
2524 return handle->fns->sys_acl_set_file_fn(handle, smb_fname,
2528 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2529 struct files_struct *fsp, SMB_ACL_T theacl)
2531 VFS_FIND(sys_acl_set_fd);
2532 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2535 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2536 const struct smb_filename *smb_fname)
2538 VFS_FIND(sys_acl_delete_def_file);
2539 return handle->fns->sys_acl_delete_def_file_fn(handle, smb_fname);
2542 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2543 const struct smb_filename *smb_fname,
2549 return handle->fns->getxattr_fn(handle, smb_fname, name, value, size);
2552 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2553 struct files_struct *fsp, const char *name,
2554 void *value, size_t size)
2556 VFS_FIND(fgetxattr);
2557 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2560 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2561 const struct smb_filename *smb_fname,
2565 VFS_FIND(listxattr);
2566 return handle->fns->listxattr_fn(handle, smb_fname, list, size);
2569 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2570 struct files_struct *fsp, char *list,
2573 VFS_FIND(flistxattr);
2574 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2577 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2578 const struct smb_filename *smb_fname,
2581 VFS_FIND(removexattr);
2582 return handle->fns->removexattr_fn(handle, smb_fname, name);
2585 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2586 struct files_struct *fsp, const char *name)
2588 VFS_FIND(fremovexattr);
2589 return handle->fns->fremovexattr_fn(handle, fsp, name);
2592 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle,
2593 const struct smb_filename *smb_fname,
2600 return handle->fns->setxattr_fn(handle, smb_fname,
2601 name, value, size, flags);
2604 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2605 struct files_struct *fsp, const char *name,
2606 const void *value, size_t size, int flags)
2608 VFS_FIND(fsetxattr);
2609 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2612 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2613 struct files_struct *fsp)
2615 VFS_FIND(aio_force);
2616 return handle->fns->aio_force_fn(handle, fsp);
2619 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2620 struct files_struct *fsp,
2621 TALLOC_CTX *mem_ctx,
2624 VFS_FIND(durable_cookie);
2625 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2628 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2629 struct files_struct *fsp,
2630 const DATA_BLOB old_cookie,
2631 TALLOC_CTX *mem_ctx,
2632 DATA_BLOB *new_cookie)
2634 VFS_FIND(durable_disconnect);
2635 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2636 mem_ctx, new_cookie);
2639 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2640 struct smb_request *smb1req,
2641 struct smbXsrv_open *op,
2642 const DATA_BLOB old_cookie,
2643 TALLOC_CTX *mem_ctx,
2644 struct files_struct **fsp,
2645 DATA_BLOB *new_cookie)
2647 VFS_FIND(durable_reconnect);
2648 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2649 old_cookie, mem_ctx, fsp,
2653 NTSTATUS smb_vfs_call_readdir_attr(struct vfs_handle_struct *handle,
2654 const struct smb_filename *fname,
2655 TALLOC_CTX *mem_ctx,
2656 struct readdir_attr_data **attr_data)
2658 VFS_FIND(readdir_attr);
2659 return handle->fns->readdir_attr_fn(handle, fname, mem_ctx, attr_data);