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 Write data to a fd on the vfs.
403 ****************************************************************************/
405 ssize_t vfs_write_data(struct smb_request *req,
413 if (req && req->unread_bytes) {
414 int sockfd = req->xconn->transport.sock;
416 SMB_ASSERT(req->unread_bytes == N);
417 /* VFS_RECVFILE must drain the socket
418 * before returning. */
419 req->unread_bytes = 0;
420 /* Ensure the socket is blocking. */
421 old_flags = fcntl(sockfd, F_GETFL, 0);
422 if (set_blocking(sockfd, true) == -1) {
425 ret = SMB_VFS_RECVFILE(sockfd,
429 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
436 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
445 return (ssize_t)total;
448 ssize_t vfs_pwrite_data(struct smb_request *req,
457 if (req && req->unread_bytes) {
458 int sockfd = req->xconn->transport.sock;
459 SMB_ASSERT(req->unread_bytes == N);
460 /* VFS_RECVFILE must drain the socket
461 * before returning. */
462 req->unread_bytes = 0;
464 * Leave the socket non-blocking and
465 * use SMB_VFS_RECVFILE. If it returns
466 * EAGAIN || EWOULDBLOCK temporarily set
467 * the socket blocking and retry
471 ret = SMB_VFS_RECVFILE(sockfd,
475 if (ret == 0 || (ret == -1 &&
477 errno == EWOULDBLOCK))) {
479 /* Ensure the socket is blocking. */
480 old_flags = fcntl(sockfd, F_GETFL, 0);
481 if (set_blocking(sockfd, true) == -1) {
484 ret = SMB_VFS_RECVFILE(sockfd,
488 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
495 return (ssize_t)total;
497 /* Any other error case. */
503 return (ssize_t)total;
507 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
517 return (ssize_t)total;
519 /****************************************************************************
520 An allocate file space call using the vfs interface.
521 Allocates space for a file from a filedescriptor.
522 Returns 0 on success, -1 on failure.
523 ****************************************************************************/
525 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
528 connection_struct *conn = fsp->conn;
529 uint64_t space_avail;
530 uint64_t bsize,dfree,dsize;
534 * Actually try and commit the space on disk....
537 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
538 fsp_str_dbg(fsp), (double)len));
540 if (((off_t)len) < 0) {
541 DEBUG(0,("vfs_allocate_file_space: %s negative len "
542 "requested.\n", fsp_str_dbg(fsp)));
547 status = vfs_stat_fsp(fsp);
548 if (!NT_STATUS_IS_OK(status)) {
552 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
555 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
556 /* Shrink - use ftruncate. */
558 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
559 "size %.0f\n", fsp_str_dbg(fsp),
560 (double)fsp->fsp_name->st.st_ex_size));
562 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
564 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
565 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
566 set_filelen_write_cache(fsp, len);
569 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
574 /* Grow - we need to test if we have enough space. */
576 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
578 if (lp_strict_allocate(SNUM(fsp->conn))) {
579 /* See if we have a syscall that will allocate beyond
580 end-of-file without changing EOF. */
581 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_FL_KEEP_SIZE,
587 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
590 /* We changed the allocation size on disk, but not
591 EOF - exactly as required. We're done ! */
595 if (ret == -1 && errno == ENOSPC) {
599 len -= fsp->fsp_name->st.st_ex_size;
600 len /= 1024; /* Len is now number of 1k blocks needed. */
602 get_dfree_info(conn, fsp->fsp_name, &bsize, &dfree, &dsize);
603 if (space_avail == (uint64_t)-1) {
607 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
608 "needed blocks = %.0f, space avail = %.0f\n",
609 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
610 (double)space_avail));
612 if (len > space_avail) {
620 /****************************************************************************
621 A vfs set_filelen call.
622 set the length of a file from a filedescriptor.
623 Returns 0 on success, -1 on failure.
624 ****************************************************************************/
626 int vfs_set_filelen(files_struct *fsp, off_t len)
630 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
632 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
633 fsp_str_dbg(fsp), (double)len));
634 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
635 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
636 set_filelen_write_cache(fsp, len);
637 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
638 FILE_NOTIFY_CHANGE_SIZE
639 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
640 fsp->fsp_name->base_name);
643 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
648 /****************************************************************************
649 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
650 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
651 as this is also called from the default SMB_VFS_FTRUNCATE code.
652 Always extends the file size.
653 Returns 0 on success, -1 on failure.
654 ****************************************************************************/
656 #define SPARSE_BUF_WRITE_SIZE (32*1024)
658 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
664 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
671 while (total < len) {
672 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
674 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
675 if (pwrite_ret == -1) {
676 int saved_errno = errno;
677 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
678 "%s failed with error %s\n",
679 fsp_str_dbg(fsp), strerror(saved_errno)));
689 /****************************************************************************
690 A vfs fill sparse call.
691 Writes zeros from the end of file to len, if len is greater than EOF.
692 Used only by strict_sync.
693 Returns 0 on success, -1 on failure.
694 ****************************************************************************/
696 int vfs_fill_sparse(files_struct *fsp, off_t len)
703 status = vfs_stat_fsp(fsp);
704 if (!NT_STATUS_IS_OK(status)) {
708 if (len <= fsp->fsp_name->st.st_ex_size) {
713 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
718 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
719 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
720 (double)fsp->fsp_name->st.st_ex_size, (double)len,
721 (double)(len - fsp->fsp_name->st.st_ex_size)));
723 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
725 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
727 offset = fsp->fsp_name->st.st_ex_size;
728 num_to_write = len - fsp->fsp_name->st.st_ex_size;
730 /* Only do this on non-stream file handles. */
731 if (fsp->base_fsp == NULL) {
732 /* for allocation try fallocate first. This can fail on some
733 * platforms e.g. when the filesystem doesn't support it and no
734 * emulation is being done by the libc (like on AIX with JFS1). In that
735 * case we do our own emulation. fallocate implementations can
736 * return ENOTSUP or EINVAL in cases like that. */
737 ret = SMB_VFS_FALLOCATE(fsp, 0, offset, num_to_write);
738 if (ret == -1 && errno == ENOSPC) {
744 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
745 "error %d. Falling back to slow manual allocation\n", ret));
748 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
753 set_filelen_write_cache(fsp, len);
756 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
760 /****************************************************************************
761 Transfer some data (n bytes) between two file_struct's.
762 ****************************************************************************/
764 static ssize_t vfs_pread_fn(void *file, void *buf, size_t len, off_t offset)
766 struct files_struct *fsp = (struct files_struct *)file;
768 return SMB_VFS_PREAD(fsp, buf, len, offset);
771 static ssize_t vfs_pwrite_fn(void *file, const void *buf, size_t len, off_t offset)
773 struct files_struct *fsp = (struct files_struct *)file;
775 return SMB_VFS_PWRITE(fsp, buf, len, offset);
778 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
780 return transfer_file_internal((void *)in, (void *)out, n,
781 vfs_pread_fn, vfs_pwrite_fn);
784 /*******************************************************************
785 A vfs_readdir wrapper which just returns the file name.
786 ********************************************************************/
788 const char *vfs_readdirname(connection_struct *conn, void *p,
789 SMB_STRUCT_STAT *sbuf, char **talloced)
791 struct dirent *ptr= NULL;
799 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
811 #ifdef HAVE_BROKEN_READDIR_NAME
812 /* using /usr/ucb/cc is BAD */
816 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
817 talloc_tos(), &translated);
818 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
822 *talloced = translated;
823 if (!NT_STATUS_IS_OK(status)) {
829 /*******************************************************************
830 A wrapper for vfs_chdir().
831 ********************************************************************/
833 int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
837 struct smb_filename *saved_cwd = NULL;
840 LastDir = SMB_STRDUP("");
843 if (ISDOT(smb_fname->base_name)) {
847 if (*smb_fname->base_name == '/' &&
848 strcsequal(LastDir,smb_fname->base_name)) {
852 if (conn->cwd_fname != NULL) {
854 * Save off where we are in case we need to return
855 * on vfs_GetWd() failure after successful SMB_VFS_CHDIR().
857 saved_cwd = cp_smb_filename(conn, conn->cwd_fname);
858 if (saved_cwd == NULL) {
863 DEBUG(4,("vfs_ChDir to %s\n", smb_fname->base_name));
865 ret = SMB_VFS_CHDIR(conn, smb_fname);
868 TALLOC_FREE(saved_cwd);
874 * Always replace conn->cwd_fname. We
875 * don't know if it's been modified by
876 * VFS modules in the stack.
880 TALLOC_FREE(conn->cwd_fname);
881 conn->cwd_fname = vfs_GetWd(conn, conn);
882 if (conn->cwd_fname == NULL) {
884 * vfs_GetWd() failed.
885 * We must be able to read cwd.
886 * Return to original directory
891 if (saved_cwd == NULL) {
893 * Failed on the very first chdir()+getwd()
894 * for this connection. We can't
897 smb_panic("conn->cwd getwd failed\n");
902 /* Return to the previous $cwd. */
903 ret = SMB_VFS_CHDIR(conn, saved_cwd);
905 smb_panic("conn->cwd getwd failed\n");
909 /* Restore original conn->cwd_fname. */
910 conn->cwd_fname = saved_cwd;
912 /* And fail the chdir(). */
916 /* vfs_GetWd() succeeded. */
917 /* Replace global cache. */
919 LastDir = SMB_STRDUP(smb_fname->base_name);
921 DEBUG(4,("vfs_ChDir got %s\n", conn->cwd_fname->base_name));
923 TALLOC_FREE(saved_cwd);
924 if (saved_errno != 0) {
930 /*******************************************************************
931 Return the absolute current directory path - given a UNIX pathname.
932 Note that this path is returned in DOS format, not UNIX
933 format. Note this can be called with conn == NULL.
934 ********************************************************************/
936 struct smb_filename *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
938 struct smb_filename *current_dir_fname = NULL;
940 struct smb_filename *smb_fname_dot = NULL;
941 struct smb_filename *smb_fname_full = NULL;
942 struct smb_filename *result = NULL;
944 if (!lp_getwd_cache()) {
948 smb_fname_dot = synthetic_smb_fname(ctx, ".", NULL, NULL, 0);
949 if (smb_fname_dot == NULL) {
954 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
956 * Known to fail for root: the directory may be NFS-mounted
957 * and exported with root_squash (so has no root access).
959 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
960 "(NFS problem ?)\n", strerror(errno) ));
964 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
966 smb_fname_full = (struct smb_filename *)memcache_lookup_talloc(
969 data_blob_const(&key, sizeof(key)));
971 if (smb_fname_full == NULL) {
975 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
976 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
977 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
978 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
981 * Note: smb_fname_full is owned by smbd_memcache()
982 * so we must make a copy to return.
984 result = cp_smb_filename(ctx, smb_fname_full);
985 if (result == NULL) {
994 * We don't have the information to hand so rely on traditional
995 * methods. The very slow getcwd, which spawns a process on some
996 * systems, or the not quite so bad getwd.
999 current_dir_fname = SMB_VFS_GETWD(conn, ctx);
1000 if (current_dir_fname == NULL) {
1001 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
1006 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
1007 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
1010 * smbd_memcache() will own current_dir_fname after the
1011 * memcache_add_talloc call, so we must make
1012 * a copy on ctx to return.
1014 result = cp_smb_filename(ctx, current_dir_fname);
1015 if (result == NULL) {
1020 * Ensure the memory going into the cache
1021 * doesn't have a destructor so it can be
1024 talloc_set_destructor(current_dir_fname, NULL);
1026 memcache_add_talloc(smbd_memcache(),
1028 data_blob_const(&key, sizeof(key)),
1029 ¤t_dir_fname);
1030 /* current_dir_fname is now == NULL here. */
1032 /* current_dir_fname is already allocated on ctx. */
1033 result = current_dir_fname;
1037 TALLOC_FREE(smb_fname_dot);
1039 * Don't free current_dir_fname here. It's either been moved
1040 * to the memcache or is being returned in result.
1045 /*******************************************************************
1046 Reduce a file name, removing .. elements and checking that
1047 it is below dir in the heirachy. This uses realpath.
1048 This function must run as root, and will return names
1049 and valid stat structs that can be checked on open.
1050 ********************************************************************/
1052 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
1053 const struct smb_filename *smb_fname,
1054 struct smb_request *smbreq)
1057 TALLOC_CTX *ctx = talloc_tos();
1058 const char *conn_rootdir;
1060 char *dir_name = NULL;
1061 char *resolved_name = NULL;
1062 const char *last_component = NULL;
1063 struct smb_filename *resolved_fname = NULL;
1064 struct smb_filename *saved_dir_fname = NULL;
1065 struct smb_filename *smb_fname_cwd = NULL;
1066 struct privilege_paths *priv_paths = NULL;
1069 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
1070 smb_fname->base_name,
1071 conn->connectpath));
1074 priv_paths = talloc_zero(smbreq, struct privilege_paths);
1076 status = NT_STATUS_NO_MEMORY;
1080 if (!parent_dirname(ctx, smb_fname->base_name,
1081 &dir_name, &last_component)) {
1082 status = NT_STATUS_NO_MEMORY;
1086 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
1087 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
1089 if (priv_paths->parent_name.base_name == NULL ||
1090 priv_paths->file_name.base_name == NULL) {
1091 status = NT_STATUS_NO_MEMORY;
1095 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
1096 status = map_nt_error_from_unix(errno);
1099 /* Remember where we were. */
1100 saved_dir_fname = vfs_GetWd(ctx, conn);
1101 if (!saved_dir_fname) {
1102 status = map_nt_error_from_unix(errno);
1106 if (vfs_ChDir(conn, &priv_paths->parent_name) == -1) {
1107 status = map_nt_error_from_unix(errno);
1111 smb_fname_cwd = synthetic_smb_fname(talloc_tos(), ".", NULL, NULL, 0);
1112 if (smb_fname_cwd == NULL) {
1113 status = NT_STATUS_NO_MEMORY;
1117 /* Get the absolute path of the parent directory. */
1118 resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname_cwd);
1119 if (resolved_fname == NULL) {
1120 status = map_nt_error_from_unix(errno);
1123 resolved_name = resolved_fname->base_name;
1125 if (*resolved_name != '/') {
1126 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1127 "doesn't return absolute paths !\n"));
1128 status = NT_STATUS_OBJECT_NAME_INVALID;
1132 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1133 priv_paths->parent_name.base_name,
1136 /* Now check the stat value is the same. */
1137 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1138 status = map_nt_error_from_unix(errno);
1142 /* Ensure we're pointing at the same place. */
1143 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1144 DEBUG(0,("check_reduced_name_with_privilege: "
1145 "device/inode/uid/gid on directory %s changed. "
1146 "Denying access !\n",
1147 priv_paths->parent_name.base_name));
1148 status = NT_STATUS_ACCESS_DENIED;
1152 /* Ensure we're below the connect path. */
1154 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
1155 if (conn_rootdir == NULL) {
1156 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1158 status = NT_STATUS_ACCESS_DENIED;
1162 rootdir_len = strlen(conn_rootdir);
1165 * In the case of rootdir_len == 1, we know that conn_rootdir is
1166 * "/", and we also know that resolved_name starts with a slash.
1167 * So, in this corner case, resolved_name is automatically a
1168 * sub-directory of the conn_rootdir. Thus we can skip the string
1169 * comparison and the next character checks (which are even
1170 * wrong in this case).
1172 if (rootdir_len != 1) {
1175 matched = (strncmp(conn_rootdir, resolved_name,
1178 if (!matched || (resolved_name[rootdir_len] != '/' &&
1179 resolved_name[rootdir_len] != '\0')) {
1180 DEBUG(2, ("check_reduced_name_with_privilege: Bad "
1181 "access attempt: %s is a symlink outside the "
1184 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1185 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1186 status = NT_STATUS_ACCESS_DENIED;
1191 /* Now ensure that the last component either doesn't
1192 exist, or is *NOT* a symlink. */
1194 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1196 /* Errno must be ENOENT for this be ok. */
1197 if (errno != ENOENT) {
1198 status = map_nt_error_from_unix(errno);
1199 DEBUG(2, ("check_reduced_name_with_privilege: "
1200 "LSTAT on %s failed with %s\n",
1201 priv_paths->file_name.base_name,
1202 nt_errstr(status)));
1207 if (VALID_STAT(priv_paths->file_name.st) &&
1208 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1209 DEBUG(2, ("check_reduced_name_with_privilege: "
1210 "Last component %s is a symlink. Denying"
1212 priv_paths->file_name.base_name));
1213 status = NT_STATUS_ACCESS_DENIED;
1217 smbreq->priv_paths = priv_paths;
1218 status = NT_STATUS_OK;
1222 if (saved_dir_fname != NULL) {
1223 vfs_ChDir(conn, saved_dir_fname);
1224 TALLOC_FREE(saved_dir_fname);
1226 TALLOC_FREE(resolved_fname);
1227 if (!NT_STATUS_IS_OK(status)) {
1228 TALLOC_FREE(priv_paths);
1230 TALLOC_FREE(dir_name);
1234 /*******************************************************************
1235 Reduce a file name, removing .. elements and checking that
1236 it is below dir in the heirachy. This uses realpath.
1238 If cwd_name == NULL then fname is a client given path relative
1239 to the root path of the share.
1241 If cwd_name != NULL then fname is a client given path relative
1242 to cwd_name. cwd_name is relative to the root path of the share.
1243 ********************************************************************/
1245 NTSTATUS check_reduced_name(connection_struct *conn,
1246 const struct smb_filename *cwd_fname,
1247 const struct smb_filename *smb_fname)
1249 TALLOC_CTX *ctx = talloc_tos();
1250 const char *cwd_name = cwd_fname ? cwd_fname->base_name : NULL;
1251 const char *fname = smb_fname->base_name;
1252 struct smb_filename *resolved_fname;
1253 char *resolved_name = NULL;
1254 char *new_fname = NULL;
1255 bool allow_symlinks = true;
1256 bool allow_widelinks = false;
1258 DBG_DEBUG("check_reduced_name [%s] [%s]\n", fname, conn->connectpath);
1260 resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname);
1262 if (resolved_fname == NULL) {
1265 DEBUG(3,("check_reduced_name: Component not a "
1266 "directory in getting realpath for "
1268 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1271 char *dir_name = NULL;
1272 struct smb_filename dir_fname = {0};
1273 const char *last_component = NULL;
1275 /* Last component didn't exist.
1276 Remove it and try and canonicalise
1277 the directory name. */
1278 if (!parent_dirname(ctx, fname,
1281 return NT_STATUS_NO_MEMORY;
1284 dir_fname = (struct smb_filename)
1285 { .base_name = dir_name };
1286 resolved_fname = SMB_VFS_REALPATH(conn,
1289 if (resolved_fname == NULL) {
1290 NTSTATUS status = map_nt_error_from_unix(errno);
1292 if (errno == ENOENT || errno == ENOTDIR) {
1293 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1296 DEBUG(3,("check_reduce_name: "
1297 "couldn't get realpath for "
1300 nt_errstr(status)));
1303 resolved_name = talloc_asprintf(ctx,
1305 resolved_fname->base_name,
1307 if (resolved_name == NULL) {
1308 return NT_STATUS_NO_MEMORY;
1313 DEBUG(3,("check_reduced_name: couldn't get "
1314 "realpath for %s\n", fname));
1315 return map_nt_error_from_unix(errno);
1318 resolved_name = resolved_fname->base_name;
1321 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1324 if (*resolved_name != '/') {
1325 DEBUG(0,("check_reduced_name: realpath doesn't return "
1326 "absolute paths !\n"));
1327 TALLOC_FREE(resolved_fname);
1328 return NT_STATUS_OBJECT_NAME_INVALID;
1331 allow_widelinks = lp_widelinks(SNUM(conn));
1332 allow_symlinks = lp_follow_symlinks(SNUM(conn));
1334 /* Common widelinks and symlinks checks. */
1335 if (!allow_widelinks || !allow_symlinks) {
1336 const char *conn_rootdir;
1339 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
1340 if (conn_rootdir == NULL) {
1341 DEBUG(2, ("check_reduced_name: Could not get "
1343 TALLOC_FREE(resolved_fname);
1344 return NT_STATUS_ACCESS_DENIED;
1347 rootdir_len = strlen(conn_rootdir);
1350 * In the case of rootdir_len == 1, we know that
1351 * conn_rootdir is "/", and we also know that
1352 * resolved_name starts with a slash. So, in this
1353 * corner case, resolved_name is automatically a
1354 * sub-directory of the conn_rootdir. Thus we can skip
1355 * the string comparison and the next character checks
1356 * (which are even wrong in this case).
1358 if (rootdir_len != 1) {
1361 matched = (strncmp(conn_rootdir, resolved_name,
1363 if (!matched || (resolved_name[rootdir_len] != '/' &&
1364 resolved_name[rootdir_len] != '\0')) {
1365 DEBUG(2, ("check_reduced_name: Bad access "
1366 "attempt: %s is a symlink outside the "
1367 "share path\n", fname));
1368 DEBUGADD(2, ("conn_rootdir =%s\n",
1370 DEBUGADD(2, ("resolved_name=%s\n",
1372 TALLOC_FREE(resolved_fname);
1373 return NT_STATUS_ACCESS_DENIED;
1377 /* Extra checks if all symlinks are disallowed. */
1378 if (!allow_symlinks) {
1379 /* fname can't have changed in resolved_path. */
1380 const char *p = &resolved_name[rootdir_len];
1383 * UNIX filesystem semantics, names consisting
1384 * only of "." or ".." CANNOT be symlinks.
1386 if (ISDOT(fname) || ISDOTDOT(fname)) {
1391 DEBUG(2, ("check_reduced_name: logic error (%c) "
1392 "in resolved_name: %s\n",
1395 TALLOC_FREE(resolved_fname);
1396 return NT_STATUS_ACCESS_DENIED;
1402 * If cwd_name is present and not ".",
1403 * then fname is relative to that, not
1404 * the root of the share. Make sure the
1405 * path we check is the one the client
1406 * sent (cwd_name+fname).
1408 if (cwd_name != NULL && !ISDOT(cwd_name)) {
1409 new_fname = talloc_asprintf(ctx,
1413 if (new_fname == NULL) {
1414 TALLOC_FREE(resolved_fname);
1415 return NT_STATUS_NO_MEMORY;
1420 if (strcmp(fname, p)!=0) {
1421 DEBUG(2, ("check_reduced_name: Bad access "
1422 "attempt: %s is a symlink to %s\n",
1424 TALLOC_FREE(resolved_fname);
1425 TALLOC_FREE(new_fname);
1426 return NT_STATUS_ACCESS_DENIED;
1433 DBG_INFO("%s reduced to %s\n", fname, resolved_name);
1434 TALLOC_FREE(resolved_fname);
1435 TALLOC_FREE(new_fname);
1436 return NT_STATUS_OK;
1440 * XXX: This is temporary and there should be no callers of this once
1441 * smb_filename is plumbed through all path based operations.
1443 * Called when we know stream name parsing has already been done.
1445 int vfs_stat_smb_basename(struct connection_struct *conn,
1446 const struct smb_filename *smb_fname_in,
1447 SMB_STRUCT_STAT *psbuf)
1449 struct smb_filename smb_fname = {
1450 .base_name = discard_const_p(char, smb_fname_in->base_name),
1451 .flags = smb_fname_in->flags
1455 if (smb_fname.flags & SMB_FILENAME_POSIX_PATH) {
1456 ret = SMB_VFS_LSTAT(conn, &smb_fname);
1458 ret = SMB_VFS_STAT(conn, &smb_fname);
1462 *psbuf = smb_fname.st;
1468 * Ensure LSTAT is called for POSIX paths.
1471 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1475 if(fsp->fh->fd == -1) {
1476 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1477 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1479 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1482 return map_nt_error_from_unix(errno);
1485 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1486 return map_nt_error_from_unix(errno);
1489 return NT_STATUS_OK;
1493 * Initialize num_streams and streams, then call VFS op streaminfo
1495 NTSTATUS vfs_streaminfo(connection_struct *conn,
1496 struct files_struct *fsp,
1497 const struct smb_filename *smb_fname,
1498 TALLOC_CTX *mem_ctx,
1499 unsigned int *num_streams,
1500 struct stream_struct **streams)
1504 return SMB_VFS_STREAMINFO(conn,
1513 generate a file_id from a stat structure
1515 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1517 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1520 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1521 const char *service, const char *user)
1524 return handle->fns->connect_fn(handle, service, user);
1527 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1529 VFS_FIND(disconnect);
1530 handle->fns->disconnect_fn(handle);
1533 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1534 const struct smb_filename *smb_fname,
1539 VFS_FIND(disk_free);
1540 return handle->fns->disk_free_fn(handle, smb_fname,
1541 bsize, dfree, dsize);
1544 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1545 const struct smb_filename *smb_fname,
1546 enum SMB_QUOTA_TYPE qtype,
1550 VFS_FIND(get_quota);
1551 return handle->fns->get_quota_fn(handle, smb_fname, qtype, id, qt);
1554 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1555 enum SMB_QUOTA_TYPE qtype, unid_t id,
1558 VFS_FIND(set_quota);
1559 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1562 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1563 struct files_struct *fsp,
1564 struct shadow_copy_data *shadow_copy_data,
1567 VFS_FIND(get_shadow_copy_data);
1568 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1572 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle,
1573 const struct smb_filename *smb_fname,
1574 struct vfs_statvfs_struct *statbuf)
1577 return handle->fns->statvfs_fn(handle, smb_fname, statbuf);
1580 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1581 enum timestamp_set_resolution *p_ts_res)
1583 VFS_FIND(fs_capabilities);
1584 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1587 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1588 struct dfs_GetDFSReferral *r)
1590 VFS_FIND(get_dfs_referrals);
1591 return handle->fns->get_dfs_referrals_fn(handle, r);
1594 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1595 const struct smb_filename *smb_fname,
1597 uint32_t attributes)
1600 return handle->fns->opendir_fn(handle, smb_fname, mask, attributes);
1603 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1604 struct files_struct *fsp,
1606 uint32_t attributes)
1608 VFS_FIND(fdopendir);
1609 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1612 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1614 SMB_STRUCT_STAT *sbuf)
1617 return handle->fns->readdir_fn(handle, dirp, sbuf);
1620 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1621 DIR *dirp, long offset)
1624 handle->fns->seekdir_fn(handle, dirp, offset);
1627 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1631 return handle->fns->telldir_fn(handle, dirp);
1634 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1637 VFS_FIND(rewind_dir);
1638 handle->fns->rewind_dir_fn(handle, dirp);
1641 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle,
1642 const struct smb_filename *smb_fname,
1646 return handle->fns->mkdir_fn(handle, smb_fname, mode);
1649 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle,
1650 const struct smb_filename *smb_fname)
1653 return handle->fns->rmdir_fn(handle, smb_fname);
1656 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1660 return handle->fns->closedir_fn(handle, dir);
1663 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1664 struct smb_filename *smb_fname, struct files_struct *fsp,
1665 int flags, mode_t mode)
1668 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1671 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1672 struct smb_request *req,
1673 uint16_t root_dir_fid,
1674 struct smb_filename *smb_fname,
1675 uint32_t access_mask,
1676 uint32_t share_access,
1677 uint32_t create_disposition,
1678 uint32_t create_options,
1679 uint32_t file_attributes,
1680 uint32_t oplock_request,
1681 struct smb2_lease *lease,
1682 uint64_t allocation_size,
1683 uint32_t private_flags,
1684 struct security_descriptor *sd,
1685 struct ea_list *ea_list,
1686 files_struct **result,
1688 const struct smb2_create_blobs *in_context_blobs,
1689 struct smb2_create_blobs *out_context_blobs)
1691 VFS_FIND(create_file);
1692 return handle->fns->create_file_fn(
1693 handle, req, root_dir_fid, smb_fname, access_mask,
1694 share_access, create_disposition, create_options,
1695 file_attributes, oplock_request, lease, allocation_size,
1696 private_flags, sd, ea_list,
1697 result, pinfo, in_context_blobs, out_context_blobs);
1700 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1701 struct files_struct *fsp)
1704 return handle->fns->close_fn(handle, fsp);
1707 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1708 struct files_struct *fsp, void *data, size_t n)
1711 return handle->fns->read_fn(handle, fsp, data, n);
1714 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1715 struct files_struct *fsp, void *data, size_t n,
1719 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1722 struct smb_vfs_call_pread_state {
1723 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1725 struct vfs_aio_state vfs_aio_state;
1728 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1730 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1731 TALLOC_CTX *mem_ctx,
1732 struct tevent_context *ev,
1733 struct files_struct *fsp,
1735 size_t n, off_t offset)
1737 struct tevent_req *req, *subreq;
1738 struct smb_vfs_call_pread_state *state;
1740 req = tevent_req_create(mem_ctx, &state,
1741 struct smb_vfs_call_pread_state);
1745 VFS_FIND(pread_send);
1746 state->recv_fn = handle->fns->pread_recv_fn;
1748 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1750 if (tevent_req_nomem(subreq, req)) {
1751 return tevent_req_post(req, ev);
1753 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1757 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1759 struct tevent_req *req = tevent_req_callback_data(
1760 subreq, struct tevent_req);
1761 struct smb_vfs_call_pread_state *state = tevent_req_data(
1762 req, struct smb_vfs_call_pread_state);
1764 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1765 TALLOC_FREE(subreq);
1766 if (state->retval == -1) {
1767 tevent_req_error(req, state->vfs_aio_state.error);
1770 tevent_req_done(req);
1773 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req,
1774 struct vfs_aio_state *vfs_aio_state)
1776 struct smb_vfs_call_pread_state *state = tevent_req_data(
1777 req, struct smb_vfs_call_pread_state);
1779 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1782 *vfs_aio_state = state->vfs_aio_state;
1783 return state->retval;
1786 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1787 struct files_struct *fsp, const void *data,
1791 return handle->fns->write_fn(handle, fsp, data, n);
1794 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1795 struct files_struct *fsp, const void *data,
1796 size_t n, off_t offset)
1799 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1802 struct smb_vfs_call_pwrite_state {
1803 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1805 struct vfs_aio_state vfs_aio_state;
1808 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1810 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1811 TALLOC_CTX *mem_ctx,
1812 struct tevent_context *ev,
1813 struct files_struct *fsp,
1815 size_t n, off_t offset)
1817 struct tevent_req *req, *subreq;
1818 struct smb_vfs_call_pwrite_state *state;
1820 req = tevent_req_create(mem_ctx, &state,
1821 struct smb_vfs_call_pwrite_state);
1825 VFS_FIND(pwrite_send);
1826 state->recv_fn = handle->fns->pwrite_recv_fn;
1828 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1830 if (tevent_req_nomem(subreq, req)) {
1831 return tevent_req_post(req, ev);
1833 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1837 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1839 struct tevent_req *req = tevent_req_callback_data(
1840 subreq, struct tevent_req);
1841 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1842 req, struct smb_vfs_call_pwrite_state);
1844 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1845 TALLOC_FREE(subreq);
1846 if (state->retval == -1) {
1847 tevent_req_error(req, state->vfs_aio_state.error);
1850 tevent_req_done(req);
1853 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req,
1854 struct vfs_aio_state *vfs_aio_state)
1856 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1857 req, struct smb_vfs_call_pwrite_state);
1859 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1862 *vfs_aio_state = state->vfs_aio_state;
1863 return state->retval;
1866 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1867 struct files_struct *fsp, off_t offset,
1871 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1874 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1875 files_struct *fromfsp, const DATA_BLOB *header,
1876 off_t offset, size_t count)
1879 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1883 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1884 files_struct *tofsp, off_t offset,
1888 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1891 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1892 const struct smb_filename *smb_fname_src,
1893 const struct smb_filename *smb_fname_dst)
1896 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1899 struct smb_vfs_call_fsync_state {
1900 int (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1902 struct vfs_aio_state vfs_aio_state;
1905 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1907 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1908 TALLOC_CTX *mem_ctx,
1909 struct tevent_context *ev,
1910 struct files_struct *fsp)
1912 struct tevent_req *req, *subreq;
1913 struct smb_vfs_call_fsync_state *state;
1915 req = tevent_req_create(mem_ctx, &state,
1916 struct smb_vfs_call_fsync_state);
1920 VFS_FIND(fsync_send);
1921 state->recv_fn = handle->fns->fsync_recv_fn;
1923 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1924 if (tevent_req_nomem(subreq, req)) {
1925 return tevent_req_post(req, ev);
1927 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1931 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1933 struct tevent_req *req = tevent_req_callback_data(
1934 subreq, struct tevent_req);
1935 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1936 req, struct smb_vfs_call_fsync_state);
1938 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1939 TALLOC_FREE(subreq);
1940 if (state->retval == -1) {
1941 tevent_req_error(req, state->vfs_aio_state.error);
1944 tevent_req_done(req);
1947 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state)
1949 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1950 req, struct smb_vfs_call_fsync_state);
1952 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1955 *vfs_aio_state = state->vfs_aio_state;
1956 return state->retval;
1960 * Synchronous version of fsync, built from backend
1961 * async VFS primitives. Uses a temporary sub-event
1962 * context (NOT NESTED).
1965 int smb_vfs_fsync_sync(files_struct *fsp)
1967 TALLOC_CTX *frame = talloc_stackframe();
1968 struct tevent_req *req = NULL;
1969 struct vfs_aio_state aio_state = { 0 };
1972 struct tevent_context *ev = samba_tevent_context_init(frame);
1978 req = SMB_VFS_FSYNC_SEND(talloc_tos(), ev, fsp);
1983 ok = tevent_req_poll(req, ev);
1988 ret = SMB_VFS_FSYNC_RECV(req, &aio_state);
1993 if (aio_state.error != 0) {
1994 errno = aio_state.error;
1999 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
2000 struct smb_filename *smb_fname)
2003 return handle->fns->stat_fn(handle, smb_fname);
2006 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
2007 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
2010 return handle->fns->fstat_fn(handle, fsp, sbuf);
2013 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
2014 struct smb_filename *smb_filename)
2017 return handle->fns->lstat_fn(handle, smb_filename);
2020 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
2021 struct files_struct *fsp,
2022 const SMB_STRUCT_STAT *sbuf)
2024 VFS_FIND(get_alloc_size);
2025 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
2028 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
2029 const struct smb_filename *smb_fname)
2032 return handle->fns->unlink_fn(handle, smb_fname);
2035 int smb_vfs_call_chmod(struct vfs_handle_struct *handle,
2036 const struct smb_filename *smb_fname,
2040 return handle->fns->chmod_fn(handle, smb_fname, mode);
2043 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
2044 struct files_struct *fsp, mode_t mode)
2047 return handle->fns->fchmod_fn(handle, fsp, mode);
2050 int smb_vfs_call_chown(struct vfs_handle_struct *handle,
2051 const struct smb_filename *smb_fname,
2056 return handle->fns->chown_fn(handle, smb_fname, uid, gid);
2059 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
2060 struct files_struct *fsp, uid_t uid, gid_t gid)
2063 return handle->fns->fchown_fn(handle, fsp, uid, gid);
2066 int smb_vfs_call_lchown(struct vfs_handle_struct *handle,
2067 const struct smb_filename *smb_fname,
2072 return handle->fns->lchown_fn(handle, smb_fname, uid, gid);
2075 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
2078 bool as_root = false;
2081 if (fsp->fh->fd != -1) {
2083 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
2085 return NT_STATUS_OK;
2087 if (ret == -1 && errno != ENOSYS) {
2088 return map_nt_error_from_unix(errno);
2092 as_root = (geteuid() == 0);
2096 * We are being asked to chown as root. Make
2097 * sure we chdir() into the path to pin it,
2098 * and always act using lchown to ensure we
2099 * don't deref any symbolic links.
2101 char *parent_dir = NULL;
2102 const char *final_component = NULL;
2103 struct smb_filename *local_smb_fname = NULL;
2104 struct smb_filename parent_dir_fname = {0};
2105 struct smb_filename *saved_dir_fname = NULL;
2107 saved_dir_fname = vfs_GetWd(talloc_tos(),fsp->conn);
2108 if (!saved_dir_fname) {
2109 status = map_nt_error_from_unix(errno);
2110 DEBUG(0,("vfs_chown_fsp: failed to get "
2111 "current working directory. Error was %s\n",
2116 if (!parent_dirname(talloc_tos(),
2117 fsp->fsp_name->base_name,
2119 &final_component)) {
2120 return NT_STATUS_NO_MEMORY;
2123 parent_dir_fname = (struct smb_filename) {
2124 .base_name = parent_dir,
2125 .flags = fsp->fsp_name->flags
2128 /* cd into the parent dir to pin it. */
2129 ret = vfs_ChDir(fsp->conn, &parent_dir_fname);
2131 return map_nt_error_from_unix(errno);
2134 local_smb_fname = synthetic_smb_fname(talloc_tos(),
2138 fsp->fsp_name->flags);
2139 if (local_smb_fname == NULL) {
2140 status = NT_STATUS_NO_MEMORY;
2144 /* Must use lstat here. */
2145 ret = SMB_VFS_LSTAT(fsp->conn, local_smb_fname);
2147 status = map_nt_error_from_unix(errno);
2151 /* Ensure it matches the fsp stat. */
2152 if (!check_same_stat(&local_smb_fname->st,
2153 &fsp->fsp_name->st)) {
2154 status = NT_STATUS_ACCESS_DENIED;
2158 ret = SMB_VFS_LCHOWN(fsp->conn,
2163 status = NT_STATUS_OK;
2165 status = map_nt_error_from_unix(errno);
2170 vfs_ChDir(fsp->conn, saved_dir_fname);
2171 TALLOC_FREE(local_smb_fname);
2172 TALLOC_FREE(saved_dir_fname);
2173 TALLOC_FREE(parent_dir);
2178 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
2179 ret = SMB_VFS_LCHOWN(fsp->conn,
2183 ret = SMB_VFS_CHOWN(fsp->conn,
2189 status = NT_STATUS_OK;
2191 status = map_nt_error_from_unix(errno);
2196 int smb_vfs_call_chdir(struct vfs_handle_struct *handle,
2197 const struct smb_filename *smb_fname)
2200 return handle->fns->chdir_fn(handle, smb_fname);
2203 struct smb_filename *smb_vfs_call_getwd(struct vfs_handle_struct *handle,
2207 return handle->fns->getwd_fn(handle, ctx);
2210 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
2211 const struct smb_filename *smb_fname,
2212 struct smb_file_time *ft)
2215 return handle->fns->ntimes_fn(handle, smb_fname, ft);
2218 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2219 struct files_struct *fsp, off_t offset)
2221 VFS_FIND(ftruncate);
2222 return handle->fns->ftruncate_fn(handle, fsp, offset);
2225 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2226 struct files_struct *fsp,
2231 VFS_FIND(fallocate);
2232 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2235 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2236 struct files_struct *fsp, uint32_t share_mode,
2237 uint32_t access_mask)
2239 VFS_FIND(kernel_flock);
2240 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2244 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2245 struct files_struct *fsp, int leasetype)
2247 VFS_FIND(linux_setlease);
2248 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2251 int smb_vfs_call_symlink(struct vfs_handle_struct *handle,
2252 const char *link_target,
2253 const struct smb_filename *new_smb_fname)
2256 return handle->fns->symlink_fn(handle, link_target, new_smb_fname);
2259 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2260 const struct smb_filename *smb_fname,
2265 return handle->fns->readlink_fn(handle, smb_fname, buf, bufsiz);
2268 int smb_vfs_call_link(struct vfs_handle_struct *handle,
2269 const struct smb_filename *old_smb_fname,
2270 const struct smb_filename *new_smb_fname)
2273 return handle->fns->link_fn(handle, old_smb_fname, new_smb_fname);
2276 int smb_vfs_call_mknod(struct vfs_handle_struct *handle,
2277 const struct smb_filename *smb_fname,
2282 return handle->fns->mknod_fn(handle, smb_fname, mode, dev);
2285 struct smb_filename *smb_vfs_call_realpath(struct vfs_handle_struct *handle,
2287 const struct smb_filename *smb_fname)
2290 return handle->fns->realpath_fn(handle, ctx, smb_fname);
2293 int smb_vfs_call_chflags(struct vfs_handle_struct *handle,
2294 const struct smb_filename *smb_fname,
2298 return handle->fns->chflags_fn(handle, smb_fname, flags);
2301 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2302 const SMB_STRUCT_STAT *sbuf)
2304 VFS_FIND(file_id_create);
2305 return handle->fns->file_id_create_fn(handle, sbuf);
2308 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2309 struct files_struct *fsp,
2310 const struct smb_filename *smb_fname,
2311 TALLOC_CTX *mem_ctx,
2312 unsigned int *num_streams,
2313 struct stream_struct **streams)
2315 VFS_FIND(streaminfo);
2316 return handle->fns->streaminfo_fn(handle, fsp, smb_fname, mem_ctx,
2317 num_streams, streams);
2320 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2321 const char *path, const char *name,
2322 TALLOC_CTX *mem_ctx, char **found_name)
2324 VFS_FIND(get_real_filename);
2325 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2329 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2330 const struct smb_filename *smb_fname)
2332 VFS_FIND(connectpath);
2333 return handle->fns->connectpath_fn(handle, smb_fname);
2336 bool smb_vfs_call_strict_lock_check(struct vfs_handle_struct *handle,
2337 struct files_struct *fsp,
2338 struct lock_struct *plock)
2340 VFS_FIND(strict_lock_check);
2341 return handle->fns->strict_lock_check_fn(handle, fsp, plock);
2344 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2346 enum vfs_translate_direction direction,
2347 TALLOC_CTX *mem_ctx,
2350 VFS_FIND(translate_name);
2351 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2355 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2356 struct files_struct *fsp,
2360 const uint8_t *in_data,
2363 uint32_t max_out_len,
2367 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2368 in_data, in_len, out_data, max_out_len,
2372 NTSTATUS smb_vfs_call_get_dos_attributes(struct vfs_handle_struct *handle,
2373 struct smb_filename *smb_fname,
2376 VFS_FIND(get_dos_attributes);
2377 return handle->fns->get_dos_attributes_fn(handle, smb_fname, dosmode);
2380 NTSTATUS smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct *handle,
2381 struct files_struct *fsp,
2384 VFS_FIND(fget_dos_attributes);
2385 return handle->fns->fget_dos_attributes_fn(handle, fsp, dosmode);
2388 NTSTATUS smb_vfs_call_set_dos_attributes(struct vfs_handle_struct *handle,
2389 const struct smb_filename *smb_fname,
2392 VFS_FIND(set_dos_attributes);
2393 return handle->fns->set_dos_attributes_fn(handle, smb_fname, dosmode);
2396 NTSTATUS smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct *handle,
2397 struct files_struct *fsp,
2400 VFS_FIND(set_dos_attributes);
2401 return handle->fns->fset_dos_attributes_fn(handle, fsp, dosmode);
2404 struct tevent_req *smb_vfs_call_offload_read_send(TALLOC_CTX *mem_ctx,
2405 struct tevent_context *ev,
2406 struct vfs_handle_struct *handle,
2407 struct files_struct *fsp,
2413 VFS_FIND(offload_read_send);
2414 return handle->fns->offload_read_send_fn(mem_ctx, ev, handle,
2416 ttl, offset, to_copy);
2419 NTSTATUS smb_vfs_call_offload_read_recv(struct tevent_req *req,
2420 struct vfs_handle_struct *handle,
2421 TALLOC_CTX *mem_ctx,
2422 DATA_BLOB *token_blob)
2424 VFS_FIND(offload_read_recv);
2425 return handle->fns->offload_read_recv_fn(req, handle, mem_ctx, token_blob);
2428 struct tevent_req *smb_vfs_call_offload_write_send(struct vfs_handle_struct *handle,
2429 TALLOC_CTX *mem_ctx,
2430 struct tevent_context *ev,
2433 off_t transfer_offset,
2434 struct files_struct *dest_fsp,
2438 VFS_FIND(offload_write_send);
2439 return handle->fns->offload_write_send_fn(handle, mem_ctx, ev, fsctl,
2440 token, transfer_offset,
2441 dest_fsp, dest_off, num);
2444 NTSTATUS smb_vfs_call_offload_write_recv(struct vfs_handle_struct *handle,
2445 struct tevent_req *req,
2448 VFS_FIND(offload_write_recv);
2449 return handle->fns->offload_write_recv_fn(handle, req, copied);
2452 NTSTATUS smb_vfs_call_get_compression(vfs_handle_struct *handle,
2453 TALLOC_CTX *mem_ctx,
2454 struct files_struct *fsp,
2455 struct smb_filename *smb_fname,
2456 uint16_t *_compression_fmt)
2458 VFS_FIND(get_compression);
2459 return handle->fns->get_compression_fn(handle, mem_ctx, fsp, smb_fname,
2463 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2464 TALLOC_CTX *mem_ctx,
2465 struct files_struct *fsp,
2466 uint16_t compression_fmt)
2468 VFS_FIND(set_compression);
2469 return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2473 NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
2474 TALLOC_CTX *mem_ctx,
2475 const char *service_path,
2478 VFS_FIND(snap_check_path);
2479 return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path,
2483 NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle,
2484 TALLOC_CTX *mem_ctx,
2485 const char *base_volume,
2491 VFS_FIND(snap_create);
2492 return handle->fns->snap_create_fn(handle, mem_ctx, base_volume, tstamp,
2493 rw, base_path, snap_path);
2496 NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle,
2497 TALLOC_CTX *mem_ctx,
2501 VFS_FIND(snap_delete);
2502 return handle->fns->snap_delete_fn(handle, mem_ctx, base_path,
2506 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2507 struct files_struct *fsp,
2508 uint32_t security_info,
2509 TALLOC_CTX *mem_ctx,
2510 struct security_descriptor **ppdesc)
2512 VFS_FIND(fget_nt_acl);
2513 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2517 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2518 const struct smb_filename *smb_fname,
2519 uint32_t security_info,
2520 TALLOC_CTX *mem_ctx,
2521 struct security_descriptor **ppdesc)
2523 VFS_FIND(get_nt_acl);
2524 return handle->fns->get_nt_acl_fn(handle,
2531 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2532 struct files_struct *fsp,
2533 uint32_t security_info_sent,
2534 const struct security_descriptor *psd)
2536 VFS_FIND(fset_nt_acl);
2537 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2541 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2542 struct smb_filename *file,
2543 struct security_acl *sacl,
2544 uint32_t access_requested,
2545 uint32_t access_denied)
2547 VFS_FIND(audit_file);
2548 return handle->fns->audit_file_fn(handle,
2555 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle,
2556 const struct smb_filename *smb_fname,
2559 VFS_FIND(chmod_acl);
2560 return handle->fns->chmod_acl_fn(handle, smb_fname, mode);
2563 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2564 struct files_struct *fsp, mode_t mode)
2566 VFS_FIND(fchmod_acl);
2567 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2570 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2571 const struct smb_filename *smb_fname,
2572 SMB_ACL_TYPE_T type,
2573 TALLOC_CTX *mem_ctx)
2575 VFS_FIND(sys_acl_get_file);
2576 return handle->fns->sys_acl_get_file_fn(handle, smb_fname, type, mem_ctx);
2579 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2580 struct files_struct *fsp,
2581 TALLOC_CTX *mem_ctx)
2583 VFS_FIND(sys_acl_get_fd);
2584 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2587 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2588 const struct smb_filename *smb_fname,
2589 TALLOC_CTX *mem_ctx,
2590 char **blob_description,
2593 VFS_FIND(sys_acl_blob_get_file);
2594 return handle->fns->sys_acl_blob_get_file_fn(handle, smb_fname,
2595 mem_ctx, blob_description, blob);
2598 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2599 struct files_struct *fsp,
2600 TALLOC_CTX *mem_ctx,
2601 char **blob_description,
2604 VFS_FIND(sys_acl_blob_get_fd);
2605 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2608 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2609 const struct smb_filename *smb_fname,
2610 SMB_ACL_TYPE_T acltype,
2613 VFS_FIND(sys_acl_set_file);
2614 return handle->fns->sys_acl_set_file_fn(handle, smb_fname,
2618 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2619 struct files_struct *fsp, SMB_ACL_T theacl)
2621 VFS_FIND(sys_acl_set_fd);
2622 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2625 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2626 const struct smb_filename *smb_fname)
2628 VFS_FIND(sys_acl_delete_def_file);
2629 return handle->fns->sys_acl_delete_def_file_fn(handle, smb_fname);
2632 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2633 const struct smb_filename *smb_fname,
2639 return handle->fns->getxattr_fn(handle, smb_fname, name, value, size);
2642 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2643 struct files_struct *fsp, const char *name,
2644 void *value, size_t size)
2646 VFS_FIND(fgetxattr);
2647 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2650 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2651 const struct smb_filename *smb_fname,
2655 VFS_FIND(listxattr);
2656 return handle->fns->listxattr_fn(handle, smb_fname, list, size);
2659 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2660 struct files_struct *fsp, char *list,
2663 VFS_FIND(flistxattr);
2664 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2667 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2668 const struct smb_filename *smb_fname,
2671 VFS_FIND(removexattr);
2672 return handle->fns->removexattr_fn(handle, smb_fname, name);
2675 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2676 struct files_struct *fsp, const char *name)
2678 VFS_FIND(fremovexattr);
2679 return handle->fns->fremovexattr_fn(handle, fsp, name);
2682 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle,
2683 const struct smb_filename *smb_fname,
2690 return handle->fns->setxattr_fn(handle, smb_fname,
2691 name, value, size, flags);
2694 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2695 struct files_struct *fsp, const char *name,
2696 const void *value, size_t size, int flags)
2698 VFS_FIND(fsetxattr);
2699 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2702 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2703 struct files_struct *fsp)
2705 VFS_FIND(aio_force);
2706 return handle->fns->aio_force_fn(handle, fsp);
2709 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2710 struct files_struct *fsp,
2711 TALLOC_CTX *mem_ctx,
2714 VFS_FIND(durable_cookie);
2715 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2718 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2719 struct files_struct *fsp,
2720 const DATA_BLOB old_cookie,
2721 TALLOC_CTX *mem_ctx,
2722 DATA_BLOB *new_cookie)
2724 VFS_FIND(durable_disconnect);
2725 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2726 mem_ctx, new_cookie);
2729 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2730 struct smb_request *smb1req,
2731 struct smbXsrv_open *op,
2732 const DATA_BLOB old_cookie,
2733 TALLOC_CTX *mem_ctx,
2734 struct files_struct **fsp,
2735 DATA_BLOB *new_cookie)
2737 VFS_FIND(durable_reconnect);
2738 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2739 old_cookie, mem_ctx, fsp,
2743 NTSTATUS smb_vfs_call_readdir_attr(struct vfs_handle_struct *handle,
2744 const struct smb_filename *fname,
2745 TALLOC_CTX *mem_ctx,
2746 struct readdir_attr_data **attr_data)
2748 VFS_FIND(readdir_attr);
2749 return handle->fns->readdir_attr_fn(handle, fname, mem_ctx, attr_data);