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"
34 #include "lib/util/tevent_ntstatus.h"
35 #include "lib/util/sys_rw.h"
38 #define DBGC_CLASS DBGC_VFS
43 struct vfs_fsp_data *next;
44 struct vfs_handle_struct *owner;
45 void (*destroy)(void *p_data);
47 /* NOTE: This structure contains four pointers so that we can guarantee
48 * that the end of the structure is always both 4-byte and 8-byte aligned.
52 struct vfs_init_function_entry {
54 struct vfs_init_function_entry *prev, *next;
55 const struct vfs_fn_pointers *fns;
58 /****************************************************************************
59 maintain the list of available backends
60 ****************************************************************************/
62 static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
64 struct vfs_init_function_entry *entry = backends;
66 DEBUG(10, ("vfs_find_backend_entry called for %s\n", name));
69 if (strcmp(entry->name, name)==0) return entry;
76 NTSTATUS smb_register_vfs(int version, const char *name,
77 const struct vfs_fn_pointers *fns)
79 struct vfs_init_function_entry *entry = backends;
81 if ((version != SMB_VFS_INTERFACE_VERSION)) {
82 DEBUG(0, ("Failed to register vfs module.\n"
83 "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
84 "current SMB_VFS_INTERFACE_VERSION is %d.\n"
85 "Please recompile against the current Samba Version!\n",
86 version, SMB_VFS_INTERFACE_VERSION));
87 return NT_STATUS_OBJECT_TYPE_MISMATCH;
90 if (!name || !name[0]) {
91 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
92 return NT_STATUS_INVALID_PARAMETER;
95 if (vfs_find_backend_entry(name)) {
96 DEBUG(0,("VFS module %s already loaded!\n", name));
97 return NT_STATUS_OBJECT_NAME_COLLISION;
100 entry = SMB_XMALLOC_P(struct vfs_init_function_entry);
101 entry->name = smb_xstrdup(name);
104 DLIST_ADD(backends, entry);
105 DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
109 /****************************************************************************
110 initialise default vfs hooks
111 ****************************************************************************/
113 static void vfs_init_default(connection_struct *conn)
115 DEBUG(3, ("Initialising default vfs hooks\n"));
116 vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME);
119 /****************************************************************************
120 initialise custom vfs hooks
121 ****************************************************************************/
123 bool vfs_init_custom(connection_struct *conn, const char *vfs_object)
125 char *module_path = NULL;
126 char *module_name = NULL;
127 char *module_param = NULL, *p;
128 vfs_handle_struct *handle;
129 const struct vfs_init_function_entry *entry;
131 if (!conn||!vfs_object||!vfs_object[0]) {
132 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
133 "empty vfs_object!\n"));
138 static_init_vfs(NULL);
141 DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
143 module_path = smb_xstrdup(vfs_object);
145 p = strchr_m(module_path, ':');
150 trim_char(module_param, ' ', ' ');
153 trim_char(module_path, ' ', ' ');
155 module_name = smb_xstrdup(module_path);
157 if ((module_name[0] == '/') &&
158 (strcmp(module_path, DEFAULT_VFS_MODULE_NAME) != 0)) {
161 * Extract the module name from the path. Just use the base
162 * name of the last path component.
165 SAFE_FREE(module_name);
166 module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
168 p = strchr_m(module_name, '.');
175 /* First, try to load the module with the new module system */
176 entry = vfs_find_backend_entry(module_name);
180 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
183 status = smb_load_module("vfs", module_path);
184 if (!NT_STATUS_IS_OK(status)) {
185 DEBUG(0, ("error probing vfs module '%s': %s\n",
186 module_path, nt_errstr(status)));
190 entry = vfs_find_backend_entry(module_name);
192 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
197 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
199 handle = talloc_zero(conn, vfs_handle_struct);
201 DEBUG(0,("TALLOC_ZERO() failed!\n"));
205 handle->fns = entry->fns;
207 handle->param = talloc_strdup(conn, module_param);
209 DLIST_ADD(conn->vfs_handles, handle);
211 SAFE_FREE(module_path);
212 SAFE_FREE(module_name);
216 SAFE_FREE(module_path);
217 SAFE_FREE(module_name);
221 /*****************************************************************
222 Allow VFS modules to extend files_struct with VFS-specific state.
223 This will be ok for small numbers of extensions, but might need to
224 be refactored if it becomes more widely used.
225 ******************************************************************/
227 #define EXT_DATA_AREA(e) ((uint8_t *)(e) + sizeof(struct vfs_fsp_data))
229 void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle,
230 files_struct *fsp, size_t ext_size,
231 void (*destroy_fn)(void *p_data))
233 struct vfs_fsp_data *ext;
236 /* Prevent VFS modules adding multiple extensions. */
237 if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
241 ext = (struct vfs_fsp_data *)TALLOC_ZERO(
242 handle->conn, sizeof(struct vfs_fsp_data) + ext_size);
248 ext->next = fsp->vfs_extension;
249 ext->destroy = destroy_fn;
250 fsp->vfs_extension = ext;
251 return EXT_DATA_AREA(ext);
254 void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
256 struct vfs_fsp_data *curr;
257 struct vfs_fsp_data *prev;
259 for (curr = fsp->vfs_extension, prev = NULL;
261 prev = curr, curr = curr->next) {
262 if (curr->owner == handle) {
264 prev->next = curr->next;
266 fsp->vfs_extension = curr->next;
269 curr->destroy(EXT_DATA_AREA(curr));
277 void vfs_remove_all_fsp_extensions(files_struct *fsp)
279 struct vfs_fsp_data *curr;
280 struct vfs_fsp_data *next;
282 for (curr = fsp->vfs_extension; curr; curr = next) {
285 fsp->vfs_extension = next;
288 curr->destroy(EXT_DATA_AREA(curr));
294 void *vfs_memctx_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
296 struct vfs_fsp_data *head;
298 for (head = fsp->vfs_extension; head; head = head->next) {
299 if (head->owner == handle) {
307 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
309 struct vfs_fsp_data *head;
311 head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
313 return EXT_DATA_AREA(head);
322 * Ensure this module catches all VFS functions.
325 void smb_vfs_assert_all_fns(const struct vfs_fn_pointers* fns,
328 bool missing_fn = false;
330 const uintptr_t *end = (const uintptr_t *)(fns + 1);
332 for (idx = 0; ((const uintptr_t *)fns + idx) < end; idx++) {
333 if (*((const uintptr_t *)fns + idx) == 0) {
334 DBG_ERR("VFS function at index %d not implemented "
335 "in module %s\n", idx, module);
341 smb_panic("Required VFS function not implemented in module.\n");
345 void smb_vfs_assert_all_fns(const struct vfs_fn_pointers* fns,
351 /*****************************************************************
353 ******************************************************************/
355 bool smbd_vfs_init(connection_struct *conn)
357 const char **vfs_objects;
361 /* Normal share - initialise with disk access functions */
362 vfs_init_default(conn);
364 /* No need to load vfs modules for printer connections */
369 if (lp_widelinks(SNUM(conn))) {
371 * As the widelinks logic is now moving into a
372 * vfs_widelinks module, we need to custom load
373 * it after the default module is initialized.
374 * That way no changes to smb.conf files are
377 bool ok = vfs_init_custom(conn, "widelinks");
379 DBG_ERR("widelinks enabled and vfs_init_custom "
380 "failed for vfs_widelinks module\n");
385 vfs_objects = lp_vfs_objects(SNUM(conn));
387 /* Override VFS functions if 'vfs object' was not specified*/
388 if (!vfs_objects || !vfs_objects[0])
391 for (i=0; vfs_objects[i] ;) {
395 for (j=i-1; j >= 0; j--) {
396 if (!vfs_init_custom(conn, vfs_objects[j])) {
397 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
404 /*******************************************************************
405 Check if a file exists in the vfs.
406 ********************************************************************/
408 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
410 /* Only return OK if stat was successful and S_ISREG */
411 if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
412 S_ISREG(smb_fname->st.st_ex_mode)) {
416 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
419 bool vfs_valid_pread_range(off_t offset, size_t length)
421 return sys_valid_io_range(offset, length);
424 bool vfs_valid_pwrite_range(off_t offset, size_t length)
427 * See MAXFILESIZE in [MS-FSA] 2.1.5.3 Server Requests a Write
429 static const uint64_t maxfilesize = 0xfffffff0000;
430 uint64_t last_byte_ofs;
433 ok = sys_valid_io_range(offset, length);
442 last_byte_ofs = offset + length;
443 if (last_byte_ofs > maxfilesize) {
450 ssize_t vfs_pwrite_data(struct smb_request *req,
460 ok = vfs_valid_pwrite_range(offset, N);
466 if (req && req->unread_bytes) {
467 int sockfd = req->xconn->transport.sock;
468 SMB_ASSERT(req->unread_bytes == N);
469 /* VFS_RECVFILE must drain the socket
470 * before returning. */
471 req->unread_bytes = 0;
473 * Leave the socket non-blocking and
474 * use SMB_VFS_RECVFILE. If it returns
475 * EAGAIN || EWOULDBLOCK temporarily set
476 * the socket blocking and retry
480 ret = SMB_VFS_RECVFILE(sockfd,
484 if (ret == 0 || (ret == -1 &&
486 errno == EWOULDBLOCK))) {
488 /* Ensure the socket is blocking. */
489 old_flags = fcntl(sockfd, F_GETFL, 0);
490 if (set_blocking(sockfd, true) == -1) {
493 ret = SMB_VFS_RECVFILE(sockfd,
497 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
504 return (ssize_t)total;
506 /* Any other error case. */
512 return (ssize_t)total;
516 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
526 return (ssize_t)total;
528 /****************************************************************************
529 An allocate file space call using the vfs interface.
530 Allocates space for a file from a filedescriptor.
531 Returns 0 on success, -1 on failure.
532 ****************************************************************************/
534 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
537 connection_struct *conn = fsp->conn;
538 uint64_t space_avail;
539 uint64_t bsize,dfree,dsize;
544 * Actually try and commit the space on disk....
547 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
548 fsp_str_dbg(fsp), (double)len));
550 ok = vfs_valid_pwrite_range((off_t)len, 0);
552 DEBUG(0,("vfs_allocate_file_space: %s negative/invalid len "
553 "requested.\n", fsp_str_dbg(fsp)));
558 status = vfs_stat_fsp(fsp);
559 if (!NT_STATUS_IS_OK(status)) {
563 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
566 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
567 /* Shrink - use ftruncate. */
569 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
570 "size %.0f\n", fsp_str_dbg(fsp),
571 (double)fsp->fsp_name->st.st_ex_size));
573 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
575 ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len);
577 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
582 /* Grow - we need to test if we have enough space. */
584 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
586 if (lp_strict_allocate(SNUM(fsp->conn))) {
587 /* See if we have a syscall that will allocate beyond
588 end-of-file without changing EOF. */
589 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_FL_KEEP_SIZE,
595 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
598 /* We changed the allocation size on disk, but not
599 EOF - exactly as required. We're done ! */
603 if (ret == -1 && errno == ENOSPC) {
607 len -= fsp->fsp_name->st.st_ex_size;
608 len /= 1024; /* Len is now number of 1k blocks needed. */
610 get_dfree_info(conn, fsp->fsp_name, &bsize, &dfree, &dsize);
611 if (space_avail == (uint64_t)-1) {
615 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
616 "needed blocks = %.0f, space avail = %.0f\n",
617 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
618 (double)space_avail));
620 if (len > space_avail) {
628 /****************************************************************************
629 A vfs set_filelen call.
630 set the length of a file from a filedescriptor.
631 Returns 0 on success, -1 on failure.
632 ****************************************************************************/
634 int vfs_set_filelen(files_struct *fsp, off_t len)
639 ok = vfs_valid_pwrite_range(len, 0);
645 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
647 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
648 fsp_str_dbg(fsp), (double)len));
649 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
650 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
651 FILE_NOTIFY_CHANGE_SIZE
652 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
653 fsp->fsp_name->base_name);
656 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
661 /****************************************************************************
662 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
663 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
664 as this is also called from the default SMB_VFS_FTRUNCATE code.
665 Always extends the file size.
666 Returns 0 on success, -1 on failure.
667 ****************************************************************************/
669 #define SPARSE_BUF_WRITE_SIZE (32*1024)
671 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
677 ok = vfs_valid_pwrite_range(offset, len);
684 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
691 while (total < len) {
692 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
694 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
695 if (pwrite_ret == -1) {
696 int saved_errno = errno;
697 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
698 "%s failed with error %s\n",
699 fsp_str_dbg(fsp), strerror(saved_errno)));
709 /****************************************************************************
710 A vfs fill sparse call.
711 Writes zeros from the end of file to len, if len is greater than EOF.
712 Used only by strict_sync.
713 Returns 0 on success, -1 on failure.
714 ****************************************************************************/
716 int vfs_fill_sparse(files_struct *fsp, off_t len)
724 ok = vfs_valid_pwrite_range(len, 0);
730 status = vfs_stat_fsp(fsp);
731 if (!NT_STATUS_IS_OK(status)) {
735 if (len <= fsp->fsp_name->st.st_ex_size) {
740 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
745 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
746 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
747 (double)fsp->fsp_name->st.st_ex_size, (double)len,
748 (double)(len - fsp->fsp_name->st.st_ex_size)));
750 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
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);
777 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
781 /*******************************************************************************
782 Set a fd into blocking/nonblocking mode through VFS
783 *******************************************************************************/
785 int vfs_set_blocking(files_struct *fsp, bool set)
789 #define FLAG_TO_SET O_NONBLOCK
792 #define FLAG_TO_SET O_NDELAY
794 #define FLAG_TO_SET FNDELAY
797 val = SMB_VFS_FCNTL(fsp, F_GETFL, 0);
808 return SMB_VFS_FCNTL(fsp, F_SETFL, val);
812 /****************************************************************************
813 Transfer some data (n bytes) between two file_struct's.
814 ****************************************************************************/
816 static ssize_t vfs_pread_fn(void *file, void *buf, size_t len, off_t offset)
818 struct files_struct *fsp = (struct files_struct *)file;
820 return SMB_VFS_PREAD(fsp, buf, len, offset);
823 static ssize_t vfs_pwrite_fn(void *file, const void *buf, size_t len, off_t offset)
825 struct files_struct *fsp = (struct files_struct *)file;
827 return SMB_VFS_PWRITE(fsp, buf, len, offset);
830 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
832 return transfer_file_internal((void *)in, (void *)out, n,
833 vfs_pread_fn, vfs_pwrite_fn);
836 /*******************************************************************
837 A vfs_readdir wrapper which just returns the file name.
838 ********************************************************************/
840 const char *vfs_readdirname(connection_struct *conn, void *p,
841 SMB_STRUCT_STAT *sbuf, char **talloced)
843 struct dirent *ptr= NULL;
851 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
857 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
858 talloc_tos(), &translated);
859 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
863 *talloced = translated;
864 if (!NT_STATUS_IS_OK(status)) {
870 /*******************************************************************
871 A wrapper for vfs_chdir().
872 ********************************************************************/
874 int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
877 struct smb_filename *cwd = NULL;
880 LastDir = SMB_STRDUP("");
883 if (ISDOT(smb_fname->base_name)) {
885 * passing a '.' is a noop,
886 * and we only expect this after
887 * everything is initialized.
889 * So the first vfs_ChDir() on a given
890 * connection_struct must not be '.'.
892 * Note: conn_new() sets
893 * conn->cwd_fsp->fh->fd = -1
894 * and vfs_ChDir() leaves with
895 * conn->cwd_fsp->fh->fd = AT_FDCWD
898 if (fsp_get_pathref_fd(conn->cwd_fsp) != AT_FDCWD) {
900 * This should never happen and
901 * we might change this to
902 * SMB_ASSERT() in future.
904 DBG_ERR("Called with '.' as first operation!\n");
912 if (smb_fname->base_name[0] == '/' &&
913 strcsequal(LastDir,smb_fname->base_name))
916 * conn->cwd_fsp->fsp_name and the kernel
917 * are already correct, but conn->cwd_fsp->fh->fd
918 * might still be -1 as initialized in conn_new().
920 * This can happen when a client made a 2nd
921 * tree connect to a share with the same underlying
922 * path (may or may not the same share).
924 fsp_set_fd(conn->cwd_fsp, AT_FDCWD);
928 DEBUG(4,("vfs_ChDir to %s\n", smb_fname->base_name));
930 ret = SMB_VFS_CHDIR(conn, smb_fname);
936 * Always replace conn->cwd_fsp. We
937 * don't know if it's been modified by
938 * VFS modules in the stack.
942 cwd = vfs_GetWd(conn, conn);
945 * vfs_GetWd() failed.
946 * We must be able to read cwd.
947 * Return to original directory
950 int saved_errno = errno;
952 if (conn->cwd_fsp->fsp_name == NULL) {
954 * Failed on the very first chdir()+getwd()
955 * for this connection. We can't
958 smb_panic("conn->cwd getwd failed\n");
963 /* Return to the previous $cwd. */
964 ret = SMB_VFS_CHDIR(conn, conn->cwd_fsp->fsp_name);
966 smb_panic("conn->cwd getwd failed\n");
971 /* And fail the chdir(). */
975 /* vfs_GetWd() succeeded. */
976 /* Replace global cache. */
978 LastDir = SMB_STRDUP(smb_fname->base_name);
981 * (Indirect) Callers of vfs_ChDir() may still hold references to the
982 * old conn->cwd_fsp->fsp_name. Move it to talloc_tos(), that way
983 * callers can use it for the lifetime of the SMB request.
985 talloc_move(talloc_tos(), &conn->cwd_fsp->fsp_name);
987 conn->cwd_fsp->fsp_name = talloc_move(conn->cwd_fsp, &cwd);
988 fsp_set_fd(conn->cwd_fsp, AT_FDCWD);
990 DBG_INFO("vfs_ChDir got %s\n", fsp_str_dbg(conn->cwd_fsp));
995 /*******************************************************************
996 Return the absolute current directory path - given a UNIX pathname.
997 Note that this path is returned in DOS format, not UNIX
998 format. Note this can be called with conn == NULL.
999 ********************************************************************/
1001 struct smb_filename *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
1003 struct smb_filename *current_dir_fname = NULL;
1005 struct smb_filename *smb_fname_dot = NULL;
1006 struct smb_filename *smb_fname_full = NULL;
1007 struct smb_filename *result = NULL;
1009 if (!lp_getwd_cache()) {
1013 smb_fname_dot = synthetic_smb_fname(ctx,
1019 if (smb_fname_dot == NULL) {
1024 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
1026 * Known to fail for root: the directory may be NFS-mounted
1027 * and exported with root_squash (so has no root access).
1029 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
1030 "(NFS problem ?)\n", strerror(errno) ));
1034 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
1036 smb_fname_full = (struct smb_filename *)memcache_lookup_talloc(
1039 data_blob_const(&key, sizeof(key)));
1041 if (smb_fname_full == NULL) {
1045 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
1046 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
1047 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
1048 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
1051 * Note: smb_fname_full is owned by smbd_memcache()
1052 * so we must make a copy to return.
1054 result = cp_smb_filename(ctx, smb_fname_full);
1055 if (result == NULL) {
1064 * We don't have the information to hand so rely on traditional
1065 * methods. The very slow getcwd, which spawns a process on some
1066 * systems, or the not quite so bad getwd.
1069 current_dir_fname = SMB_VFS_GETWD(conn, ctx);
1070 if (current_dir_fname == NULL) {
1071 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
1076 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
1077 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
1080 * smbd_memcache() will own current_dir_fname after the
1081 * memcache_add_talloc call, so we must make
1082 * a copy on ctx to return.
1084 result = cp_smb_filename(ctx, current_dir_fname);
1085 if (result == NULL) {
1090 * Ensure the memory going into the cache
1091 * doesn't have a destructor so it can be
1094 talloc_set_destructor(current_dir_fname, NULL);
1096 memcache_add_talloc(smbd_memcache(),
1098 data_blob_const(&key, sizeof(key)),
1099 ¤t_dir_fname);
1100 /* current_dir_fname is now == NULL here. */
1102 /* current_dir_fname is already allocated on ctx. */
1103 result = current_dir_fname;
1107 TALLOC_FREE(smb_fname_dot);
1109 * Don't free current_dir_fname here. It's either been moved
1110 * to the memcache or is being returned in result.
1115 /*******************************************************************
1116 Reduce a file name, removing .. elements and checking that
1117 it is below dir in the hierarchy. This uses realpath.
1118 This function must run as root, and will return names
1119 and valid stat structs that can be checked on open.
1120 ********************************************************************/
1122 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
1123 const struct smb_filename *smb_fname,
1124 struct smb_request *smbreq)
1127 TALLOC_CTX *ctx = talloc_tos();
1128 const char *conn_rootdir;
1130 char *resolved_name = NULL;
1131 struct smb_filename *resolved_fname = NULL;
1132 struct smb_filename *saved_dir_fname = NULL;
1133 struct smb_filename *smb_fname_cwd = NULL;
1135 struct smb_filename *parent_name = NULL;
1136 struct smb_filename *file_name = NULL;
1139 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
1140 smb_fname->base_name,
1141 conn->connectpath));
1144 ok = parent_smb_fname(ctx,
1149 status = NT_STATUS_NO_MEMORY;
1153 if (SMB_VFS_STAT(conn, parent_name) != 0) {
1154 status = map_nt_error_from_unix(errno);
1157 /* Remember where we were. */
1158 saved_dir_fname = vfs_GetWd(ctx, conn);
1159 if (!saved_dir_fname) {
1160 status = map_nt_error_from_unix(errno);
1164 if (vfs_ChDir(conn, parent_name) == -1) {
1165 status = map_nt_error_from_unix(errno);
1169 smb_fname_cwd = synthetic_smb_fname(talloc_tos(),
1175 if (smb_fname_cwd == NULL) {
1176 status = NT_STATUS_NO_MEMORY;
1180 /* Get the absolute path of the parent directory. */
1181 resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname_cwd);
1182 if (resolved_fname == NULL) {
1183 status = map_nt_error_from_unix(errno);
1186 resolved_name = resolved_fname->base_name;
1188 if (*resolved_name != '/') {
1189 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1190 "doesn't return absolute paths !\n"));
1191 status = NT_STATUS_OBJECT_NAME_INVALID;
1195 DBG_DEBUG("realpath [%s] -> [%s]\n",
1196 smb_fname_str_dbg(parent_name),
1199 /* Now check the stat value is the same. */
1200 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1201 status = map_nt_error_from_unix(errno);
1205 /* Ensure we're pointing at the same place. */
1206 if (!check_same_stat(&smb_fname_cwd->st, &parent_name->st)) {
1207 DBG_ERR("device/inode/uid/gid on directory %s changed. "
1208 "Denying access !\n",
1209 smb_fname_str_dbg(parent_name));
1210 status = NT_STATUS_ACCESS_DENIED;
1214 /* Ensure we're below the connect path. */
1216 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
1217 if (conn_rootdir == NULL) {
1218 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1220 status = NT_STATUS_ACCESS_DENIED;
1224 rootdir_len = strlen(conn_rootdir);
1227 * In the case of rootdir_len == 1, we know that conn_rootdir is
1228 * "/", and we also know that resolved_name starts with a slash.
1229 * So, in this corner case, resolved_name is automatically a
1230 * sub-directory of the conn_rootdir. Thus we can skip the string
1231 * comparison and the next character checks (which are even
1232 * wrong in this case).
1234 if (rootdir_len != 1) {
1237 matched = (strncmp(conn_rootdir, resolved_name,
1240 if (!matched || (resolved_name[rootdir_len] != '/' &&
1241 resolved_name[rootdir_len] != '\0')) {
1242 DBG_WARNING("%s is a symlink outside the "
1244 smb_fname_str_dbg(parent_name));
1245 DEBUGADD(1, ("conn_rootdir =%s\n", conn_rootdir));
1246 DEBUGADD(1, ("resolved_name=%s\n", resolved_name));
1247 status = NT_STATUS_ACCESS_DENIED;
1252 /* Now ensure that the last component either doesn't
1253 exist, or is *NOT* a symlink. */
1255 ret = SMB_VFS_LSTAT(conn, file_name);
1257 /* Errno must be ENOENT for this be ok. */
1258 if (errno != ENOENT) {
1259 status = map_nt_error_from_unix(errno);
1260 DBG_WARNING("LSTAT on %s failed with %s\n",
1261 smb_fname_str_dbg(file_name),
1267 if (VALID_STAT(file_name->st) &&
1268 S_ISLNK(file_name->st.st_ex_mode))
1270 DBG_WARNING("Last component %s is a symlink. Denying"
1272 smb_fname_str_dbg(file_name));
1273 status = NT_STATUS_ACCESS_DENIED;
1277 status = NT_STATUS_OK;
1281 if (saved_dir_fname != NULL) {
1282 vfs_ChDir(conn, saved_dir_fname);
1283 TALLOC_FREE(saved_dir_fname);
1285 TALLOC_FREE(resolved_fname);
1286 TALLOC_FREE(parent_name);
1290 /*******************************************************************
1291 Reduce a file name, removing .. elements and checking that
1292 it is below dir in the hierarchy. This uses realpath.
1294 If cwd_name == NULL then fname is a client given path relative
1295 to the root path of the share.
1297 If cwd_name != NULL then fname is a client given path relative
1298 to cwd_name. cwd_name is relative to the root path of the share.
1299 ********************************************************************/
1301 NTSTATUS check_reduced_name(connection_struct *conn,
1302 const struct smb_filename *cwd_fname,
1303 const struct smb_filename *smb_fname)
1305 TALLOC_CTX *ctx = talloc_tos();
1306 const char *cwd_name = cwd_fname ? cwd_fname->base_name : NULL;
1307 const char *fname = smb_fname->base_name;
1308 struct smb_filename *resolved_fname;
1309 char *resolved_name = NULL;
1310 char *new_fname = NULL;
1311 bool allow_symlinks = true;
1312 const char *conn_rootdir;
1316 DBG_DEBUG("check_reduced_name [%s] [%s]\n", fname, conn->connectpath);
1318 resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname);
1320 if (resolved_fname == NULL) {
1321 struct smb_filename *dir_fname = NULL;
1322 struct smb_filename *last_component = NULL;
1324 if (errno == ENOTDIR) {
1325 DBG_NOTICE("Component not a directory in getting "
1326 "realpath for %s\n",
1328 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1330 if (errno != ENOENT) {
1331 NTSTATUS status = map_nt_error_from_unix(errno);
1332 DBG_NOTICE("couldn't get realpath for %s: %s\n",
1338 /* errno == ENOENT */
1341 * Last component didn't exist. Remove it and try and
1342 * canonicalise the directory name.
1345 ok = parent_smb_fname(ctx,
1350 return NT_STATUS_NO_MEMORY;
1353 resolved_fname = SMB_VFS_REALPATH(conn, ctx, dir_fname);
1354 if (resolved_fname == NULL) {
1355 NTSTATUS status = map_nt_error_from_unix(errno);
1357 if (errno == ENOENT || errno == ENOTDIR) {
1358 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1361 DBG_NOTICE("couldn't get realpath for "
1363 smb_fname_str_dbg(dir_fname),
1367 resolved_name = talloc_asprintf(ctx,
1369 resolved_fname->base_name,
1370 last_component->base_name);
1371 if (resolved_name == NULL) {
1372 return NT_STATUS_NO_MEMORY;
1375 resolved_name = resolved_fname->base_name;
1378 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1381 if (*resolved_name != '/') {
1382 DEBUG(0,("check_reduced_name: realpath doesn't return "
1383 "absolute paths !\n"));
1384 TALLOC_FREE(resolved_fname);
1385 return NT_STATUS_OBJECT_NAME_INVALID;
1388 /* Common widelinks and symlinks checks. */
1389 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
1390 if (conn_rootdir == NULL) {
1391 DBG_NOTICE("Could not get conn_rootdir\n");
1392 TALLOC_FREE(resolved_fname);
1393 return NT_STATUS_ACCESS_DENIED;
1396 rootdir_len = strlen(conn_rootdir);
1399 * In the case of rootdir_len == 1, we know that
1400 * conn_rootdir is "/", and we also know that
1401 * resolved_name starts with a slash. So, in this
1402 * corner case, resolved_name is automatically a
1403 * sub-directory of the conn_rootdir. Thus we can skip
1404 * the string comparison and the next character checks
1405 * (which are even wrong in this case).
1407 if (rootdir_len != 1) {
1410 matched = (strncmp(conn_rootdir, resolved_name,
1412 if (!matched || (resolved_name[rootdir_len] != '/' &&
1413 resolved_name[rootdir_len] != '\0')) {
1414 DBG_NOTICE("Bad access attempt: %s is a symlink "
1417 "conn_rootdir =%s\n"
1418 "resolved_name=%s\n",
1422 TALLOC_FREE(resolved_fname);
1423 return NT_STATUS_ACCESS_DENIED;
1427 /* Extra checks if all symlinks are disallowed. */
1428 allow_symlinks = lp_follow_symlinks(SNUM(conn));
1429 if (!allow_symlinks) {
1430 /* fname can't have changed in resolved_path. */
1431 const char *p = &resolved_name[rootdir_len];
1434 * UNIX filesystem semantics, names consisting
1435 * only of "." or ".." CANNOT be symlinks.
1437 if (ISDOT(fname) || ISDOTDOT(fname)) {
1442 DBG_NOTICE("logic error (%c) "
1443 "in resolved_name: %s\n",
1446 TALLOC_FREE(resolved_fname);
1447 return NT_STATUS_ACCESS_DENIED;
1453 * If cwd_name is present and not ".",
1454 * then fname is relative to that, not
1455 * the root of the share. Make sure the
1456 * path we check is the one the client
1457 * sent (cwd_name+fname).
1459 if (cwd_name != NULL && !ISDOT(cwd_name)) {
1460 new_fname = talloc_asprintf(ctx,
1464 if (new_fname == NULL) {
1465 TALLOC_FREE(resolved_fname);
1466 return NT_STATUS_NO_MEMORY;
1471 if (strcmp(fname, p)!=0) {
1472 DBG_NOTICE("Bad access "
1473 "attempt: %s is a symlink to %s\n",
1476 TALLOC_FREE(resolved_fname);
1477 TALLOC_FREE(new_fname);
1478 return NT_STATUS_ACCESS_DENIED;
1484 DBG_INFO("%s reduced to %s\n", fname, resolved_name);
1485 TALLOC_FREE(resolved_fname);
1486 TALLOC_FREE(new_fname);
1487 return NT_STATUS_OK;
1491 * XXX: This is temporary and there should be no callers of this once
1492 * smb_filename is plumbed through all path based operations.
1494 * Called when we know stream name parsing has already been done.
1496 int vfs_stat_smb_basename(struct connection_struct *conn,
1497 const struct smb_filename *smb_fname_in,
1498 SMB_STRUCT_STAT *psbuf)
1500 struct smb_filename smb_fname = {
1501 .base_name = discard_const_p(char, smb_fname_in->base_name),
1502 .flags = smb_fname_in->flags,
1503 .twrp = smb_fname_in->twrp,
1507 if (smb_fname.flags & SMB_FILENAME_POSIX_PATH) {
1508 ret = SMB_VFS_LSTAT(conn, &smb_fname);
1510 ret = SMB_VFS_STAT(conn, &smb_fname);
1514 *psbuf = smb_fname.st;
1520 * Ensure LSTAT is called for POSIX paths.
1523 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1526 struct stat_ex saved_stat = fsp->fsp_name->st;
1528 if (fsp_get_pathref_fd(fsp) == -1) {
1529 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1530 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1532 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1535 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
1538 return map_nt_error_from_unix(errno);
1540 update_stat_ex_from_saved_stat(&fsp->fsp_name->st, &saved_stat);
1541 return NT_STATUS_OK;
1544 void init_smb_file_time(struct smb_file_time *ft)
1546 *ft = (struct smb_file_time) {
1547 .atime = make_omit_timespec(),
1548 .ctime = make_omit_timespec(),
1549 .mtime = make_omit_timespec(),
1550 .create_time = make_omit_timespec()
1555 * Initialize num_streams and streams, then call VFS op streaminfo
1557 NTSTATUS vfs_streaminfo(connection_struct *conn,
1558 struct files_struct *fsp,
1559 const struct smb_filename *smb_fname,
1560 TALLOC_CTX *mem_ctx,
1561 unsigned int *num_streams,
1562 struct stream_struct **streams)
1566 return SMB_VFS_STREAMINFO(conn,
1574 int vfs_fake_fd(void)
1580 * Return a valid fd, but ensure any attempt to use
1581 * it returns an error (EPIPE).
1583 ret = pipe(pipe_fds);
1593 generate a file_id from a stat structure
1595 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1597 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1600 NTSTATUS vfs_at_fspcwd(TALLOC_CTX *mem_ctx,
1601 struct connection_struct *conn,
1602 struct files_struct **_fsp)
1604 struct files_struct *fsp = NULL;
1606 fsp = talloc_zero(mem_ctx, struct files_struct);
1608 return NT_STATUS_NO_MEMORY;
1611 fsp->fsp_name = synthetic_smb_fname(fsp, ".", NULL, NULL, 0, 0);
1612 if (fsp->fsp_name == NULL) {
1614 return NT_STATUS_NO_MEMORY;
1617 fsp->fh = talloc_zero(fsp, struct fd_handle);
1618 if (fsp->fh == NULL) {
1620 return NT_STATUS_NO_MEMORY;
1623 fsp_set_fd(fsp, AT_FDCWD);
1624 fsp->fnum = FNUM_FIELD_INVALID;
1628 return NT_STATUS_OK;
1631 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1632 const char *service, const char *user)
1635 return handle->fns->connect_fn(handle, service, user);
1638 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1640 VFS_FIND(disconnect);
1641 handle->fns->disconnect_fn(handle);
1644 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1645 const struct smb_filename *smb_fname,
1650 VFS_FIND(disk_free);
1651 return handle->fns->disk_free_fn(handle, smb_fname,
1652 bsize, dfree, dsize);
1655 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1656 const struct smb_filename *smb_fname,
1657 enum SMB_QUOTA_TYPE qtype,
1661 VFS_FIND(get_quota);
1662 return handle->fns->get_quota_fn(handle, smb_fname, qtype, id, qt);
1665 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1666 enum SMB_QUOTA_TYPE qtype, unid_t id,
1669 VFS_FIND(set_quota);
1670 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1673 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1674 struct files_struct *fsp,
1675 struct shadow_copy_data *shadow_copy_data,
1678 VFS_FIND(get_shadow_copy_data);
1679 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1683 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle,
1684 const struct smb_filename *smb_fname,
1685 struct vfs_statvfs_struct *statbuf)
1688 return handle->fns->statvfs_fn(handle, smb_fname, statbuf);
1691 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1692 enum timestamp_set_resolution *p_ts_res)
1694 VFS_FIND(fs_capabilities);
1695 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1698 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1699 struct dfs_GetDFSReferral *r)
1701 VFS_FIND(get_dfs_referrals);
1702 return handle->fns->get_dfs_referrals_fn(handle, r);
1705 NTSTATUS smb_vfs_call_create_dfs_pathat(struct vfs_handle_struct *handle,
1706 struct files_struct *dirfsp,
1707 const struct smb_filename *smb_fname,
1708 const struct referral *reflist,
1709 size_t referral_count)
1711 VFS_FIND(create_dfs_pathat);
1712 return handle->fns->create_dfs_pathat_fn(handle,
1719 NTSTATUS smb_vfs_call_read_dfs_pathat(struct vfs_handle_struct *handle,
1720 TALLOC_CTX *mem_ctx,
1721 struct files_struct *dirfsp,
1722 struct smb_filename *smb_fname,
1723 struct referral **ppreflist,
1724 size_t *preferral_count)
1726 VFS_FIND(read_dfs_pathat);
1727 return handle->fns->read_dfs_pathat_fn(handle,
1735 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1736 struct files_struct *fsp,
1738 uint32_t attributes)
1740 VFS_FIND(fdopendir);
1741 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1744 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1746 SMB_STRUCT_STAT *sbuf)
1749 return handle->fns->readdir_fn(handle, dirp, sbuf);
1752 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1753 DIR *dirp, long offset)
1756 handle->fns->seekdir_fn(handle, dirp, offset);
1759 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1763 return handle->fns->telldir_fn(handle, dirp);
1766 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1769 VFS_FIND(rewind_dir);
1770 handle->fns->rewind_dir_fn(handle, dirp);
1773 int smb_vfs_call_mkdirat(struct vfs_handle_struct *handle,
1774 struct files_struct *dirfsp,
1775 const struct smb_filename *smb_fname,
1779 return handle->fns->mkdirat_fn(handle,
1785 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1789 return handle->fns->closedir_fn(handle, dir);
1792 int smb_vfs_call_openat(struct vfs_handle_struct *handle,
1793 const struct files_struct *dirfsp,
1794 const struct smb_filename *smb_fname,
1795 struct files_struct *fsp,
1800 return handle->fns->openat_fn(handle,
1808 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1809 struct smb_request *req,
1810 struct smb_filename *smb_fname,
1811 uint32_t access_mask,
1812 uint32_t share_access,
1813 uint32_t create_disposition,
1814 uint32_t create_options,
1815 uint32_t file_attributes,
1816 uint32_t oplock_request,
1817 const struct smb2_lease *lease,
1818 uint64_t allocation_size,
1819 uint32_t private_flags,
1820 struct security_descriptor *sd,
1821 struct ea_list *ea_list,
1822 files_struct **result,
1824 const struct smb2_create_blobs *in_context_blobs,
1825 struct smb2_create_blobs *out_context_blobs)
1827 VFS_FIND(create_file);
1828 return handle->fns->create_file_fn(
1829 handle, req, smb_fname,
1830 access_mask, share_access, create_disposition, create_options,
1831 file_attributes, oplock_request, lease, allocation_size,
1832 private_flags, sd, ea_list,
1833 result, pinfo, in_context_blobs, out_context_blobs);
1836 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1837 struct files_struct *fsp)
1840 return handle->fns->close_fn(handle, fsp);
1843 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1844 struct files_struct *fsp, void *data, size_t n,
1848 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1851 struct smb_vfs_call_pread_state {
1852 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1854 struct vfs_aio_state vfs_aio_state;
1857 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1859 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1860 TALLOC_CTX *mem_ctx,
1861 struct tevent_context *ev,
1862 struct files_struct *fsp,
1864 size_t n, off_t offset)
1866 struct tevent_req *req, *subreq;
1867 struct smb_vfs_call_pread_state *state;
1869 req = tevent_req_create(mem_ctx, &state,
1870 struct smb_vfs_call_pread_state);
1874 VFS_FIND(pread_send);
1875 state->recv_fn = handle->fns->pread_recv_fn;
1877 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1879 if (tevent_req_nomem(subreq, req)) {
1880 return tevent_req_post(req, ev);
1882 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1886 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1888 struct tevent_req *req = tevent_req_callback_data(
1889 subreq, struct tevent_req);
1890 struct smb_vfs_call_pread_state *state = tevent_req_data(
1891 req, struct smb_vfs_call_pread_state);
1893 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1894 TALLOC_FREE(subreq);
1895 if (state->retval == -1) {
1896 tevent_req_error(req, state->vfs_aio_state.error);
1899 tevent_req_done(req);
1902 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req,
1903 struct vfs_aio_state *vfs_aio_state)
1905 struct smb_vfs_call_pread_state *state = tevent_req_data(
1906 req, struct smb_vfs_call_pread_state);
1909 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1910 tevent_req_received(req);
1913 *vfs_aio_state = state->vfs_aio_state;
1914 retval = state->retval;
1915 tevent_req_received(req);
1919 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1920 struct files_struct *fsp, const void *data,
1921 size_t n, off_t offset)
1924 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1927 struct smb_vfs_call_pwrite_state {
1928 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1930 struct vfs_aio_state vfs_aio_state;
1933 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1935 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1936 TALLOC_CTX *mem_ctx,
1937 struct tevent_context *ev,
1938 struct files_struct *fsp,
1940 size_t n, off_t offset)
1942 struct tevent_req *req, *subreq;
1943 struct smb_vfs_call_pwrite_state *state;
1945 req = tevent_req_create(mem_ctx, &state,
1946 struct smb_vfs_call_pwrite_state);
1950 VFS_FIND(pwrite_send);
1951 state->recv_fn = handle->fns->pwrite_recv_fn;
1953 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1955 if (tevent_req_nomem(subreq, req)) {
1956 return tevent_req_post(req, ev);
1958 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1962 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1964 struct tevent_req *req = tevent_req_callback_data(
1965 subreq, struct tevent_req);
1966 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1967 req, struct smb_vfs_call_pwrite_state);
1969 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1970 TALLOC_FREE(subreq);
1971 if (state->retval == -1) {
1972 tevent_req_error(req, state->vfs_aio_state.error);
1975 tevent_req_done(req);
1978 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req,
1979 struct vfs_aio_state *vfs_aio_state)
1981 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1982 req, struct smb_vfs_call_pwrite_state);
1985 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1986 tevent_req_received(req);
1989 *vfs_aio_state = state->vfs_aio_state;
1990 retval = state->retval;
1991 tevent_req_received(req);
1995 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1996 struct files_struct *fsp, off_t offset,
2000 return handle->fns->lseek_fn(handle, fsp, offset, whence);
2003 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
2004 files_struct *fromfsp, const DATA_BLOB *header,
2005 off_t offset, size_t count)
2008 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
2012 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
2013 files_struct *tofsp, off_t offset,
2017 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
2020 int smb_vfs_call_renameat(struct vfs_handle_struct *handle,
2021 files_struct *srcfsp,
2022 const struct smb_filename *smb_fname_src,
2023 files_struct *dstfsp,
2024 const struct smb_filename *smb_fname_dst)
2027 return handle->fns->renameat_fn(handle,
2034 struct smb_vfs_call_fsync_state {
2035 int (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
2037 struct vfs_aio_state vfs_aio_state;
2040 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
2042 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
2043 TALLOC_CTX *mem_ctx,
2044 struct tevent_context *ev,
2045 struct files_struct *fsp)
2047 struct tevent_req *req, *subreq;
2048 struct smb_vfs_call_fsync_state *state;
2050 req = tevent_req_create(mem_ctx, &state,
2051 struct smb_vfs_call_fsync_state);
2055 VFS_FIND(fsync_send);
2056 state->recv_fn = handle->fns->fsync_recv_fn;
2058 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
2059 if (tevent_req_nomem(subreq, req)) {
2060 return tevent_req_post(req, ev);
2062 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
2066 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
2068 struct tevent_req *req = tevent_req_callback_data(
2069 subreq, struct tevent_req);
2070 struct smb_vfs_call_fsync_state *state = tevent_req_data(
2071 req, struct smb_vfs_call_fsync_state);
2073 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
2074 TALLOC_FREE(subreq);
2075 if (state->retval == -1) {
2076 tevent_req_error(req, state->vfs_aio_state.error);
2079 tevent_req_done(req);
2082 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state)
2084 struct smb_vfs_call_fsync_state *state = tevent_req_data(
2085 req, struct smb_vfs_call_fsync_state);
2088 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
2089 tevent_req_received(req);
2092 *vfs_aio_state = state->vfs_aio_state;
2093 retval = state->retval;
2094 tevent_req_received(req);
2099 * Synchronous version of fsync, built from backend
2100 * async VFS primitives. Uses a temporary sub-event
2101 * context (NOT NESTED).
2104 int smb_vfs_fsync_sync(files_struct *fsp)
2106 TALLOC_CTX *frame = talloc_stackframe();
2107 struct tevent_req *req = NULL;
2108 struct vfs_aio_state aio_state = { 0 };
2111 struct tevent_context *ev = samba_tevent_context_init(frame);
2117 req = SMB_VFS_FSYNC_SEND(talloc_tos(), ev, fsp);
2122 ok = tevent_req_poll(req, ev);
2127 ret = SMB_VFS_FSYNC_RECV(req, &aio_state);
2132 if (aio_state.error != 0) {
2133 errno = aio_state.error;
2138 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
2139 struct smb_filename *smb_fname)
2142 return handle->fns->stat_fn(handle, smb_fname);
2145 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
2146 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
2149 return handle->fns->fstat_fn(handle, fsp, sbuf);
2152 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
2153 struct smb_filename *smb_filename)
2156 return handle->fns->lstat_fn(handle, smb_filename);
2159 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
2160 struct files_struct *fsp,
2161 const SMB_STRUCT_STAT *sbuf)
2163 VFS_FIND(get_alloc_size);
2164 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
2167 int smb_vfs_call_unlinkat(struct vfs_handle_struct *handle,
2168 struct files_struct *dirfsp,
2169 const struct smb_filename *smb_fname,
2173 return handle->fns->unlinkat_fn(handle,
2179 int smb_vfs_call_chmod(struct vfs_handle_struct *handle,
2180 const struct smb_filename *smb_fname,
2184 return handle->fns->chmod_fn(handle, smb_fname, mode);
2187 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
2188 struct files_struct *fsp, mode_t mode)
2191 return handle->fns->fchmod_fn(handle, fsp, mode);
2194 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
2195 struct files_struct *fsp, uid_t uid, gid_t gid)
2198 return handle->fns->fchown_fn(handle, fsp, uid, gid);
2201 int smb_vfs_call_lchown(struct vfs_handle_struct *handle,
2202 const struct smb_filename *smb_fname,
2207 return handle->fns->lchown_fn(handle, smb_fname, uid, gid);
2210 int smb_vfs_call_chdir(struct vfs_handle_struct *handle,
2211 const struct smb_filename *smb_fname)
2214 return handle->fns->chdir_fn(handle, smb_fname);
2217 struct smb_filename *smb_vfs_call_getwd(struct vfs_handle_struct *handle,
2221 return handle->fns->getwd_fn(handle, ctx);
2224 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
2225 const struct smb_filename *smb_fname,
2226 struct smb_file_time *ft)
2229 return handle->fns->ntimes_fn(handle, smb_fname, ft);
2232 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2233 struct files_struct *fsp, off_t offset)
2235 VFS_FIND(ftruncate);
2236 return handle->fns->ftruncate_fn(handle, fsp, offset);
2239 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2240 struct files_struct *fsp,
2245 VFS_FIND(fallocate);
2246 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2249 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2250 struct files_struct *fsp, uint32_t share_mode,
2251 uint32_t access_mask)
2253 VFS_FIND(kernel_flock);
2254 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2258 int smb_vfs_call_fcntl(struct vfs_handle_struct *handle,
2259 struct files_struct *fsp, int cmd, ...)
2266 va_start(cmd_arg, cmd);
2267 result = handle->fns->fcntl_fn(handle, fsp, cmd, cmd_arg);
2273 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2274 struct files_struct *fsp, int leasetype)
2276 VFS_FIND(linux_setlease);
2277 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2280 int smb_vfs_call_symlinkat(struct vfs_handle_struct *handle,
2281 const struct smb_filename *link_target,
2282 struct files_struct *dirfsp,
2283 const struct smb_filename *new_smb_fname)
2285 VFS_FIND(symlinkat);
2286 return handle->fns->symlinkat_fn(handle,
2292 int smb_vfs_call_readlinkat(struct vfs_handle_struct *handle,
2293 const struct files_struct *dirfsp,
2294 const struct smb_filename *smb_fname,
2298 VFS_FIND(readlinkat);
2299 return handle->fns->readlinkat_fn(handle,
2306 int smb_vfs_call_linkat(struct vfs_handle_struct *handle,
2307 struct files_struct *srcfsp,
2308 const struct smb_filename *old_smb_fname,
2309 struct files_struct *dstfsp,
2310 const struct smb_filename *new_smb_fname,
2314 return handle->fns->linkat_fn(handle,
2322 int smb_vfs_call_mknodat(struct vfs_handle_struct *handle,
2323 struct files_struct *dirfsp,
2324 const struct smb_filename *smb_fname,
2329 return handle->fns->mknodat_fn(handle,
2336 struct smb_filename *smb_vfs_call_realpath(struct vfs_handle_struct *handle,
2338 const struct smb_filename *smb_fname)
2341 return handle->fns->realpath_fn(handle, ctx, smb_fname);
2344 int smb_vfs_call_chflags(struct vfs_handle_struct *handle,
2345 const struct smb_filename *smb_fname,
2349 return handle->fns->chflags_fn(handle, smb_fname, flags);
2352 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2353 const SMB_STRUCT_STAT *sbuf)
2355 VFS_FIND(file_id_create);
2356 return handle->fns->file_id_create_fn(handle, sbuf);
2359 uint64_t smb_vfs_call_fs_file_id(struct vfs_handle_struct *handle,
2360 const SMB_STRUCT_STAT *sbuf)
2362 VFS_FIND(fs_file_id);
2363 return handle->fns->fs_file_id_fn(handle, sbuf);
2366 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2367 struct files_struct *fsp,
2368 const struct smb_filename *smb_fname,
2369 TALLOC_CTX *mem_ctx,
2370 unsigned int *num_streams,
2371 struct stream_struct **streams)
2373 VFS_FIND(streaminfo);
2374 return handle->fns->streaminfo_fn(handle, fsp, smb_fname, mem_ctx,
2375 num_streams, streams);
2378 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2379 const struct smb_filename *path,
2381 TALLOC_CTX *mem_ctx,
2384 VFS_FIND(get_real_filename);
2385 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2389 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2390 const struct smb_filename *smb_fname)
2392 VFS_FIND(connectpath);
2393 return handle->fns->connectpath_fn(handle, smb_fname);
2396 bool smb_vfs_call_strict_lock_check(struct vfs_handle_struct *handle,
2397 struct files_struct *fsp,
2398 struct lock_struct *plock)
2400 VFS_FIND(strict_lock_check);
2401 return handle->fns->strict_lock_check_fn(handle, fsp, plock);
2404 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2406 enum vfs_translate_direction direction,
2407 TALLOC_CTX *mem_ctx,
2410 VFS_FIND(translate_name);
2411 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2415 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2416 struct files_struct *fsp,
2420 const uint8_t *in_data,
2423 uint32_t max_out_len,
2427 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2428 in_data, in_len, out_data, max_out_len,
2432 NTSTATUS smb_vfs_call_get_dos_attributes(struct vfs_handle_struct *handle,
2433 struct smb_filename *smb_fname,
2436 VFS_FIND(get_dos_attributes);
2437 return handle->fns->get_dos_attributes_fn(handle, smb_fname, dosmode);
2440 NTSTATUS smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct *handle,
2441 struct files_struct *fsp,
2444 VFS_FIND(fget_dos_attributes);
2445 return handle->fns->fget_dos_attributes_fn(handle, fsp, dosmode);
2448 NTSTATUS smb_vfs_call_set_dos_attributes(struct vfs_handle_struct *handle,
2449 const struct smb_filename *smb_fname,
2452 VFS_FIND(set_dos_attributes);
2453 return handle->fns->set_dos_attributes_fn(handle, smb_fname, dosmode);
2456 NTSTATUS smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct *handle,
2457 struct files_struct *fsp,
2460 VFS_FIND(set_dos_attributes);
2461 return handle->fns->fset_dos_attributes_fn(handle, fsp, dosmode);
2464 struct tevent_req *smb_vfs_call_offload_read_send(TALLOC_CTX *mem_ctx,
2465 struct tevent_context *ev,
2466 struct vfs_handle_struct *handle,
2467 struct files_struct *fsp,
2473 VFS_FIND(offload_read_send);
2474 return handle->fns->offload_read_send_fn(mem_ctx, ev, handle,
2476 ttl, offset, to_copy);
2479 NTSTATUS smb_vfs_call_offload_read_recv(struct tevent_req *req,
2480 struct vfs_handle_struct *handle,
2481 TALLOC_CTX *mem_ctx,
2482 DATA_BLOB *token_blob)
2484 VFS_FIND(offload_read_recv);
2485 return handle->fns->offload_read_recv_fn(req, handle, mem_ctx, token_blob);
2488 struct tevent_req *smb_vfs_call_offload_write_send(struct vfs_handle_struct *handle,
2489 TALLOC_CTX *mem_ctx,
2490 struct tevent_context *ev,
2493 off_t transfer_offset,
2494 struct files_struct *dest_fsp,
2498 VFS_FIND(offload_write_send);
2499 return handle->fns->offload_write_send_fn(handle, mem_ctx, ev, fsctl,
2500 token, transfer_offset,
2501 dest_fsp, dest_off, num);
2504 NTSTATUS smb_vfs_call_offload_write_recv(struct vfs_handle_struct *handle,
2505 struct tevent_req *req,
2508 VFS_FIND(offload_write_recv);
2509 return handle->fns->offload_write_recv_fn(handle, req, copied);
2512 struct smb_vfs_call_get_dos_attributes_state {
2513 files_struct *dir_fsp;
2514 NTSTATUS (*recv_fn)(struct tevent_req *req,
2515 struct vfs_aio_state *aio_state,
2517 struct vfs_aio_state aio_state;
2518 uint32_t dos_attributes;
2521 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq);
2523 struct tevent_req *smb_vfs_call_get_dos_attributes_send(
2524 TALLOC_CTX *mem_ctx,
2525 struct tevent_context *ev,
2526 struct vfs_handle_struct *handle,
2527 files_struct *dir_fsp,
2528 struct smb_filename *smb_fname)
2530 struct tevent_req *req = NULL;
2531 struct smb_vfs_call_get_dos_attributes_state *state = NULL;
2532 struct tevent_req *subreq = NULL;
2534 req = tevent_req_create(mem_ctx, &state,
2535 struct smb_vfs_call_get_dos_attributes_state);
2540 VFS_FIND(get_dos_attributes_send);
2542 *state = (struct smb_vfs_call_get_dos_attributes_state) {
2544 .recv_fn = handle->fns->get_dos_attributes_recv_fn,
2547 subreq = handle->fns->get_dos_attributes_send_fn(mem_ctx,
2552 if (tevent_req_nomem(subreq, req)) {
2553 return tevent_req_post(req, ev);
2555 tevent_req_defer_callback(req, ev);
2557 tevent_req_set_callback(subreq,
2558 smb_vfs_call_get_dos_attributes_done,
2564 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq)
2566 struct tevent_req *req =
2567 tevent_req_callback_data(subreq,
2569 struct smb_vfs_call_get_dos_attributes_state *state =
2570 tevent_req_data(req,
2571 struct smb_vfs_call_get_dos_attributes_state);
2576 * Make sure we run as the user again
2578 ok = change_to_user_and_service_by_fsp(state->dir_fsp);
2581 status = state->recv_fn(subreq,
2583 &state->dos_attributes);
2584 TALLOC_FREE(subreq);
2585 if (tevent_req_nterror(req, status)) {
2589 tevent_req_done(req);
2592 NTSTATUS smb_vfs_call_get_dos_attributes_recv(
2593 struct tevent_req *req,
2594 struct vfs_aio_state *aio_state,
2595 uint32_t *dos_attributes)
2597 struct smb_vfs_call_get_dos_attributes_state *state =
2598 tevent_req_data(req,
2599 struct smb_vfs_call_get_dos_attributes_state);
2602 if (tevent_req_is_nterror(req, &status)) {
2603 tevent_req_received(req);
2607 *aio_state = state->aio_state;
2608 *dos_attributes = state->dos_attributes;
2609 tevent_req_received(req);
2610 return NT_STATUS_OK;
2613 NTSTATUS smb_vfs_call_get_compression(vfs_handle_struct *handle,
2614 TALLOC_CTX *mem_ctx,
2615 struct files_struct *fsp,
2616 struct smb_filename *smb_fname,
2617 uint16_t *_compression_fmt)
2619 VFS_FIND(get_compression);
2620 return handle->fns->get_compression_fn(handle, mem_ctx, fsp, smb_fname,
2624 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2625 TALLOC_CTX *mem_ctx,
2626 struct files_struct *fsp,
2627 uint16_t compression_fmt)
2629 VFS_FIND(set_compression);
2630 return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2634 NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
2635 TALLOC_CTX *mem_ctx,
2636 const char *service_path,
2639 VFS_FIND(snap_check_path);
2640 return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path,
2644 NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle,
2645 TALLOC_CTX *mem_ctx,
2646 const char *base_volume,
2652 VFS_FIND(snap_create);
2653 return handle->fns->snap_create_fn(handle, mem_ctx, base_volume, tstamp,
2654 rw, base_path, snap_path);
2657 NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle,
2658 TALLOC_CTX *mem_ctx,
2662 VFS_FIND(snap_delete);
2663 return handle->fns->snap_delete_fn(handle, mem_ctx, base_path,
2667 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2668 struct files_struct *fsp,
2669 uint32_t security_info,
2670 TALLOC_CTX *mem_ctx,
2671 struct security_descriptor **ppdesc)
2673 VFS_FIND(fget_nt_acl);
2674 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2678 NTSTATUS smb_vfs_call_get_nt_acl_at(struct vfs_handle_struct *handle,
2679 struct files_struct *dirfsp,
2680 const struct smb_filename *smb_fname,
2681 uint32_t security_info,
2682 TALLOC_CTX *mem_ctx,
2683 struct security_descriptor **ppdesc)
2685 VFS_FIND(get_nt_acl_at);
2686 return handle->fns->get_nt_acl_at_fn(handle,
2694 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2695 struct files_struct *fsp,
2696 uint32_t security_info_sent,
2697 const struct security_descriptor *psd)
2699 VFS_FIND(fset_nt_acl);
2700 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2704 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2705 struct smb_filename *file,
2706 struct security_acl *sacl,
2707 uint32_t access_requested,
2708 uint32_t access_denied)
2710 VFS_FIND(audit_file);
2711 return handle->fns->audit_file_fn(handle,
2718 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2719 const struct smb_filename *smb_fname,
2720 SMB_ACL_TYPE_T type,
2721 TALLOC_CTX *mem_ctx)
2723 VFS_FIND(sys_acl_get_file);
2724 return handle->fns->sys_acl_get_file_fn(handle, smb_fname, type, mem_ctx);
2727 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2728 struct files_struct *fsp,
2729 TALLOC_CTX *mem_ctx)
2731 VFS_FIND(sys_acl_get_fd);
2732 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2735 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2736 const struct smb_filename *smb_fname,
2737 TALLOC_CTX *mem_ctx,
2738 char **blob_description,
2741 VFS_FIND(sys_acl_blob_get_file);
2742 return handle->fns->sys_acl_blob_get_file_fn(handle, smb_fname,
2743 mem_ctx, blob_description, blob);
2746 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2747 struct files_struct *fsp,
2748 TALLOC_CTX *mem_ctx,
2749 char **blob_description,
2752 VFS_FIND(sys_acl_blob_get_fd);
2753 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2756 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2757 const struct smb_filename *smb_fname,
2758 SMB_ACL_TYPE_T acltype,
2761 VFS_FIND(sys_acl_set_file);
2762 return handle->fns->sys_acl_set_file_fn(handle, smb_fname,
2766 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2767 struct files_struct *fsp, SMB_ACL_T theacl)
2769 VFS_FIND(sys_acl_set_fd);
2770 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2773 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2774 const struct smb_filename *smb_fname)
2776 VFS_FIND(sys_acl_delete_def_file);
2777 return handle->fns->sys_acl_delete_def_file_fn(handle, smb_fname);
2780 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2781 const struct smb_filename *smb_fname,
2787 return handle->fns->getxattr_fn(handle, smb_fname, name, value, size);
2791 struct smb_vfs_call_getxattrat_state {
2792 files_struct *dir_fsp;
2793 ssize_t (*recv_fn)(struct tevent_req *req,
2794 struct vfs_aio_state *aio_state,
2795 TALLOC_CTX *mem_ctx,
2796 uint8_t **xattr_value);
2798 uint8_t *xattr_value;
2799 struct vfs_aio_state aio_state;
2802 static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq);
2804 struct tevent_req *smb_vfs_call_getxattrat_send(
2805 TALLOC_CTX *mem_ctx,
2806 struct tevent_context *ev,
2807 struct vfs_handle_struct *handle,
2808 files_struct *dir_fsp,
2809 const struct smb_filename *smb_fname,
2810 const char *xattr_name,
2813 struct tevent_req *req = NULL;
2814 struct smb_vfs_call_getxattrat_state *state = NULL;
2815 struct tevent_req *subreq = NULL;
2817 req = tevent_req_create(mem_ctx, &state,
2818 struct smb_vfs_call_getxattrat_state);
2823 VFS_FIND(getxattrat_send);
2825 *state = (struct smb_vfs_call_getxattrat_state) {
2827 .recv_fn = handle->fns->getxattrat_recv_fn,
2830 subreq = handle->fns->getxattrat_send_fn(mem_ctx,
2837 if (tevent_req_nomem(subreq, req)) {
2838 return tevent_req_post(req, ev);
2840 tevent_req_defer_callback(req, ev);
2842 tevent_req_set_callback(subreq, smb_vfs_call_getxattrat_done, req);
2846 static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq)
2848 struct tevent_req *req = tevent_req_callback_data(
2849 subreq, struct tevent_req);
2850 struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2851 req, struct smb_vfs_call_getxattrat_state);
2855 * Make sure we run as the user again
2857 ok = change_to_user_and_service_by_fsp(state->dir_fsp);
2860 state->retval = state->recv_fn(subreq,
2863 &state->xattr_value);
2864 TALLOC_FREE(subreq);
2865 if (state->retval == -1) {
2866 tevent_req_error(req, state->aio_state.error);
2870 tevent_req_done(req);
2873 ssize_t smb_vfs_call_getxattrat_recv(struct tevent_req *req,
2874 struct vfs_aio_state *aio_state,
2875 TALLOC_CTX *mem_ctx,
2876 uint8_t **xattr_value)
2878 struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2879 req, struct smb_vfs_call_getxattrat_state);
2882 if (tevent_req_is_unix_error(req, &aio_state->error)) {
2883 tevent_req_received(req);
2887 *aio_state = state->aio_state;
2888 xattr_size = state->retval;
2889 if (xattr_value != NULL) {
2890 *xattr_value = talloc_move(mem_ctx, &state->xattr_value);
2893 tevent_req_received(req);
2897 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2898 struct files_struct *fsp, const char *name,
2899 void *value, size_t size)
2901 VFS_FIND(fgetxattr);
2902 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2905 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2906 const struct smb_filename *smb_fname,
2910 VFS_FIND(listxattr);
2911 return handle->fns->listxattr_fn(handle, smb_fname, list, size);
2914 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2915 struct files_struct *fsp, char *list,
2918 VFS_FIND(flistxattr);
2919 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2922 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2923 const struct smb_filename *smb_fname,
2926 VFS_FIND(removexattr);
2927 return handle->fns->removexattr_fn(handle, smb_fname, name);
2930 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2931 struct files_struct *fsp, const char *name)
2933 VFS_FIND(fremovexattr);
2934 return handle->fns->fremovexattr_fn(handle, fsp, name);
2937 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle,
2938 const struct smb_filename *smb_fname,
2945 return handle->fns->setxattr_fn(handle, smb_fname,
2946 name, value, size, flags);
2949 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2950 struct files_struct *fsp, const char *name,
2951 const void *value, size_t size, int flags)
2953 VFS_FIND(fsetxattr);
2954 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2957 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2958 struct files_struct *fsp)
2960 VFS_FIND(aio_force);
2961 return handle->fns->aio_force_fn(handle, fsp);
2964 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2965 struct files_struct *fsp,
2966 TALLOC_CTX *mem_ctx,
2969 VFS_FIND(durable_cookie);
2970 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2973 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2974 struct files_struct *fsp,
2975 const DATA_BLOB old_cookie,
2976 TALLOC_CTX *mem_ctx,
2977 DATA_BLOB *new_cookie)
2979 VFS_FIND(durable_disconnect);
2980 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2981 mem_ctx, new_cookie);
2984 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2985 struct smb_request *smb1req,
2986 struct smbXsrv_open *op,
2987 const DATA_BLOB old_cookie,
2988 TALLOC_CTX *mem_ctx,
2989 struct files_struct **fsp,
2990 DATA_BLOB *new_cookie)
2992 VFS_FIND(durable_reconnect);
2993 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2994 old_cookie, mem_ctx, fsp,
2998 NTSTATUS smb_vfs_call_readdir_attr(struct vfs_handle_struct *handle,
2999 const struct smb_filename *fname,
3000 TALLOC_CTX *mem_ctx,
3001 struct readdir_attr_data **attr_data)
3003 VFS_FIND(readdir_attr);
3004 return handle->fns->readdir_attr_fn(handle, fname, mem_ctx, attr_data);