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 /****************************************************************************
402 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
403 ****************************************************************************/
405 ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
409 while (total < byte_count)
411 ssize_t ret = SMB_VFS_READ(fsp, buf + total,
414 if (ret == 0) return total;
423 return (ssize_t)total;
426 /****************************************************************************
427 Write data to a fd on the vfs.
428 ****************************************************************************/
430 ssize_t vfs_write_data(struct smb_request *req,
438 if (req && req->unread_bytes) {
439 int sockfd = req->xconn->transport.sock;
441 SMB_ASSERT(req->unread_bytes == N);
442 /* VFS_RECVFILE must drain the socket
443 * before returning. */
444 req->unread_bytes = 0;
445 /* Ensure the socket is blocking. */
446 old_flags = fcntl(sockfd, F_GETFL, 0);
447 if (set_blocking(sockfd, true) == -1) {
450 ret = SMB_VFS_RECVFILE(sockfd,
454 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
461 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
470 return (ssize_t)total;
473 ssize_t vfs_pwrite_data(struct smb_request *req,
482 if (req && req->unread_bytes) {
483 int sockfd = req->xconn->transport.sock;
484 SMB_ASSERT(req->unread_bytes == N);
485 /* VFS_RECVFILE must drain the socket
486 * before returning. */
487 req->unread_bytes = 0;
489 * Leave the socket non-blocking and
490 * use SMB_VFS_RECVFILE. If it returns
491 * EAGAIN || EWOULDBLOCK temporarily set
492 * the socket blocking and retry
496 ret = SMB_VFS_RECVFILE(sockfd,
500 if (ret == 0 || (ret == -1 &&
502 errno == EWOULDBLOCK))) {
504 /* Ensure the socket is blocking. */
505 old_flags = fcntl(sockfd, F_GETFL, 0);
506 if (set_blocking(sockfd, true) == -1) {
509 ret = SMB_VFS_RECVFILE(sockfd,
513 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
520 return (ssize_t)total;
522 /* Any other error case. */
528 return (ssize_t)total;
532 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
542 return (ssize_t)total;
544 /****************************************************************************
545 An allocate file space call using the vfs interface.
546 Allocates space for a file from a filedescriptor.
547 Returns 0 on success, -1 on failure.
548 ****************************************************************************/
550 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
553 connection_struct *conn = fsp->conn;
554 uint64_t space_avail;
555 uint64_t bsize,dfree,dsize;
559 * Actually try and commit the space on disk....
562 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
563 fsp_str_dbg(fsp), (double)len));
565 if (((off_t)len) < 0) {
566 DEBUG(0,("vfs_allocate_file_space: %s negative len "
567 "requested.\n", fsp_str_dbg(fsp)));
572 status = vfs_stat_fsp(fsp);
573 if (!NT_STATUS_IS_OK(status)) {
577 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
580 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
581 /* Shrink - use ftruncate. */
583 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
584 "size %.0f\n", fsp_str_dbg(fsp),
585 (double)fsp->fsp_name->st.st_ex_size));
587 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
589 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
590 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
591 set_filelen_write_cache(fsp, len);
594 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
599 /* Grow - we need to test if we have enough space. */
601 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
603 if (lp_strict_allocate(SNUM(fsp->conn))) {
604 /* See if we have a syscall that will allocate beyond
605 end-of-file without changing EOF. */
606 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_FL_KEEP_SIZE,
612 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
615 /* We changed the allocation size on disk, but not
616 EOF - exactly as required. We're done ! */
620 if (ret == -1 && errno == ENOSPC) {
624 len -= fsp->fsp_name->st.st_ex_size;
625 len /= 1024; /* Len is now number of 1k blocks needed. */
627 get_dfree_info(conn, fsp->fsp_name, &bsize, &dfree, &dsize);
628 if (space_avail == (uint64_t)-1) {
632 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
633 "needed blocks = %.0f, space avail = %.0f\n",
634 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
635 (double)space_avail));
637 if (len > space_avail) {
645 /****************************************************************************
646 A vfs set_filelen call.
647 set the length of a file from a filedescriptor.
648 Returns 0 on success, -1 on failure.
649 ****************************************************************************/
651 int vfs_set_filelen(files_struct *fsp, off_t len)
655 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
657 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
658 fsp_str_dbg(fsp), (double)len));
659 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
660 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
661 set_filelen_write_cache(fsp, len);
662 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
663 FILE_NOTIFY_CHANGE_SIZE
664 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
665 fsp->fsp_name->base_name);
668 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
673 /****************************************************************************
674 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
675 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
676 as this is also called from the default SMB_VFS_FTRUNCATE code.
677 Always extends the file size.
678 Returns 0 on success, -1 on failure.
679 ****************************************************************************/
681 #define SPARSE_BUF_WRITE_SIZE (32*1024)
683 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
689 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
696 while (total < len) {
697 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
699 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
700 if (pwrite_ret == -1) {
701 int saved_errno = errno;
702 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
703 "%s failed with error %s\n",
704 fsp_str_dbg(fsp), strerror(saved_errno)));
714 /****************************************************************************
715 A vfs fill sparse call.
716 Writes zeros from the end of file to len, if len is greater than EOF.
717 Used only by strict_sync.
718 Returns 0 on success, -1 on failure.
719 ****************************************************************************/
721 int vfs_fill_sparse(files_struct *fsp, off_t len)
728 status = vfs_stat_fsp(fsp);
729 if (!NT_STATUS_IS_OK(status)) {
733 if (len <= fsp->fsp_name->st.st_ex_size) {
738 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
743 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
744 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
745 (double)fsp->fsp_name->st.st_ex_size, (double)len,
746 (double)(len - fsp->fsp_name->st.st_ex_size)));
748 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
750 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
752 offset = fsp->fsp_name->st.st_ex_size;
753 num_to_write = len - fsp->fsp_name->st.st_ex_size;
755 /* Only do this on non-stream file handles. */
756 if (fsp->base_fsp == NULL) {
757 /* for allocation try fallocate first. This can fail on some
758 * platforms e.g. when the filesystem doesn't support it and no
759 * emulation is being done by the libc (like on AIX with JFS1). In that
760 * case we do our own emulation. fallocate implementations can
761 * return ENOTSUP or EINVAL in cases like that. */
762 ret = SMB_VFS_FALLOCATE(fsp, 0, offset, num_to_write);
763 if (ret == -1 && errno == ENOSPC) {
769 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
770 "error %d. Falling back to slow manual allocation\n", ret));
773 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
778 set_filelen_write_cache(fsp, len);
781 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
785 /****************************************************************************
786 Transfer some data (n bytes) between two file_struct's.
787 ****************************************************************************/
789 static ssize_t vfs_pread_fn(void *file, void *buf, size_t len, off_t offset)
791 struct files_struct *fsp = (struct files_struct *)file;
793 return SMB_VFS_PREAD(fsp, buf, len, offset);
796 static ssize_t vfs_pwrite_fn(void *file, const void *buf, size_t len, off_t offset)
798 struct files_struct *fsp = (struct files_struct *)file;
800 return SMB_VFS_PWRITE(fsp, buf, len, offset);
803 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
805 return transfer_file_internal((void *)in, (void *)out, n,
806 vfs_pread_fn, vfs_pwrite_fn);
809 /*******************************************************************
810 A vfs_readdir wrapper which just returns the file name.
811 ********************************************************************/
813 const char *vfs_readdirname(connection_struct *conn, void *p,
814 SMB_STRUCT_STAT *sbuf, char **talloced)
816 struct dirent *ptr= NULL;
824 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
836 #ifdef HAVE_BROKEN_READDIR_NAME
837 /* using /usr/ucb/cc is BAD */
841 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
842 talloc_tos(), &translated);
843 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
847 *talloced = translated;
848 if (!NT_STATUS_IS_OK(status)) {
854 /*******************************************************************
855 A wrapper for vfs_chdir().
856 ********************************************************************/
858 int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
863 LastDir = SMB_STRDUP("");
866 if (ISDOT(smb_fname->base_name)) {
870 if (*smb_fname->base_name == '/' &&
871 strcsequal(LastDir,smb_fname->base_name)) {
875 DEBUG(4,("vfs_ChDir to %s\n", smb_fname->base_name));
877 ret = SMB_VFS_CHDIR(conn, smb_fname);
881 LastDir = SMB_STRDUP(smb_fname->base_name);
884 TALLOC_FREE(conn->cwd_fname);
885 conn->cwd_fname = vfs_GetWd(conn, conn);
886 if (conn->cwd_fname == NULL) {
887 smb_panic("con->cwd getwd failed\n");
891 DEBUG(4,("vfs_ChDir got %s\n",conn->cwd_fname->base_name));
896 /*******************************************************************
897 Return the absolute current directory path - given a UNIX pathname.
898 Note that this path is returned in DOS format, not UNIX
899 format. Note this can be called with conn == NULL.
900 ********************************************************************/
902 struct smb_filename *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
904 struct smb_filename *current_dir_fname = NULL;
906 struct smb_filename *smb_fname_dot = NULL;
907 struct smb_filename *smb_fname_full = NULL;
908 struct smb_filename *result = NULL;
910 if (!lp_getwd_cache()) {
914 smb_fname_dot = synthetic_smb_fname(ctx, ".", NULL, NULL, 0);
915 if (smb_fname_dot == NULL) {
920 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
922 * Known to fail for root: the directory may be NFS-mounted
923 * and exported with root_squash (so has no root access).
925 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
926 "(NFS problem ?)\n", strerror(errno) ));
930 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
932 smb_fname_full = (struct smb_filename *)memcache_lookup_talloc(
935 data_blob_const(&key, sizeof(key)));
937 if (smb_fname_full == NULL) {
941 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
942 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
943 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
944 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
947 * Note: smb_fname_full is owned by smbd_memcache()
948 * so we must make a copy to return.
950 result = cp_smb_filename(ctx, smb_fname_full);
951 if (result == NULL) {
960 * We don't have the information to hand so rely on traditional
961 * methods. The very slow getcwd, which spawns a process on some
962 * systems, or the not quite so bad getwd.
965 current_dir_fname = SMB_VFS_GETWD(conn, ctx);
966 if (current_dir_fname == NULL) {
967 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
972 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
973 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
976 * smbd_memcache() will own current_dir_fname after the
977 * memcache_add_talloc call, so we must make
978 * a copy on ctx to return.
980 result = cp_smb_filename(ctx, current_dir_fname);
981 if (result == NULL) {
986 * Ensure the memory going into the cache
987 * doesn't have a destructor so it can be
990 talloc_set_destructor(current_dir_fname, NULL);
992 memcache_add_talloc(smbd_memcache(),
994 data_blob_const(&key, sizeof(key)),
996 /* current_dir_fname is now == NULL here. */
998 /* current_dir_fname is already allocated on ctx. */
999 result = current_dir_fname;
1003 TALLOC_FREE(smb_fname_dot);
1005 * Don't free current_dir_fname here. It's either been moved
1006 * to the memcache or is being returned in result.
1011 /*******************************************************************
1012 Reduce a file name, removing .. elements and checking that
1013 it is below dir in the heirachy. This uses realpath.
1014 This function must run as root, and will return names
1015 and valid stat structs that can be checked on open.
1016 ********************************************************************/
1018 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
1020 struct smb_request *smbreq)
1023 TALLOC_CTX *ctx = talloc_tos();
1024 const char *conn_rootdir;
1026 char *dir_name = NULL;
1027 const char *last_component = NULL;
1028 char *resolved_name = NULL;
1029 struct smb_filename *saved_dir_fname = NULL;
1030 struct smb_filename *smb_fname_cwd = NULL;
1031 struct privilege_paths *priv_paths = NULL;
1034 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
1036 conn->connectpath));
1039 priv_paths = talloc_zero(smbreq, struct privilege_paths);
1041 status = NT_STATUS_NO_MEMORY;
1045 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
1046 status = NT_STATUS_NO_MEMORY;
1050 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
1051 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
1053 if (priv_paths->parent_name.base_name == NULL ||
1054 priv_paths->file_name.base_name == NULL) {
1055 status = NT_STATUS_NO_MEMORY;
1059 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
1060 status = map_nt_error_from_unix(errno);
1063 /* Remember where we were. */
1064 saved_dir_fname = vfs_GetWd(ctx, conn);
1065 if (!saved_dir_fname) {
1066 status = map_nt_error_from_unix(errno);
1070 if (vfs_ChDir(conn, &priv_paths->parent_name) == -1) {
1071 status = map_nt_error_from_unix(errno);
1075 /* Get the absolute path of the parent directory. */
1076 resolved_name = SMB_VFS_REALPATH(conn,".");
1077 if (!resolved_name) {
1078 status = map_nt_error_from_unix(errno);
1082 if (*resolved_name != '/') {
1083 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1084 "doesn't return absolute paths !\n"));
1085 status = NT_STATUS_OBJECT_NAME_INVALID;
1089 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1090 priv_paths->parent_name.base_name,
1093 /* Now check the stat value is the same. */
1094 smb_fname_cwd = synthetic_smb_fname(talloc_tos(), ".", NULL, NULL, 0);
1095 if (smb_fname_cwd == NULL) {
1096 status = NT_STATUS_NO_MEMORY;
1100 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1101 status = map_nt_error_from_unix(errno);
1105 /* Ensure we're pointing at the same place. */
1106 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1107 DEBUG(0,("check_reduced_name_with_privilege: "
1108 "device/inode/uid/gid on directory %s changed. "
1109 "Denying access !\n",
1110 priv_paths->parent_name.base_name));
1111 status = NT_STATUS_ACCESS_DENIED;
1115 /* Ensure we're below the connect path. */
1117 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1118 if (conn_rootdir == NULL) {
1119 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1121 status = NT_STATUS_ACCESS_DENIED;
1125 rootdir_len = strlen(conn_rootdir);
1128 * In the case of rootdir_len == 1, we know that conn_rootdir is
1129 * "/", and we also know that resolved_name starts with a slash.
1130 * So, in this corner case, resolved_name is automatically a
1131 * sub-directory of the conn_rootdir. Thus we can skip the string
1132 * comparison and the next character checks (which are even
1133 * wrong in this case).
1135 if (rootdir_len != 1) {
1138 matched = (strncmp(conn_rootdir, resolved_name,
1141 if (!matched || (resolved_name[rootdir_len] != '/' &&
1142 resolved_name[rootdir_len] != '\0')) {
1143 DEBUG(2, ("check_reduced_name_with_privilege: Bad "
1144 "access attempt: %s is a symlink outside the "
1147 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1148 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1149 status = NT_STATUS_ACCESS_DENIED;
1154 /* Now ensure that the last component either doesn't
1155 exist, or is *NOT* a symlink. */
1157 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1159 /* Errno must be ENOENT for this be ok. */
1160 if (errno != ENOENT) {
1161 status = map_nt_error_from_unix(errno);
1162 DEBUG(2, ("check_reduced_name_with_privilege: "
1163 "LSTAT on %s failed with %s\n",
1164 priv_paths->file_name.base_name,
1165 nt_errstr(status)));
1170 if (VALID_STAT(priv_paths->file_name.st) &&
1171 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1172 DEBUG(2, ("check_reduced_name_with_privilege: "
1173 "Last component %s is a symlink. Denying"
1175 priv_paths->file_name.base_name));
1176 status = NT_STATUS_ACCESS_DENIED;
1180 smbreq->priv_paths = priv_paths;
1181 status = NT_STATUS_OK;
1185 if (saved_dir_fname != NULL) {
1186 vfs_ChDir(conn, saved_dir_fname);
1187 TALLOC_FREE(saved_dir_fname);
1189 SAFE_FREE(resolved_name);
1190 if (!NT_STATUS_IS_OK(status)) {
1191 TALLOC_FREE(priv_paths);
1193 TALLOC_FREE(dir_name);
1197 /*******************************************************************
1198 Reduce a file name, removing .. elements and checking that
1199 it is below dir in the heirachy. This uses realpath.
1201 If cwd_name == NULL then fname is a client given path relative
1202 to the root path of the share.
1204 If cwd_name != NULL then fname is a client given path relative
1205 to cwd_name. cwd_name is relative to the root path of the share.
1206 ********************************************************************/
1208 NTSTATUS check_reduced_name(connection_struct *conn,
1209 const char *cwd_name,
1212 char *resolved_name = NULL;
1213 char *new_fname = NULL;
1214 bool allow_symlinks = true;
1215 bool allow_widelinks = false;
1217 DBG_DEBUG("check_reduced_name [%s] [%s]\n", fname, conn->connectpath);
1219 resolved_name = SMB_VFS_REALPATH(conn,fname);
1221 if (!resolved_name) {
1224 DEBUG(3,("check_reduced_name: Component not a "
1225 "directory in getting realpath for "
1227 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1230 TALLOC_CTX *ctx = talloc_tos();
1231 char *dir_name = NULL;
1232 const char *last_component = NULL;
1233 char *new_name = NULL;
1236 /* Last component didn't exist.
1237 Remove it and try and canonicalise
1238 the directory name. */
1239 if (!parent_dirname(ctx, fname,
1242 return NT_STATUS_NO_MEMORY;
1245 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1246 if (!resolved_name) {
1247 NTSTATUS status = map_nt_error_from_unix(errno);
1249 if (errno == ENOENT || errno == ENOTDIR) {
1250 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1253 DEBUG(3,("check_reduce_name: "
1254 "couldn't get realpath for "
1257 nt_errstr(status)));
1260 ret = asprintf(&new_name, "%s/%s",
1261 resolved_name, last_component);
1262 SAFE_FREE(resolved_name);
1264 return NT_STATUS_NO_MEMORY;
1266 resolved_name = new_name;
1270 DEBUG(3,("check_reduced_name: couldn't get "
1271 "realpath for %s\n", fname));
1272 return map_nt_error_from_unix(errno);
1276 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1279 if (*resolved_name != '/') {
1280 DEBUG(0,("check_reduced_name: realpath doesn't return "
1281 "absolute paths !\n"));
1282 SAFE_FREE(resolved_name);
1283 return NT_STATUS_OBJECT_NAME_INVALID;
1286 allow_widelinks = lp_widelinks(SNUM(conn));
1287 allow_symlinks = lp_follow_symlinks(SNUM(conn));
1289 /* Common widelinks and symlinks checks. */
1290 if (!allow_widelinks || !allow_symlinks) {
1291 const char *conn_rootdir;
1294 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1295 if (conn_rootdir == NULL) {
1296 DEBUG(2, ("check_reduced_name: Could not get "
1298 SAFE_FREE(resolved_name);
1299 return NT_STATUS_ACCESS_DENIED;
1302 rootdir_len = strlen(conn_rootdir);
1305 * In the case of rootdir_len == 1, we know that
1306 * conn_rootdir is "/", and we also know that
1307 * resolved_name starts with a slash. So, in this
1308 * corner case, resolved_name is automatically a
1309 * sub-directory of the conn_rootdir. Thus we can skip
1310 * the string comparison and the next character checks
1311 * (which are even wrong in this case).
1313 if (rootdir_len != 1) {
1316 matched = (strncmp(conn_rootdir, resolved_name,
1318 if (!matched || (resolved_name[rootdir_len] != '/' &&
1319 resolved_name[rootdir_len] != '\0')) {
1320 DEBUG(2, ("check_reduced_name: Bad access "
1321 "attempt: %s is a symlink outside the "
1322 "share path\n", fname));
1323 DEBUGADD(2, ("conn_rootdir =%s\n",
1325 DEBUGADD(2, ("resolved_name=%s\n",
1327 SAFE_FREE(resolved_name);
1328 return NT_STATUS_ACCESS_DENIED;
1332 /* Extra checks if all symlinks are disallowed. */
1333 if (!allow_symlinks) {
1334 /* fname can't have changed in resolved_path. */
1335 const char *p = &resolved_name[rootdir_len];
1338 * UNIX filesystem semantics, names consisting
1339 * only of "." or ".." CANNOT be symlinks.
1341 if (ISDOT(fname) || ISDOTDOT(fname)) {
1346 DEBUG(2, ("check_reduced_name: logic error (%c) "
1347 "in resolved_name: %s\n",
1350 SAFE_FREE(resolved_name);
1351 return NT_STATUS_ACCESS_DENIED;
1357 * If cwd_name is present and not ".",
1358 * then fname is relative to that, not
1359 * the root of the share. Make sure the
1360 * path we check is the one the client
1361 * sent (cwd_name+fname).
1363 if (cwd_name != NULL && !ISDOT(cwd_name)) {
1364 new_fname = talloc_asprintf(talloc_tos(),
1368 if (new_fname == NULL) {
1369 SAFE_FREE(resolved_name);
1370 return NT_STATUS_NO_MEMORY;
1375 if (strcmp(fname, p)!=0) {
1376 DEBUG(2, ("check_reduced_name: Bad access "
1377 "attempt: %s is a symlink to %s\n",
1379 SAFE_FREE(resolved_name);
1380 TALLOC_FREE(new_fname);
1381 return NT_STATUS_ACCESS_DENIED;
1388 DBG_INFO("%s reduced to %s\n", fname, resolved_name);
1389 SAFE_FREE(resolved_name);
1390 TALLOC_FREE(new_fname);
1391 return NT_STATUS_OK;
1395 * XXX: This is temporary and there should be no callers of this once
1396 * smb_filename is plumbed through all path based operations.
1398 * Called when we know stream name parsing has already been done.
1400 int vfs_stat_smb_basename(struct connection_struct *conn,
1401 const struct smb_filename *smb_fname_in,
1402 SMB_STRUCT_STAT *psbuf)
1404 struct smb_filename smb_fname = {
1405 .base_name = discard_const_p(char, smb_fname_in->base_name),
1406 .flags = smb_fname_in->flags
1410 if (smb_fname.flags & SMB_FILENAME_POSIX_PATH) {
1411 ret = SMB_VFS_LSTAT(conn, &smb_fname);
1413 ret = SMB_VFS_STAT(conn, &smb_fname);
1417 *psbuf = smb_fname.st;
1423 * Ensure LSTAT is called for POSIX paths.
1426 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1430 if(fsp->fh->fd == -1) {
1431 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1432 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1434 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1437 return map_nt_error_from_unix(errno);
1440 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1441 return map_nt_error_from_unix(errno);
1444 return NT_STATUS_OK;
1448 * Initialize num_streams and streams, then call VFS op streaminfo
1450 NTSTATUS vfs_streaminfo(connection_struct *conn,
1451 struct files_struct *fsp,
1452 const struct smb_filename *smb_fname,
1453 TALLOC_CTX *mem_ctx,
1454 unsigned int *num_streams,
1455 struct stream_struct **streams)
1459 return SMB_VFS_STREAMINFO(conn,
1468 generate a file_id from a stat structure
1470 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1472 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1475 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1476 const char *service, const char *user)
1479 return handle->fns->connect_fn(handle, service, user);
1482 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1484 VFS_FIND(disconnect);
1485 handle->fns->disconnect_fn(handle);
1488 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1489 const struct smb_filename *smb_fname,
1494 VFS_FIND(disk_free);
1495 return handle->fns->disk_free_fn(handle, smb_fname,
1496 bsize, dfree, dsize);
1499 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1500 const struct smb_filename *smb_fname,
1501 enum SMB_QUOTA_TYPE qtype,
1505 VFS_FIND(get_quota);
1506 return handle->fns->get_quota_fn(handle, smb_fname, qtype, id, qt);
1509 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1510 enum SMB_QUOTA_TYPE qtype, unid_t id,
1513 VFS_FIND(set_quota);
1514 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1517 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1518 struct files_struct *fsp,
1519 struct shadow_copy_data *shadow_copy_data,
1522 VFS_FIND(get_shadow_copy_data);
1523 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1527 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle,
1528 const struct smb_filename *smb_fname,
1529 struct vfs_statvfs_struct *statbuf)
1532 return handle->fns->statvfs_fn(handle, smb_fname, statbuf);
1535 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1536 enum timestamp_set_resolution *p_ts_res)
1538 VFS_FIND(fs_capabilities);
1539 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1542 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1543 struct dfs_GetDFSReferral *r)
1545 VFS_FIND(get_dfs_referrals);
1546 return handle->fns->get_dfs_referrals_fn(handle, r);
1549 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1550 const struct smb_filename *smb_fname,
1552 uint32_t attributes)
1555 return handle->fns->opendir_fn(handle, smb_fname, mask, attributes);
1558 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1559 struct files_struct *fsp,
1561 uint32_t attributes)
1563 VFS_FIND(fdopendir);
1564 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1567 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1569 SMB_STRUCT_STAT *sbuf)
1572 return handle->fns->readdir_fn(handle, dirp, sbuf);
1575 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1576 DIR *dirp, long offset)
1579 handle->fns->seekdir_fn(handle, dirp, offset);
1582 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1586 return handle->fns->telldir_fn(handle, dirp);
1589 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1592 VFS_FIND(rewind_dir);
1593 handle->fns->rewind_dir_fn(handle, dirp);
1596 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle,
1597 const struct smb_filename *smb_fname,
1601 return handle->fns->mkdir_fn(handle, smb_fname, mode);
1604 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle,
1605 const struct smb_filename *smb_fname)
1608 return handle->fns->rmdir_fn(handle, smb_fname);
1611 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1615 return handle->fns->closedir_fn(handle, dir);
1618 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1621 VFS_FIND(init_search_op);
1622 handle->fns->init_search_op_fn(handle, dirp);
1625 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1626 struct smb_filename *smb_fname, struct files_struct *fsp,
1627 int flags, mode_t mode)
1630 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1633 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1634 struct smb_request *req,
1635 uint16_t root_dir_fid,
1636 struct smb_filename *smb_fname,
1637 uint32_t access_mask,
1638 uint32_t share_access,
1639 uint32_t create_disposition,
1640 uint32_t create_options,
1641 uint32_t file_attributes,
1642 uint32_t oplock_request,
1643 struct smb2_lease *lease,
1644 uint64_t allocation_size,
1645 uint32_t private_flags,
1646 struct security_descriptor *sd,
1647 struct ea_list *ea_list,
1648 files_struct **result,
1650 const struct smb2_create_blobs *in_context_blobs,
1651 struct smb2_create_blobs *out_context_blobs)
1653 VFS_FIND(create_file);
1654 return handle->fns->create_file_fn(
1655 handle, req, root_dir_fid, smb_fname, access_mask,
1656 share_access, create_disposition, create_options,
1657 file_attributes, oplock_request, lease, allocation_size,
1658 private_flags, sd, ea_list,
1659 result, pinfo, in_context_blobs, out_context_blobs);
1662 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1663 struct files_struct *fsp)
1666 return handle->fns->close_fn(handle, fsp);
1669 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1670 struct files_struct *fsp, void *data, size_t n)
1673 return handle->fns->read_fn(handle, fsp, data, n);
1676 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1677 struct files_struct *fsp, void *data, size_t n,
1681 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1684 struct smb_vfs_call_pread_state {
1685 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1687 struct vfs_aio_state vfs_aio_state;
1690 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1692 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1693 TALLOC_CTX *mem_ctx,
1694 struct tevent_context *ev,
1695 struct files_struct *fsp,
1697 size_t n, off_t offset)
1699 struct tevent_req *req, *subreq;
1700 struct smb_vfs_call_pread_state *state;
1702 req = tevent_req_create(mem_ctx, &state,
1703 struct smb_vfs_call_pread_state);
1707 VFS_FIND(pread_send);
1708 state->recv_fn = handle->fns->pread_recv_fn;
1710 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1712 if (tevent_req_nomem(subreq, req)) {
1713 return tevent_req_post(req, ev);
1715 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1719 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1721 struct tevent_req *req = tevent_req_callback_data(
1722 subreq, struct tevent_req);
1723 struct smb_vfs_call_pread_state *state = tevent_req_data(
1724 req, struct smb_vfs_call_pread_state);
1726 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1727 TALLOC_FREE(subreq);
1728 if (state->retval == -1) {
1729 tevent_req_error(req, state->vfs_aio_state.error);
1732 tevent_req_done(req);
1735 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req,
1736 struct vfs_aio_state *vfs_aio_state)
1738 struct smb_vfs_call_pread_state *state = tevent_req_data(
1739 req, struct smb_vfs_call_pread_state);
1741 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1744 *vfs_aio_state = state->vfs_aio_state;
1745 return state->retval;
1748 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1749 struct files_struct *fsp, const void *data,
1753 return handle->fns->write_fn(handle, fsp, data, n);
1756 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1757 struct files_struct *fsp, const void *data,
1758 size_t n, off_t offset)
1761 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1764 struct smb_vfs_call_pwrite_state {
1765 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1767 struct vfs_aio_state vfs_aio_state;
1770 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1772 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1773 TALLOC_CTX *mem_ctx,
1774 struct tevent_context *ev,
1775 struct files_struct *fsp,
1777 size_t n, off_t offset)
1779 struct tevent_req *req, *subreq;
1780 struct smb_vfs_call_pwrite_state *state;
1782 req = tevent_req_create(mem_ctx, &state,
1783 struct smb_vfs_call_pwrite_state);
1787 VFS_FIND(pwrite_send);
1788 state->recv_fn = handle->fns->pwrite_recv_fn;
1790 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1792 if (tevent_req_nomem(subreq, req)) {
1793 return tevent_req_post(req, ev);
1795 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1799 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1801 struct tevent_req *req = tevent_req_callback_data(
1802 subreq, struct tevent_req);
1803 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1804 req, struct smb_vfs_call_pwrite_state);
1806 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1807 TALLOC_FREE(subreq);
1808 if (state->retval == -1) {
1809 tevent_req_error(req, state->vfs_aio_state.error);
1812 tevent_req_done(req);
1815 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req,
1816 struct vfs_aio_state *vfs_aio_state)
1818 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1819 req, struct smb_vfs_call_pwrite_state);
1821 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1824 *vfs_aio_state = state->vfs_aio_state;
1825 return state->retval;
1828 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1829 struct files_struct *fsp, off_t offset,
1833 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1836 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1837 files_struct *fromfsp, const DATA_BLOB *header,
1838 off_t offset, size_t count)
1841 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1845 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1846 files_struct *tofsp, off_t offset,
1850 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1853 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1854 const struct smb_filename *smb_fname_src,
1855 const struct smb_filename *smb_fname_dst)
1858 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1861 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1862 struct files_struct *fsp)
1865 return handle->fns->fsync_fn(handle, fsp);
1868 struct smb_vfs_call_fsync_state {
1869 int (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1871 struct vfs_aio_state vfs_aio_state;
1874 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1876 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1877 TALLOC_CTX *mem_ctx,
1878 struct tevent_context *ev,
1879 struct files_struct *fsp)
1881 struct tevent_req *req, *subreq;
1882 struct smb_vfs_call_fsync_state *state;
1884 req = tevent_req_create(mem_ctx, &state,
1885 struct smb_vfs_call_fsync_state);
1889 VFS_FIND(fsync_send);
1890 state->recv_fn = handle->fns->fsync_recv_fn;
1892 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1893 if (tevent_req_nomem(subreq, req)) {
1894 return tevent_req_post(req, ev);
1896 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1900 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1902 struct tevent_req *req = tevent_req_callback_data(
1903 subreq, struct tevent_req);
1904 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1905 req, struct smb_vfs_call_fsync_state);
1907 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1908 TALLOC_FREE(subreq);
1909 if (state->retval == -1) {
1910 tevent_req_error(req, state->vfs_aio_state.error);
1913 tevent_req_done(req);
1916 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state)
1918 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1919 req, struct smb_vfs_call_fsync_state);
1921 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1924 *vfs_aio_state = state->vfs_aio_state;
1925 return state->retval;
1929 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1930 struct smb_filename *smb_fname)
1933 return handle->fns->stat_fn(handle, smb_fname);
1936 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1937 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1940 return handle->fns->fstat_fn(handle, fsp, sbuf);
1943 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1944 struct smb_filename *smb_filename)
1947 return handle->fns->lstat_fn(handle, smb_filename);
1950 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1951 struct files_struct *fsp,
1952 const SMB_STRUCT_STAT *sbuf)
1954 VFS_FIND(get_alloc_size);
1955 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1958 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1959 const struct smb_filename *smb_fname)
1962 return handle->fns->unlink_fn(handle, smb_fname);
1965 int smb_vfs_call_chmod(struct vfs_handle_struct *handle,
1966 const struct smb_filename *smb_fname,
1970 return handle->fns->chmod_fn(handle, smb_fname, mode);
1973 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1974 struct files_struct *fsp, mode_t mode)
1977 return handle->fns->fchmod_fn(handle, fsp, mode);
1980 int smb_vfs_call_chown(struct vfs_handle_struct *handle,
1981 const struct smb_filename *smb_fname,
1986 return handle->fns->chown_fn(handle, smb_fname, uid, gid);
1989 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1990 struct files_struct *fsp, uid_t uid, gid_t gid)
1993 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1996 int smb_vfs_call_lchown(struct vfs_handle_struct *handle,
1997 const struct smb_filename *smb_fname,
2002 return handle->fns->lchown_fn(handle, smb_fname, uid, gid);
2005 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
2008 bool as_root = false;
2011 if (fsp->fh->fd != -1) {
2013 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
2015 return NT_STATUS_OK;
2017 if (ret == -1 && errno != ENOSYS) {
2018 return map_nt_error_from_unix(errno);
2022 as_root = (geteuid() == 0);
2026 * We are being asked to chown as root. Make
2027 * sure we chdir() into the path to pin it,
2028 * and always act using lchown to ensure we
2029 * don't deref any symbolic links.
2031 char *parent_dir = NULL;
2032 const char *final_component = NULL;
2033 struct smb_filename *local_smb_fname = NULL;
2034 struct smb_filename parent_dir_fname = {0};
2035 struct smb_filename *saved_dir_fname = NULL;
2037 saved_dir_fname = vfs_GetWd(talloc_tos(),fsp->conn);
2038 if (!saved_dir_fname) {
2039 status = map_nt_error_from_unix(errno);
2040 DEBUG(0,("vfs_chown_fsp: failed to get "
2041 "current working directory. Error was %s\n",
2046 if (!parent_dirname(talloc_tos(),
2047 fsp->fsp_name->base_name,
2049 &final_component)) {
2050 return NT_STATUS_NO_MEMORY;
2053 parent_dir_fname = (struct smb_filename) {
2054 .base_name = parent_dir,
2055 .flags = fsp->fsp_name->flags
2058 /* cd into the parent dir to pin it. */
2059 ret = vfs_ChDir(fsp->conn, &parent_dir_fname);
2061 return map_nt_error_from_unix(errno);
2064 local_smb_fname = synthetic_smb_fname(talloc_tos(),
2068 fsp->fsp_name->flags);
2069 if (local_smb_fname == NULL) {
2070 status = NT_STATUS_NO_MEMORY;
2074 /* Must use lstat here. */
2075 ret = SMB_VFS_LSTAT(fsp->conn, local_smb_fname);
2077 status = map_nt_error_from_unix(errno);
2081 /* Ensure it matches the fsp stat. */
2082 if (!check_same_stat(&local_smb_fname->st,
2083 &fsp->fsp_name->st)) {
2084 status = NT_STATUS_ACCESS_DENIED;
2088 ret = SMB_VFS_LCHOWN(fsp->conn,
2093 status = NT_STATUS_OK;
2095 status = map_nt_error_from_unix(errno);
2100 vfs_ChDir(fsp->conn, saved_dir_fname);
2101 TALLOC_FREE(local_smb_fname);
2102 TALLOC_FREE(saved_dir_fname);
2103 TALLOC_FREE(parent_dir);
2108 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
2109 ret = SMB_VFS_LCHOWN(fsp->conn,
2113 ret = SMB_VFS_CHOWN(fsp->conn,
2119 status = NT_STATUS_OK;
2121 status = map_nt_error_from_unix(errno);
2126 int smb_vfs_call_chdir(struct vfs_handle_struct *handle,
2127 const struct smb_filename *smb_fname)
2130 return handle->fns->chdir_fn(handle, smb_fname);
2133 struct smb_filename *smb_vfs_call_getwd(struct vfs_handle_struct *handle,
2137 return handle->fns->getwd_fn(handle, ctx);
2140 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
2141 const struct smb_filename *smb_fname,
2142 struct smb_file_time *ft)
2145 return handle->fns->ntimes_fn(handle, smb_fname, ft);
2148 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2149 struct files_struct *fsp, off_t offset)
2151 VFS_FIND(ftruncate);
2152 return handle->fns->ftruncate_fn(handle, fsp, offset);
2155 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2156 struct files_struct *fsp,
2161 VFS_FIND(fallocate);
2162 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2165 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2166 struct files_struct *fsp, uint32_t share_mode,
2167 uint32_t access_mask)
2169 VFS_FIND(kernel_flock);
2170 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2174 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2175 struct files_struct *fsp, int leasetype)
2177 VFS_FIND(linux_setlease);
2178 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2181 int smb_vfs_call_symlink(struct vfs_handle_struct *handle,
2182 const char *link_target,
2183 const struct smb_filename *new_smb_fname)
2186 return handle->fns->symlink_fn(handle, link_target, new_smb_fname);
2189 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2190 const struct smb_filename *smb_fname,
2195 return handle->fns->readlink_fn(handle, smb_fname, buf, bufsiz);
2198 int smb_vfs_call_link(struct vfs_handle_struct *handle,
2199 const struct smb_filename *old_smb_fname,
2200 const struct smb_filename *new_smb_fname)
2203 return handle->fns->link_fn(handle, old_smb_fname, new_smb_fname);
2206 int smb_vfs_call_mknod(struct vfs_handle_struct *handle,
2207 const struct smb_filename *smb_fname,
2212 return handle->fns->mknod_fn(handle, smb_fname, mode, dev);
2215 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
2218 return handle->fns->realpath_fn(handle, path);
2221 int smb_vfs_call_chflags(struct vfs_handle_struct *handle,
2222 const struct smb_filename *smb_fname,
2226 return handle->fns->chflags_fn(handle, smb_fname, flags);
2229 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2230 const SMB_STRUCT_STAT *sbuf)
2232 VFS_FIND(file_id_create);
2233 return handle->fns->file_id_create_fn(handle, sbuf);
2236 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2237 struct files_struct *fsp,
2238 const struct smb_filename *smb_fname,
2239 TALLOC_CTX *mem_ctx,
2240 unsigned int *num_streams,
2241 struct stream_struct **streams)
2243 VFS_FIND(streaminfo);
2244 return handle->fns->streaminfo_fn(handle, fsp, smb_fname, mem_ctx,
2245 num_streams, streams);
2248 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2249 const char *path, const char *name,
2250 TALLOC_CTX *mem_ctx, char **found_name)
2252 VFS_FIND(get_real_filename);
2253 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2257 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2258 const char *filename)
2260 VFS_FIND(connectpath);
2261 return handle->fns->connectpath_fn(handle, filename);
2264 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2265 struct files_struct *fsp,
2266 struct lock_struct *plock)
2268 VFS_FIND(strict_lock);
2269 return handle->fns->strict_lock_fn(handle, fsp, plock);
2272 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2273 struct files_struct *fsp,
2274 struct lock_struct *plock)
2276 VFS_FIND(strict_unlock);
2277 handle->fns->strict_unlock_fn(handle, fsp, plock);
2280 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2282 enum vfs_translate_direction direction,
2283 TALLOC_CTX *mem_ctx,
2286 VFS_FIND(translate_name);
2287 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2291 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2292 struct files_struct *fsp,
2296 const uint8_t *in_data,
2299 uint32_t max_out_len,
2303 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2304 in_data, in_len, out_data, max_out_len,
2308 NTSTATUS smb_vfs_call_get_dos_attributes(struct vfs_handle_struct *handle,
2309 struct smb_filename *smb_fname,
2312 VFS_FIND(get_dos_attributes);
2313 return handle->fns->get_dos_attributes_fn(handle, smb_fname, dosmode);
2316 NTSTATUS smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct *handle,
2317 struct files_struct *fsp,
2320 VFS_FIND(fget_dos_attributes);
2321 return handle->fns->fget_dos_attributes_fn(handle, fsp, dosmode);
2324 NTSTATUS smb_vfs_call_set_dos_attributes(struct vfs_handle_struct *handle,
2325 const struct smb_filename *smb_fname,
2328 VFS_FIND(set_dos_attributes);
2329 return handle->fns->set_dos_attributes_fn(handle, smb_fname, dosmode);
2332 NTSTATUS smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct *handle,
2333 struct files_struct *fsp,
2336 VFS_FIND(set_dos_attributes);
2337 return handle->fns->fset_dos_attributes_fn(handle, fsp, dosmode);
2340 struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle,
2341 TALLOC_CTX *mem_ctx,
2342 struct tevent_context *ev,
2343 struct files_struct *src_fsp,
2345 struct files_struct *dest_fsp,
2350 VFS_FIND(copy_chunk_send);
2351 return handle->fns->copy_chunk_send_fn(handle, mem_ctx, ev, src_fsp,
2352 src_off, dest_fsp, dest_off, num,
2356 NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,
2357 struct tevent_req *req,
2360 VFS_FIND(copy_chunk_recv);
2361 return handle->fns->copy_chunk_recv_fn(handle, req, copied);
2364 NTSTATUS smb_vfs_call_get_compression(vfs_handle_struct *handle,
2365 TALLOC_CTX *mem_ctx,
2366 struct files_struct *fsp,
2367 struct smb_filename *smb_fname,
2368 uint16_t *_compression_fmt)
2370 VFS_FIND(get_compression);
2371 return handle->fns->get_compression_fn(handle, mem_ctx, fsp, smb_fname,
2375 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2376 TALLOC_CTX *mem_ctx,
2377 struct files_struct *fsp,
2378 uint16_t compression_fmt)
2380 VFS_FIND(set_compression);
2381 return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2385 NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
2386 TALLOC_CTX *mem_ctx,
2387 const char *service_path,
2390 VFS_FIND(snap_check_path);
2391 return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path,
2395 NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle,
2396 TALLOC_CTX *mem_ctx,
2397 const char *base_volume,
2403 VFS_FIND(snap_create);
2404 return handle->fns->snap_create_fn(handle, mem_ctx, base_volume, tstamp,
2405 rw, base_path, snap_path);
2408 NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle,
2409 TALLOC_CTX *mem_ctx,
2413 VFS_FIND(snap_delete);
2414 return handle->fns->snap_delete_fn(handle, mem_ctx, base_path,
2418 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2419 struct files_struct *fsp,
2420 uint32_t security_info,
2421 TALLOC_CTX *mem_ctx,
2422 struct security_descriptor **ppdesc)
2424 VFS_FIND(fget_nt_acl);
2425 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2429 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2430 const struct smb_filename *smb_fname,
2431 uint32_t security_info,
2432 TALLOC_CTX *mem_ctx,
2433 struct security_descriptor **ppdesc)
2435 VFS_FIND(get_nt_acl);
2436 return handle->fns->get_nt_acl_fn(handle,
2443 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2444 struct files_struct *fsp,
2445 uint32_t security_info_sent,
2446 const struct security_descriptor *psd)
2448 VFS_FIND(fset_nt_acl);
2449 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2453 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2454 struct smb_filename *file,
2455 struct security_acl *sacl,
2456 uint32_t access_requested,
2457 uint32_t access_denied)
2459 VFS_FIND(audit_file);
2460 return handle->fns->audit_file_fn(handle,
2467 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle,
2468 const struct smb_filename *smb_fname,
2471 VFS_FIND(chmod_acl);
2472 return handle->fns->chmod_acl_fn(handle, smb_fname, mode);
2475 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2476 struct files_struct *fsp, mode_t mode)
2478 VFS_FIND(fchmod_acl);
2479 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2482 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2483 const struct smb_filename *smb_fname,
2484 SMB_ACL_TYPE_T type,
2485 TALLOC_CTX *mem_ctx)
2487 VFS_FIND(sys_acl_get_file);
2488 return handle->fns->sys_acl_get_file_fn(handle, smb_fname, type, mem_ctx);
2491 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2492 struct files_struct *fsp,
2493 TALLOC_CTX *mem_ctx)
2495 VFS_FIND(sys_acl_get_fd);
2496 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2499 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2500 const struct smb_filename *smb_fname,
2501 TALLOC_CTX *mem_ctx,
2502 char **blob_description,
2505 VFS_FIND(sys_acl_blob_get_file);
2506 return handle->fns->sys_acl_blob_get_file_fn(handle, smb_fname,
2507 mem_ctx, blob_description, blob);
2510 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2511 struct files_struct *fsp,
2512 TALLOC_CTX *mem_ctx,
2513 char **blob_description,
2516 VFS_FIND(sys_acl_blob_get_fd);
2517 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2520 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2521 const struct smb_filename *smb_fname,
2522 SMB_ACL_TYPE_T acltype,
2525 VFS_FIND(sys_acl_set_file);
2526 return handle->fns->sys_acl_set_file_fn(handle, smb_fname,
2530 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2531 struct files_struct *fsp, SMB_ACL_T theacl)
2533 VFS_FIND(sys_acl_set_fd);
2534 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2537 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2538 const struct smb_filename *smb_fname)
2540 VFS_FIND(sys_acl_delete_def_file);
2541 return handle->fns->sys_acl_delete_def_file_fn(handle, smb_fname);
2544 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2545 const struct smb_filename *smb_fname,
2551 return handle->fns->getxattr_fn(handle, smb_fname, name, value, size);
2554 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2555 struct files_struct *fsp, const char *name,
2556 void *value, size_t size)
2558 VFS_FIND(fgetxattr);
2559 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2562 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2563 const struct smb_filename *smb_fname,
2567 VFS_FIND(listxattr);
2568 return handle->fns->listxattr_fn(handle, smb_fname, list, size);
2571 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2572 struct files_struct *fsp, char *list,
2575 VFS_FIND(flistxattr);
2576 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2579 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2580 const struct smb_filename *smb_fname,
2583 VFS_FIND(removexattr);
2584 return handle->fns->removexattr_fn(handle, smb_fname, name);
2587 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2588 struct files_struct *fsp, const char *name)
2590 VFS_FIND(fremovexattr);
2591 return handle->fns->fremovexattr_fn(handle, fsp, name);
2594 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle,
2595 const struct smb_filename *smb_fname,
2602 return handle->fns->setxattr_fn(handle, smb_fname,
2603 name, value, size, flags);
2606 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2607 struct files_struct *fsp, const char *name,
2608 const void *value, size_t size, int flags)
2610 VFS_FIND(fsetxattr);
2611 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2614 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2615 struct files_struct *fsp)
2617 VFS_FIND(aio_force);
2618 return handle->fns->aio_force_fn(handle, fsp);
2621 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2622 struct files_struct *fsp,
2623 TALLOC_CTX *mem_ctx,
2626 VFS_FIND(durable_cookie);
2627 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2630 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2631 struct files_struct *fsp,
2632 const DATA_BLOB old_cookie,
2633 TALLOC_CTX *mem_ctx,
2634 DATA_BLOB *new_cookie)
2636 VFS_FIND(durable_disconnect);
2637 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2638 mem_ctx, new_cookie);
2641 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2642 struct smb_request *smb1req,
2643 struct smbXsrv_open *op,
2644 const DATA_BLOB old_cookie,
2645 TALLOC_CTX *mem_ctx,
2646 struct files_struct **fsp,
2647 DATA_BLOB *new_cookie)
2649 VFS_FIND(durable_reconnect);
2650 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2651 old_cookie, mem_ctx, fsp,
2655 NTSTATUS smb_vfs_call_readdir_attr(struct vfs_handle_struct *handle,
2656 const struct smb_filename *fname,
2657 TALLOC_CTX *mem_ctx,
2658 struct readdir_attr_data **attr_data)
2660 VFS_FIND(readdir_attr);
2661 return handle->fns->readdir_attr_fn(handle, fname, mem_ctx, attr_data);