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
798 if (fsp->fsp_flags.is_pathref) {
802 val = SMB_VFS_FCNTL(fsp, F_GETFL, 0);
813 return SMB_VFS_FCNTL(fsp, F_SETFL, val);
817 /****************************************************************************
818 Transfer some data (n bytes) between two file_struct's.
819 ****************************************************************************/
821 static ssize_t vfs_pread_fn(void *file, void *buf, size_t len, off_t offset)
823 struct files_struct *fsp = (struct files_struct *)file;
825 return SMB_VFS_PREAD(fsp, buf, len, offset);
828 static ssize_t vfs_pwrite_fn(void *file, const void *buf, size_t len, off_t offset)
830 struct files_struct *fsp = (struct files_struct *)file;
832 return SMB_VFS_PWRITE(fsp, buf, len, offset);
835 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
837 return transfer_file_internal((void *)in, (void *)out, n,
838 vfs_pread_fn, vfs_pwrite_fn);
841 /*******************************************************************
842 A vfs_readdir wrapper which just returns the file name.
843 ********************************************************************/
845 const char *vfs_readdirname(connection_struct *conn,
846 struct files_struct *dirfsp,
848 SMB_STRUCT_STAT *sbuf,
851 struct dirent *ptr= NULL;
859 ptr = SMB_VFS_READDIR(conn, dirfsp, (DIR *)p, sbuf);
865 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
866 talloc_tos(), &translated);
867 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
871 *talloced = translated;
872 if (!NT_STATUS_IS_OK(status)) {
878 /*******************************************************************
879 A wrapper for vfs_chdir().
880 ********************************************************************/
882 int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
885 struct smb_filename *cwd = NULL;
888 LastDir = SMB_STRDUP("");
891 if (ISDOT(smb_fname->base_name)) {
893 * passing a '.' is a noop,
894 * and we only expect this after
895 * everything is initialized.
897 * So the first vfs_ChDir() on a given
898 * connection_struct must not be '.'.
900 * Note: conn_new() sets
901 * conn->cwd_fsp->fh->fd = -1
902 * and vfs_ChDir() leaves with
903 * conn->cwd_fsp->fh->fd = AT_FDCWD
906 if (fsp_get_pathref_fd(conn->cwd_fsp) != AT_FDCWD) {
908 * This should never happen and
909 * we might change this to
910 * SMB_ASSERT() in future.
912 DBG_ERR("Called with '.' as first operation!\n");
920 if (smb_fname->base_name[0] == '/' &&
921 strcsequal(LastDir,smb_fname->base_name))
924 * conn->cwd_fsp->fsp_name and the kernel
925 * are already correct, but conn->cwd_fsp->fh->fd
926 * might still be -1 as initialized in conn_new().
928 * This can happen when a client made a 2nd
929 * tree connect to a share with the same underlying
930 * path (may or may not the same share).
932 fsp_set_fd(conn->cwd_fsp, AT_FDCWD);
936 DEBUG(4,("vfs_ChDir to %s\n", smb_fname->base_name));
938 ret = SMB_VFS_CHDIR(conn, smb_fname);
944 * Always replace conn->cwd_fsp. We
945 * don't know if it's been modified by
946 * VFS modules in the stack.
950 cwd = vfs_GetWd(conn, conn);
953 * vfs_GetWd() failed.
954 * We must be able to read cwd.
955 * Return to original directory
958 int saved_errno = errno;
960 if (conn->cwd_fsp->fsp_name == NULL) {
962 * Failed on the very first chdir()+getwd()
963 * for this connection. We can't
966 smb_panic("conn->cwd getwd failed\n");
971 /* Return to the previous $cwd. */
972 ret = SMB_VFS_CHDIR(conn, conn->cwd_fsp->fsp_name);
974 smb_panic("conn->cwd getwd failed\n");
979 /* And fail the chdir(). */
983 /* vfs_GetWd() succeeded. */
984 /* Replace global cache. */
986 LastDir = SMB_STRDUP(smb_fname->base_name);
989 * (Indirect) Callers of vfs_ChDir() may still hold references to the
990 * old conn->cwd_fsp->fsp_name. Move it to talloc_tos(), that way
991 * callers can use it for the lifetime of the SMB request.
993 talloc_move(talloc_tos(), &conn->cwd_fsp->fsp_name);
995 conn->cwd_fsp->fsp_name = talloc_move(conn->cwd_fsp, &cwd);
996 fsp_set_fd(conn->cwd_fsp, AT_FDCWD);
998 DBG_INFO("vfs_ChDir got %s\n", fsp_str_dbg(conn->cwd_fsp));
1003 /*******************************************************************
1004 Return the absolute current directory path - given a UNIX pathname.
1005 Note that this path is returned in DOS format, not UNIX
1006 format. Note this can be called with conn == NULL.
1007 ********************************************************************/
1009 struct smb_filename *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
1011 struct smb_filename *current_dir_fname = NULL;
1013 struct smb_filename *smb_fname_dot = NULL;
1014 struct smb_filename *smb_fname_full = NULL;
1015 struct smb_filename *result = NULL;
1017 if (!lp_getwd_cache()) {
1021 smb_fname_dot = synthetic_smb_fname(ctx,
1027 if (smb_fname_dot == NULL) {
1032 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
1034 * Known to fail for root: the directory may be NFS-mounted
1035 * and exported with root_squash (so has no root access).
1037 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
1038 "(NFS problem ?)\n", strerror(errno) ));
1042 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
1044 smb_fname_full = (struct smb_filename *)memcache_lookup_talloc(
1047 data_blob_const(&key, sizeof(key)));
1049 if (smb_fname_full == NULL) {
1053 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
1054 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
1055 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
1056 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
1059 * Note: smb_fname_full is owned by smbd_memcache()
1060 * so we must make a copy to return.
1062 result = cp_smb_filename(ctx, smb_fname_full);
1063 if (result == NULL) {
1072 * We don't have the information to hand so rely on traditional
1073 * methods. The very slow getcwd, which spawns a process on some
1074 * systems, or the not quite so bad getwd.
1077 current_dir_fname = SMB_VFS_GETWD(conn, ctx);
1078 if (current_dir_fname == NULL) {
1079 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
1084 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
1085 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
1088 * smbd_memcache() will own current_dir_fname after the
1089 * memcache_add_talloc call, so we must make
1090 * a copy on ctx to return.
1092 result = cp_smb_filename(ctx, current_dir_fname);
1093 if (result == NULL) {
1098 * Ensure the memory going into the cache
1099 * doesn't have a destructor so it can be
1102 talloc_set_destructor(current_dir_fname, NULL);
1104 memcache_add_talloc(smbd_memcache(),
1106 data_blob_const(&key, sizeof(key)),
1107 ¤t_dir_fname);
1108 /* current_dir_fname is now == NULL here. */
1110 /* current_dir_fname is already allocated on ctx. */
1111 result = current_dir_fname;
1115 TALLOC_FREE(smb_fname_dot);
1117 * Don't free current_dir_fname here. It's either been moved
1118 * to the memcache or is being returned in result.
1123 /*******************************************************************
1124 Reduce a file name, removing .. elements and checking that
1125 it is below dir in the hierarchy. This uses realpath.
1126 This function must run as root, and will return names
1127 and valid stat structs that can be checked on open.
1128 ********************************************************************/
1130 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
1131 const struct smb_filename *smb_fname,
1132 struct smb_request *smbreq)
1135 TALLOC_CTX *ctx = talloc_tos();
1136 const char *conn_rootdir;
1138 char *resolved_name = NULL;
1139 struct smb_filename *resolved_fname = NULL;
1140 struct smb_filename *saved_dir_fname = NULL;
1141 struct smb_filename *smb_fname_cwd = NULL;
1143 struct smb_filename *parent_name = NULL;
1144 struct smb_filename *file_name = NULL;
1147 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
1148 smb_fname->base_name,
1149 conn->connectpath));
1152 ok = parent_smb_fname(ctx,
1157 status = NT_STATUS_NO_MEMORY;
1161 if (SMB_VFS_STAT(conn, parent_name) != 0) {
1162 status = map_nt_error_from_unix(errno);
1165 /* Remember where we were. */
1166 saved_dir_fname = vfs_GetWd(ctx, conn);
1167 if (!saved_dir_fname) {
1168 status = map_nt_error_from_unix(errno);
1172 if (vfs_ChDir(conn, parent_name) == -1) {
1173 status = map_nt_error_from_unix(errno);
1177 smb_fname_cwd = synthetic_smb_fname(talloc_tos(),
1183 if (smb_fname_cwd == NULL) {
1184 status = NT_STATUS_NO_MEMORY;
1188 /* Get the absolute path of the parent directory. */
1189 resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname_cwd);
1190 if (resolved_fname == NULL) {
1191 status = map_nt_error_from_unix(errno);
1194 resolved_name = resolved_fname->base_name;
1196 if (*resolved_name != '/') {
1197 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1198 "doesn't return absolute paths !\n"));
1199 status = NT_STATUS_OBJECT_NAME_INVALID;
1203 DBG_DEBUG("realpath [%s] -> [%s]\n",
1204 smb_fname_str_dbg(parent_name),
1207 /* Now check the stat value is the same. */
1208 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1209 status = map_nt_error_from_unix(errno);
1213 /* Ensure we're pointing at the same place. */
1214 if (!check_same_stat(&smb_fname_cwd->st, &parent_name->st)) {
1215 DBG_ERR("device/inode/uid/gid on directory %s changed. "
1216 "Denying access !\n",
1217 smb_fname_str_dbg(parent_name));
1218 status = NT_STATUS_ACCESS_DENIED;
1222 /* Ensure we're below the connect path. */
1224 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
1225 if (conn_rootdir == NULL) {
1226 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1228 status = NT_STATUS_ACCESS_DENIED;
1232 rootdir_len = strlen(conn_rootdir);
1235 * In the case of rootdir_len == 1, we know that conn_rootdir is
1236 * "/", and we also know that resolved_name starts with a slash.
1237 * So, in this corner case, resolved_name is automatically a
1238 * sub-directory of the conn_rootdir. Thus we can skip the string
1239 * comparison and the next character checks (which are even
1240 * wrong in this case).
1242 if (rootdir_len != 1) {
1245 matched = (strncmp(conn_rootdir, resolved_name,
1248 if (!matched || (resolved_name[rootdir_len] != '/' &&
1249 resolved_name[rootdir_len] != '\0')) {
1250 DBG_WARNING("%s is a symlink outside the "
1252 smb_fname_str_dbg(parent_name));
1253 DEBUGADD(1, ("conn_rootdir =%s\n", conn_rootdir));
1254 DEBUGADD(1, ("resolved_name=%s\n", resolved_name));
1255 status = NT_STATUS_ACCESS_DENIED;
1260 /* Now ensure that the last component either doesn't
1261 exist, or is *NOT* a symlink. */
1263 ret = SMB_VFS_LSTAT(conn, file_name);
1265 /* Errno must be ENOENT for this be ok. */
1266 if (errno != ENOENT) {
1267 status = map_nt_error_from_unix(errno);
1268 DBG_WARNING("LSTAT on %s failed with %s\n",
1269 smb_fname_str_dbg(file_name),
1275 if (VALID_STAT(file_name->st) &&
1276 S_ISLNK(file_name->st.st_ex_mode))
1278 DBG_WARNING("Last component %s is a symlink. Denying"
1280 smb_fname_str_dbg(file_name));
1281 status = NT_STATUS_ACCESS_DENIED;
1285 status = NT_STATUS_OK;
1289 if (saved_dir_fname != NULL) {
1290 vfs_ChDir(conn, saved_dir_fname);
1291 TALLOC_FREE(saved_dir_fname);
1293 TALLOC_FREE(resolved_fname);
1294 TALLOC_FREE(parent_name);
1298 /*******************************************************************
1299 Reduce a file name, removing .. elements and checking that
1300 it is below dir in the hierarchy. This uses realpath.
1302 If cwd_name == NULL then fname is a client given path relative
1303 to the root path of the share.
1305 If cwd_name != NULL then fname is a client given path relative
1306 to cwd_name. cwd_name is relative to the root path of the share.
1307 ********************************************************************/
1309 NTSTATUS check_reduced_name(connection_struct *conn,
1310 const struct smb_filename *cwd_fname,
1311 const struct smb_filename *smb_fname)
1313 TALLOC_CTX *ctx = talloc_tos();
1314 const char *cwd_name = cwd_fname ? cwd_fname->base_name : NULL;
1315 const char *fname = smb_fname->base_name;
1316 struct smb_filename *resolved_fname;
1317 char *resolved_name = NULL;
1318 char *new_fname = NULL;
1319 bool allow_symlinks = true;
1320 const char *conn_rootdir;
1324 DBG_DEBUG("check_reduced_name [%s] [%s]\n", fname, conn->connectpath);
1326 resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname);
1328 if (resolved_fname == NULL) {
1329 struct smb_filename *dir_fname = NULL;
1330 struct smb_filename *last_component = NULL;
1332 if (errno == ENOTDIR) {
1333 DBG_NOTICE("Component not a directory in getting "
1334 "realpath for %s\n",
1336 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1338 if (errno != ENOENT) {
1339 NTSTATUS status = map_nt_error_from_unix(errno);
1340 DBG_NOTICE("couldn't get realpath for %s: %s\n",
1346 /* errno == ENOENT */
1349 * Last component didn't exist. Remove it and try and
1350 * canonicalise the directory name.
1353 ok = parent_smb_fname(ctx,
1358 return NT_STATUS_NO_MEMORY;
1361 resolved_fname = SMB_VFS_REALPATH(conn, ctx, dir_fname);
1362 if (resolved_fname == NULL) {
1363 NTSTATUS status = map_nt_error_from_unix(errno);
1365 if (errno == ENOENT || errno == ENOTDIR) {
1366 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1369 DBG_NOTICE("couldn't get realpath for "
1371 smb_fname_str_dbg(dir_fname),
1375 resolved_name = talloc_asprintf(ctx,
1377 resolved_fname->base_name,
1378 last_component->base_name);
1379 if (resolved_name == NULL) {
1380 return NT_STATUS_NO_MEMORY;
1383 resolved_name = resolved_fname->base_name;
1386 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1389 if (*resolved_name != '/') {
1390 DEBUG(0,("check_reduced_name: realpath doesn't return "
1391 "absolute paths !\n"));
1392 TALLOC_FREE(resolved_fname);
1393 return NT_STATUS_OBJECT_NAME_INVALID;
1396 /* Common widelinks and symlinks checks. */
1397 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
1398 if (conn_rootdir == NULL) {
1399 DBG_NOTICE("Could not get conn_rootdir\n");
1400 TALLOC_FREE(resolved_fname);
1401 return NT_STATUS_ACCESS_DENIED;
1404 rootdir_len = strlen(conn_rootdir);
1407 * In the case of rootdir_len == 1, we know that
1408 * conn_rootdir is "/", and we also know that
1409 * resolved_name starts with a slash. So, in this
1410 * corner case, resolved_name is automatically a
1411 * sub-directory of the conn_rootdir. Thus we can skip
1412 * the string comparison and the next character checks
1413 * (which are even wrong in this case).
1415 if (rootdir_len != 1) {
1418 matched = (strncmp(conn_rootdir, resolved_name,
1420 if (!matched || (resolved_name[rootdir_len] != '/' &&
1421 resolved_name[rootdir_len] != '\0')) {
1422 DBG_NOTICE("Bad access attempt: %s is a symlink "
1425 "conn_rootdir =%s\n"
1426 "resolved_name=%s\n",
1430 TALLOC_FREE(resolved_fname);
1431 return NT_STATUS_ACCESS_DENIED;
1435 /* Extra checks if all symlinks are disallowed. */
1436 allow_symlinks = lp_follow_symlinks(SNUM(conn));
1437 if (!allow_symlinks) {
1438 /* fname can't have changed in resolved_path. */
1439 const char *p = &resolved_name[rootdir_len];
1442 * UNIX filesystem semantics, names consisting
1443 * only of "." or ".." CANNOT be symlinks.
1445 if (ISDOT(fname) || ISDOTDOT(fname)) {
1450 DBG_NOTICE("logic error (%c) "
1451 "in resolved_name: %s\n",
1454 TALLOC_FREE(resolved_fname);
1455 return NT_STATUS_ACCESS_DENIED;
1461 * If cwd_name is present and not ".",
1462 * then fname is relative to that, not
1463 * the root of the share. Make sure the
1464 * path we check is the one the client
1465 * sent (cwd_name+fname).
1467 if (cwd_name != NULL && !ISDOT(cwd_name)) {
1468 new_fname = talloc_asprintf(ctx,
1472 if (new_fname == NULL) {
1473 TALLOC_FREE(resolved_fname);
1474 return NT_STATUS_NO_MEMORY;
1479 if (strcmp(fname, p)!=0) {
1480 DBG_NOTICE("Bad access "
1481 "attempt: %s is a symlink to %s\n",
1484 TALLOC_FREE(resolved_fname);
1485 TALLOC_FREE(new_fname);
1486 return NT_STATUS_ACCESS_DENIED;
1492 DBG_INFO("%s reduced to %s\n", fname, resolved_name);
1493 TALLOC_FREE(resolved_fname);
1494 TALLOC_FREE(new_fname);
1495 return NT_STATUS_OK;
1499 * Ensure LSTAT is called for POSIX paths.
1501 int vfs_stat(struct connection_struct *conn,
1502 struct smb_filename *smb_fname)
1504 if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) {
1505 return SMB_VFS_LSTAT(conn, smb_fname);
1507 return SMB_VFS_STAT(conn, smb_fname);
1511 * XXX: This is temporary and there should be no callers of this once
1512 * smb_filename is plumbed through all path based operations.
1514 * Called when we know stream name parsing has already been done.
1516 int vfs_stat_smb_basename(struct connection_struct *conn,
1517 const struct smb_filename *smb_fname_in,
1518 SMB_STRUCT_STAT *psbuf)
1520 struct smb_filename smb_fname = {
1521 .base_name = discard_const_p(char, smb_fname_in->base_name),
1522 .flags = smb_fname_in->flags,
1523 .twrp = smb_fname_in->twrp,
1527 if (smb_fname.flags & SMB_FILENAME_POSIX_PATH) {
1528 ret = SMB_VFS_LSTAT(conn, &smb_fname);
1530 ret = SMB_VFS_STAT(conn, &smb_fname);
1534 *psbuf = smb_fname.st;
1540 * Ensure LSTAT is called for POSIX paths.
1543 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1546 struct stat_ex saved_stat = fsp->fsp_name->st;
1548 if (fsp_get_pathref_fd(fsp) == -1) {
1549 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1550 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1552 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1555 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
1558 return map_nt_error_from_unix(errno);
1560 update_stat_ex_from_saved_stat(&fsp->fsp_name->st, &saved_stat);
1561 return NT_STATUS_OK;
1564 void init_smb_file_time(struct smb_file_time *ft)
1566 *ft = (struct smb_file_time) {
1567 .atime = make_omit_timespec(),
1568 .ctime = make_omit_timespec(),
1569 .mtime = make_omit_timespec(),
1570 .create_time = make_omit_timespec()
1575 * Initialize num_streams and streams, then call VFS op streaminfo
1577 NTSTATUS vfs_streaminfo(connection_struct *conn,
1578 struct files_struct *fsp,
1579 const struct smb_filename *smb_fname,
1580 TALLOC_CTX *mem_ctx,
1581 unsigned int *num_streams,
1582 struct stream_struct **streams)
1586 return SMB_VFS_STREAMINFO(conn,
1594 int vfs_fake_fd(void)
1600 * Return a valid fd, but ensure any attempt to use
1601 * it returns an error (EPIPE).
1603 ret = pipe(pipe_fds);
1613 generate a file_id from a stat structure
1615 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1617 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1620 NTSTATUS vfs_at_fspcwd(TALLOC_CTX *mem_ctx,
1621 struct connection_struct *conn,
1622 struct files_struct **_fsp)
1624 struct files_struct *fsp = NULL;
1626 fsp = talloc_zero(mem_ctx, struct files_struct);
1628 return NT_STATUS_NO_MEMORY;
1631 fsp->fsp_name = synthetic_smb_fname(fsp, ".", NULL, NULL, 0, 0);
1632 if (fsp->fsp_name == NULL) {
1634 return NT_STATUS_NO_MEMORY;
1637 fsp->fh = fd_handle_create(fsp);
1638 if (fsp->fh == NULL) {
1640 return NT_STATUS_NO_MEMORY;
1643 fsp_set_fd(fsp, AT_FDCWD);
1644 fsp->fnum = FNUM_FIELD_INVALID;
1648 return NT_STATUS_OK;
1651 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1652 const char *service, const char *user)
1655 return handle->fns->connect_fn(handle, service, user);
1658 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1660 VFS_FIND(disconnect);
1661 handle->fns->disconnect_fn(handle);
1664 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1665 const struct smb_filename *smb_fname,
1670 VFS_FIND(disk_free);
1671 return handle->fns->disk_free_fn(handle, smb_fname,
1672 bsize, dfree, dsize);
1675 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1676 const struct smb_filename *smb_fname,
1677 enum SMB_QUOTA_TYPE qtype,
1681 VFS_FIND(get_quota);
1682 return handle->fns->get_quota_fn(handle, smb_fname, qtype, id, qt);
1685 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1686 enum SMB_QUOTA_TYPE qtype, unid_t id,
1689 VFS_FIND(set_quota);
1690 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1693 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1694 struct files_struct *fsp,
1695 struct shadow_copy_data *shadow_copy_data,
1698 VFS_FIND(get_shadow_copy_data);
1699 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1703 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle,
1704 const struct smb_filename *smb_fname,
1705 struct vfs_statvfs_struct *statbuf)
1708 return handle->fns->statvfs_fn(handle, smb_fname, statbuf);
1711 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1712 enum timestamp_set_resolution *p_ts_res)
1714 VFS_FIND(fs_capabilities);
1715 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1718 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1719 struct dfs_GetDFSReferral *r)
1721 VFS_FIND(get_dfs_referrals);
1722 return handle->fns->get_dfs_referrals_fn(handle, r);
1725 NTSTATUS smb_vfs_call_create_dfs_pathat(struct vfs_handle_struct *handle,
1726 struct files_struct *dirfsp,
1727 const struct smb_filename *smb_fname,
1728 const struct referral *reflist,
1729 size_t referral_count)
1731 VFS_FIND(create_dfs_pathat);
1732 return handle->fns->create_dfs_pathat_fn(handle,
1739 NTSTATUS smb_vfs_call_read_dfs_pathat(struct vfs_handle_struct *handle,
1740 TALLOC_CTX *mem_ctx,
1741 struct files_struct *dirfsp,
1742 struct smb_filename *smb_fname,
1743 struct referral **ppreflist,
1744 size_t *preferral_count)
1746 VFS_FIND(read_dfs_pathat);
1747 return handle->fns->read_dfs_pathat_fn(handle,
1755 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1756 struct files_struct *fsp,
1758 uint32_t attributes)
1760 VFS_FIND(fdopendir);
1761 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1764 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1765 struct files_struct *dirfsp,
1767 SMB_STRUCT_STAT *sbuf)
1770 return handle->fns->readdir_fn(handle, dirfsp, dirp, sbuf);
1773 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1774 DIR *dirp, long offset)
1777 handle->fns->seekdir_fn(handle, dirp, offset);
1780 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1784 return handle->fns->telldir_fn(handle, dirp);
1787 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1790 VFS_FIND(rewind_dir);
1791 handle->fns->rewind_dir_fn(handle, dirp);
1794 int smb_vfs_call_mkdirat(struct vfs_handle_struct *handle,
1795 struct files_struct *dirfsp,
1796 const struct smb_filename *smb_fname,
1800 return handle->fns->mkdirat_fn(handle,
1806 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1810 return handle->fns->closedir_fn(handle, dir);
1813 int smb_vfs_call_openat(struct vfs_handle_struct *handle,
1814 const struct files_struct *dirfsp,
1815 const struct smb_filename *smb_fname,
1816 struct files_struct *fsp,
1821 return handle->fns->openat_fn(handle,
1829 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1830 struct smb_request *req,
1831 struct smb_filename *smb_fname,
1832 uint32_t access_mask,
1833 uint32_t share_access,
1834 uint32_t create_disposition,
1835 uint32_t create_options,
1836 uint32_t file_attributes,
1837 uint32_t oplock_request,
1838 const struct smb2_lease *lease,
1839 uint64_t allocation_size,
1840 uint32_t private_flags,
1841 struct security_descriptor *sd,
1842 struct ea_list *ea_list,
1843 files_struct **result,
1845 const struct smb2_create_blobs *in_context_blobs,
1846 struct smb2_create_blobs *out_context_blobs)
1848 VFS_FIND(create_file);
1849 return handle->fns->create_file_fn(
1850 handle, req, smb_fname,
1851 access_mask, share_access, create_disposition, create_options,
1852 file_attributes, oplock_request, lease, allocation_size,
1853 private_flags, sd, ea_list,
1854 result, pinfo, in_context_blobs, out_context_blobs);
1857 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1858 struct files_struct *fsp)
1861 return handle->fns->close_fn(handle, fsp);
1864 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1865 struct files_struct *fsp, void *data, size_t n,
1869 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1872 struct smb_vfs_call_pread_state {
1873 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1875 struct vfs_aio_state vfs_aio_state;
1878 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1880 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1881 TALLOC_CTX *mem_ctx,
1882 struct tevent_context *ev,
1883 struct files_struct *fsp,
1885 size_t n, off_t offset)
1887 struct tevent_req *req, *subreq;
1888 struct smb_vfs_call_pread_state *state;
1890 req = tevent_req_create(mem_ctx, &state,
1891 struct smb_vfs_call_pread_state);
1895 VFS_FIND(pread_send);
1896 state->recv_fn = handle->fns->pread_recv_fn;
1898 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1900 if (tevent_req_nomem(subreq, req)) {
1901 return tevent_req_post(req, ev);
1903 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1907 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1909 struct tevent_req *req = tevent_req_callback_data(
1910 subreq, struct tevent_req);
1911 struct smb_vfs_call_pread_state *state = tevent_req_data(
1912 req, struct smb_vfs_call_pread_state);
1914 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1915 TALLOC_FREE(subreq);
1916 if (state->retval == -1) {
1917 tevent_req_error(req, state->vfs_aio_state.error);
1920 tevent_req_done(req);
1923 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req,
1924 struct vfs_aio_state *vfs_aio_state)
1926 struct smb_vfs_call_pread_state *state = tevent_req_data(
1927 req, struct smb_vfs_call_pread_state);
1930 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1931 tevent_req_received(req);
1934 *vfs_aio_state = state->vfs_aio_state;
1935 retval = state->retval;
1936 tevent_req_received(req);
1940 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1941 struct files_struct *fsp, const void *data,
1942 size_t n, off_t offset)
1945 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1948 struct smb_vfs_call_pwrite_state {
1949 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1951 struct vfs_aio_state vfs_aio_state;
1954 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1956 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1957 TALLOC_CTX *mem_ctx,
1958 struct tevent_context *ev,
1959 struct files_struct *fsp,
1961 size_t n, off_t offset)
1963 struct tevent_req *req, *subreq;
1964 struct smb_vfs_call_pwrite_state *state;
1966 req = tevent_req_create(mem_ctx, &state,
1967 struct smb_vfs_call_pwrite_state);
1971 VFS_FIND(pwrite_send);
1972 state->recv_fn = handle->fns->pwrite_recv_fn;
1974 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1976 if (tevent_req_nomem(subreq, req)) {
1977 return tevent_req_post(req, ev);
1979 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1983 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1985 struct tevent_req *req = tevent_req_callback_data(
1986 subreq, struct tevent_req);
1987 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1988 req, struct smb_vfs_call_pwrite_state);
1990 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1991 TALLOC_FREE(subreq);
1992 if (state->retval == -1) {
1993 tevent_req_error(req, state->vfs_aio_state.error);
1996 tevent_req_done(req);
1999 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req,
2000 struct vfs_aio_state *vfs_aio_state)
2002 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
2003 req, struct smb_vfs_call_pwrite_state);
2006 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
2007 tevent_req_received(req);
2010 *vfs_aio_state = state->vfs_aio_state;
2011 retval = state->retval;
2012 tevent_req_received(req);
2016 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
2017 struct files_struct *fsp, off_t offset,
2021 return handle->fns->lseek_fn(handle, fsp, offset, whence);
2024 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
2025 files_struct *fromfsp, const DATA_BLOB *header,
2026 off_t offset, size_t count)
2029 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
2033 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
2034 files_struct *tofsp, off_t offset,
2038 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
2041 int smb_vfs_call_renameat(struct vfs_handle_struct *handle,
2042 files_struct *srcfsp,
2043 const struct smb_filename *smb_fname_src,
2044 files_struct *dstfsp,
2045 const struct smb_filename *smb_fname_dst)
2048 return handle->fns->renameat_fn(handle,
2055 struct smb_vfs_call_fsync_state {
2056 int (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
2058 struct vfs_aio_state vfs_aio_state;
2061 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
2063 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
2064 TALLOC_CTX *mem_ctx,
2065 struct tevent_context *ev,
2066 struct files_struct *fsp)
2068 struct tevent_req *req, *subreq;
2069 struct smb_vfs_call_fsync_state *state;
2071 req = tevent_req_create(mem_ctx, &state,
2072 struct smb_vfs_call_fsync_state);
2076 VFS_FIND(fsync_send);
2077 state->recv_fn = handle->fns->fsync_recv_fn;
2079 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
2080 if (tevent_req_nomem(subreq, req)) {
2081 return tevent_req_post(req, ev);
2083 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
2087 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
2089 struct tevent_req *req = tevent_req_callback_data(
2090 subreq, struct tevent_req);
2091 struct smb_vfs_call_fsync_state *state = tevent_req_data(
2092 req, struct smb_vfs_call_fsync_state);
2094 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
2095 TALLOC_FREE(subreq);
2096 if (state->retval == -1) {
2097 tevent_req_error(req, state->vfs_aio_state.error);
2100 tevent_req_done(req);
2103 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state)
2105 struct smb_vfs_call_fsync_state *state = tevent_req_data(
2106 req, struct smb_vfs_call_fsync_state);
2109 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
2110 tevent_req_received(req);
2113 *vfs_aio_state = state->vfs_aio_state;
2114 retval = state->retval;
2115 tevent_req_received(req);
2120 * Synchronous version of fsync, built from backend
2121 * async VFS primitives. Uses a temporary sub-event
2122 * context (NOT NESTED).
2125 int smb_vfs_fsync_sync(files_struct *fsp)
2127 TALLOC_CTX *frame = talloc_stackframe();
2128 struct tevent_req *req = NULL;
2129 struct vfs_aio_state aio_state = { 0 };
2132 struct tevent_context *ev = samba_tevent_context_init(frame);
2138 req = SMB_VFS_FSYNC_SEND(talloc_tos(), ev, fsp);
2143 ok = tevent_req_poll(req, ev);
2148 ret = SMB_VFS_FSYNC_RECV(req, &aio_state);
2153 if (aio_state.error != 0) {
2154 errno = aio_state.error;
2159 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
2160 struct smb_filename *smb_fname)
2163 return handle->fns->stat_fn(handle, smb_fname);
2166 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
2167 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
2170 return handle->fns->fstat_fn(handle, fsp, sbuf);
2173 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
2174 struct smb_filename *smb_filename)
2177 return handle->fns->lstat_fn(handle, smb_filename);
2180 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
2181 struct files_struct *fsp,
2182 const SMB_STRUCT_STAT *sbuf)
2184 VFS_FIND(get_alloc_size);
2185 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
2188 int smb_vfs_call_unlinkat(struct vfs_handle_struct *handle,
2189 struct files_struct *dirfsp,
2190 const struct smb_filename *smb_fname,
2194 return handle->fns->unlinkat_fn(handle,
2200 int smb_vfs_call_chmod(struct vfs_handle_struct *handle,
2201 const struct smb_filename *smb_fname,
2205 return handle->fns->chmod_fn(handle, smb_fname, mode);
2208 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
2209 struct files_struct *fsp, mode_t mode)
2212 return handle->fns->fchmod_fn(handle, fsp, mode);
2215 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
2216 struct files_struct *fsp, uid_t uid, gid_t gid)
2219 return handle->fns->fchown_fn(handle, fsp, uid, gid);
2222 int smb_vfs_call_lchown(struct vfs_handle_struct *handle,
2223 const struct smb_filename *smb_fname,
2228 return handle->fns->lchown_fn(handle, smb_fname, uid, gid);
2231 int smb_vfs_call_chdir(struct vfs_handle_struct *handle,
2232 const struct smb_filename *smb_fname)
2235 return handle->fns->chdir_fn(handle, smb_fname);
2238 struct smb_filename *smb_vfs_call_getwd(struct vfs_handle_struct *handle,
2242 return handle->fns->getwd_fn(handle, ctx);
2245 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
2246 const struct smb_filename *smb_fname,
2247 struct smb_file_time *ft)
2250 return handle->fns->ntimes_fn(handle, smb_fname, ft);
2253 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2254 struct files_struct *fsp, off_t offset)
2256 VFS_FIND(ftruncate);
2257 return handle->fns->ftruncate_fn(handle, fsp, offset);
2260 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2261 struct files_struct *fsp,
2266 VFS_FIND(fallocate);
2267 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2270 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2271 struct files_struct *fsp, uint32_t share_mode,
2272 uint32_t access_mask)
2274 VFS_FIND(kernel_flock);
2275 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2279 int smb_vfs_call_fcntl(struct vfs_handle_struct *handle,
2280 struct files_struct *fsp, int cmd, ...)
2287 va_start(cmd_arg, cmd);
2288 result = handle->fns->fcntl_fn(handle, fsp, cmd, cmd_arg);
2294 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2295 struct files_struct *fsp, int leasetype)
2297 VFS_FIND(linux_setlease);
2298 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2301 int smb_vfs_call_symlinkat(struct vfs_handle_struct *handle,
2302 const struct smb_filename *link_target,
2303 struct files_struct *dirfsp,
2304 const struct smb_filename *new_smb_fname)
2306 VFS_FIND(symlinkat);
2307 return handle->fns->symlinkat_fn(handle,
2313 int smb_vfs_call_readlinkat(struct vfs_handle_struct *handle,
2314 const struct files_struct *dirfsp,
2315 const struct smb_filename *smb_fname,
2319 VFS_FIND(readlinkat);
2320 return handle->fns->readlinkat_fn(handle,
2327 int smb_vfs_call_linkat(struct vfs_handle_struct *handle,
2328 struct files_struct *srcfsp,
2329 const struct smb_filename *old_smb_fname,
2330 struct files_struct *dstfsp,
2331 const struct smb_filename *new_smb_fname,
2335 return handle->fns->linkat_fn(handle,
2343 int smb_vfs_call_mknodat(struct vfs_handle_struct *handle,
2344 struct files_struct *dirfsp,
2345 const struct smb_filename *smb_fname,
2350 return handle->fns->mknodat_fn(handle,
2357 struct smb_filename *smb_vfs_call_realpath(struct vfs_handle_struct *handle,
2359 const struct smb_filename *smb_fname)
2362 return handle->fns->realpath_fn(handle, ctx, smb_fname);
2365 int smb_vfs_call_chflags(struct vfs_handle_struct *handle,
2366 const struct smb_filename *smb_fname,
2370 return handle->fns->chflags_fn(handle, smb_fname, flags);
2373 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2374 const SMB_STRUCT_STAT *sbuf)
2376 VFS_FIND(file_id_create);
2377 return handle->fns->file_id_create_fn(handle, sbuf);
2380 uint64_t smb_vfs_call_fs_file_id(struct vfs_handle_struct *handle,
2381 const SMB_STRUCT_STAT *sbuf)
2383 VFS_FIND(fs_file_id);
2384 return handle->fns->fs_file_id_fn(handle, sbuf);
2387 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2388 struct files_struct *fsp,
2389 const struct smb_filename *smb_fname,
2390 TALLOC_CTX *mem_ctx,
2391 unsigned int *num_streams,
2392 struct stream_struct **streams)
2394 VFS_FIND(streaminfo);
2395 return handle->fns->streaminfo_fn(handle, fsp, smb_fname, mem_ctx,
2396 num_streams, streams);
2399 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2400 const struct smb_filename *path,
2402 TALLOC_CTX *mem_ctx,
2405 VFS_FIND(get_real_filename);
2406 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2410 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2411 const struct smb_filename *smb_fname)
2413 VFS_FIND(connectpath);
2414 return handle->fns->connectpath_fn(handle, smb_fname);
2417 bool smb_vfs_call_strict_lock_check(struct vfs_handle_struct *handle,
2418 struct files_struct *fsp,
2419 struct lock_struct *plock)
2421 VFS_FIND(strict_lock_check);
2422 return handle->fns->strict_lock_check_fn(handle, fsp, plock);
2425 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2427 enum vfs_translate_direction direction,
2428 TALLOC_CTX *mem_ctx,
2431 VFS_FIND(translate_name);
2432 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2436 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2437 struct files_struct *fsp,
2441 const uint8_t *in_data,
2444 uint32_t max_out_len,
2448 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2449 in_data, in_len, out_data, max_out_len,
2453 NTSTATUS smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct *handle,
2454 struct files_struct *fsp,
2457 VFS_FIND(fget_dos_attributes);
2458 return handle->fns->fget_dos_attributes_fn(handle, fsp, dosmode);
2461 NTSTATUS smb_vfs_call_set_dos_attributes(struct vfs_handle_struct *handle,
2462 const struct smb_filename *smb_fname,
2465 VFS_FIND(set_dos_attributes);
2466 return handle->fns->set_dos_attributes_fn(handle, smb_fname, dosmode);
2469 NTSTATUS smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct *handle,
2470 struct files_struct *fsp,
2473 VFS_FIND(set_dos_attributes);
2474 return handle->fns->fset_dos_attributes_fn(handle, fsp, dosmode);
2477 struct tevent_req *smb_vfs_call_offload_read_send(TALLOC_CTX *mem_ctx,
2478 struct tevent_context *ev,
2479 struct vfs_handle_struct *handle,
2480 struct files_struct *fsp,
2486 VFS_FIND(offload_read_send);
2487 return handle->fns->offload_read_send_fn(mem_ctx, ev, handle,
2489 ttl, offset, to_copy);
2492 NTSTATUS smb_vfs_call_offload_read_recv(struct tevent_req *req,
2493 struct vfs_handle_struct *handle,
2494 TALLOC_CTX *mem_ctx,
2495 DATA_BLOB *token_blob)
2497 VFS_FIND(offload_read_recv);
2498 return handle->fns->offload_read_recv_fn(req, handle, mem_ctx, token_blob);
2501 struct tevent_req *smb_vfs_call_offload_write_send(struct vfs_handle_struct *handle,
2502 TALLOC_CTX *mem_ctx,
2503 struct tevent_context *ev,
2506 off_t transfer_offset,
2507 struct files_struct *dest_fsp,
2511 VFS_FIND(offload_write_send);
2512 return handle->fns->offload_write_send_fn(handle, mem_ctx, ev, fsctl,
2513 token, transfer_offset,
2514 dest_fsp, dest_off, num);
2517 NTSTATUS smb_vfs_call_offload_write_recv(struct vfs_handle_struct *handle,
2518 struct tevent_req *req,
2521 VFS_FIND(offload_write_recv);
2522 return handle->fns->offload_write_recv_fn(handle, req, copied);
2525 struct smb_vfs_call_get_dos_attributes_state {
2526 files_struct *dir_fsp;
2527 NTSTATUS (*recv_fn)(struct tevent_req *req,
2528 struct vfs_aio_state *aio_state,
2530 struct vfs_aio_state aio_state;
2531 uint32_t dos_attributes;
2534 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq);
2536 struct tevent_req *smb_vfs_call_get_dos_attributes_send(
2537 TALLOC_CTX *mem_ctx,
2538 struct tevent_context *ev,
2539 struct vfs_handle_struct *handle,
2540 files_struct *dir_fsp,
2541 struct smb_filename *smb_fname)
2543 struct tevent_req *req = NULL;
2544 struct smb_vfs_call_get_dos_attributes_state *state = NULL;
2545 struct tevent_req *subreq = NULL;
2547 req = tevent_req_create(mem_ctx, &state,
2548 struct smb_vfs_call_get_dos_attributes_state);
2553 VFS_FIND(get_dos_attributes_send);
2555 *state = (struct smb_vfs_call_get_dos_attributes_state) {
2557 .recv_fn = handle->fns->get_dos_attributes_recv_fn,
2560 subreq = handle->fns->get_dos_attributes_send_fn(mem_ctx,
2565 if (tevent_req_nomem(subreq, req)) {
2566 return tevent_req_post(req, ev);
2568 tevent_req_defer_callback(req, ev);
2570 tevent_req_set_callback(subreq,
2571 smb_vfs_call_get_dos_attributes_done,
2577 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq)
2579 struct tevent_req *req =
2580 tevent_req_callback_data(subreq,
2582 struct smb_vfs_call_get_dos_attributes_state *state =
2583 tevent_req_data(req,
2584 struct smb_vfs_call_get_dos_attributes_state);
2589 * Make sure we run as the user again
2591 ok = change_to_user_and_service_by_fsp(state->dir_fsp);
2594 status = state->recv_fn(subreq,
2596 &state->dos_attributes);
2597 TALLOC_FREE(subreq);
2598 if (tevent_req_nterror(req, status)) {
2602 tevent_req_done(req);
2605 NTSTATUS smb_vfs_call_get_dos_attributes_recv(
2606 struct tevent_req *req,
2607 struct vfs_aio_state *aio_state,
2608 uint32_t *dos_attributes)
2610 struct smb_vfs_call_get_dos_attributes_state *state =
2611 tevent_req_data(req,
2612 struct smb_vfs_call_get_dos_attributes_state);
2615 if (tevent_req_is_nterror(req, &status)) {
2616 tevent_req_received(req);
2620 *aio_state = state->aio_state;
2621 *dos_attributes = state->dos_attributes;
2622 tevent_req_received(req);
2623 return NT_STATUS_OK;
2626 NTSTATUS smb_vfs_call_fget_compression(vfs_handle_struct *handle,
2627 TALLOC_CTX *mem_ctx,
2628 struct files_struct *fsp,
2629 uint16_t *_compression_fmt)
2631 VFS_FIND(fget_compression);
2632 return handle->fns->fget_compression_fn(handle, mem_ctx, fsp,
2636 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2637 TALLOC_CTX *mem_ctx,
2638 struct files_struct *fsp,
2639 uint16_t compression_fmt)
2641 VFS_FIND(set_compression);
2642 return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2646 NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
2647 TALLOC_CTX *mem_ctx,
2648 const char *service_path,
2651 VFS_FIND(snap_check_path);
2652 return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path,
2656 NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle,
2657 TALLOC_CTX *mem_ctx,
2658 const char *base_volume,
2664 VFS_FIND(snap_create);
2665 return handle->fns->snap_create_fn(handle, mem_ctx, base_volume, tstamp,
2666 rw, base_path, snap_path);
2669 NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle,
2670 TALLOC_CTX *mem_ctx,
2674 VFS_FIND(snap_delete);
2675 return handle->fns->snap_delete_fn(handle, mem_ctx, base_path,
2679 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2680 struct files_struct *fsp,
2681 uint32_t security_info,
2682 TALLOC_CTX *mem_ctx,
2683 struct security_descriptor **ppdesc)
2685 VFS_FIND(fget_nt_acl);
2686 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2690 NTSTATUS smb_vfs_call_get_nt_acl_at(struct vfs_handle_struct *handle,
2691 struct files_struct *dirfsp,
2692 const struct smb_filename *smb_fname,
2693 uint32_t security_info,
2694 TALLOC_CTX *mem_ctx,
2695 struct security_descriptor **ppdesc)
2697 VFS_FIND(get_nt_acl_at);
2698 return handle->fns->get_nt_acl_at_fn(handle,
2706 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2707 struct files_struct *fsp,
2708 uint32_t security_info_sent,
2709 const struct security_descriptor *psd)
2711 VFS_FIND(fset_nt_acl);
2712 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2716 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2717 struct smb_filename *file,
2718 struct security_acl *sacl,
2719 uint32_t access_requested,
2720 uint32_t access_denied)
2722 VFS_FIND(audit_file);
2723 return handle->fns->audit_file_fn(handle,
2730 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2731 const struct smb_filename *smb_fname,
2732 SMB_ACL_TYPE_T type,
2733 TALLOC_CTX *mem_ctx)
2735 VFS_FIND(sys_acl_get_file);
2736 return handle->fns->sys_acl_get_file_fn(handle, smb_fname, type, mem_ctx);
2739 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2740 struct files_struct *fsp,
2741 TALLOC_CTX *mem_ctx)
2743 VFS_FIND(sys_acl_get_fd);
2744 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2747 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2748 const struct smb_filename *smb_fname,
2749 TALLOC_CTX *mem_ctx,
2750 char **blob_description,
2753 VFS_FIND(sys_acl_blob_get_file);
2754 return handle->fns->sys_acl_blob_get_file_fn(handle, smb_fname,
2755 mem_ctx, blob_description, blob);
2758 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2759 struct files_struct *fsp,
2760 TALLOC_CTX *mem_ctx,
2761 char **blob_description,
2764 VFS_FIND(sys_acl_blob_get_fd);
2765 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2768 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2769 struct files_struct *fsp,
2770 SMB_ACL_TYPE_T type,
2773 VFS_FIND(sys_acl_set_fd);
2774 return handle->fns->sys_acl_set_fd_fn(handle, fsp, type, theacl);
2777 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2778 const struct smb_filename *smb_fname)
2780 VFS_FIND(sys_acl_delete_def_file);
2781 return handle->fns->sys_acl_delete_def_file_fn(handle, smb_fname);
2784 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2785 const struct smb_filename *smb_fname,
2791 return handle->fns->getxattr_fn(handle, smb_fname, name, value, size);
2795 struct smb_vfs_call_getxattrat_state {
2796 files_struct *dir_fsp;
2797 ssize_t (*recv_fn)(struct tevent_req *req,
2798 struct vfs_aio_state *aio_state,
2799 TALLOC_CTX *mem_ctx,
2800 uint8_t **xattr_value);
2802 uint8_t *xattr_value;
2803 struct vfs_aio_state aio_state;
2806 static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq);
2808 struct tevent_req *smb_vfs_call_getxattrat_send(
2809 TALLOC_CTX *mem_ctx,
2810 struct tevent_context *ev,
2811 struct vfs_handle_struct *handle,
2812 files_struct *dir_fsp,
2813 const struct smb_filename *smb_fname,
2814 const char *xattr_name,
2817 struct tevent_req *req = NULL;
2818 struct smb_vfs_call_getxattrat_state *state = NULL;
2819 struct tevent_req *subreq = NULL;
2821 req = tevent_req_create(mem_ctx, &state,
2822 struct smb_vfs_call_getxattrat_state);
2827 VFS_FIND(getxattrat_send);
2829 *state = (struct smb_vfs_call_getxattrat_state) {
2831 .recv_fn = handle->fns->getxattrat_recv_fn,
2834 subreq = handle->fns->getxattrat_send_fn(mem_ctx,
2841 if (tevent_req_nomem(subreq, req)) {
2842 return tevent_req_post(req, ev);
2844 tevent_req_defer_callback(req, ev);
2846 tevent_req_set_callback(subreq, smb_vfs_call_getxattrat_done, req);
2850 static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq)
2852 struct tevent_req *req = tevent_req_callback_data(
2853 subreq, struct tevent_req);
2854 struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2855 req, struct smb_vfs_call_getxattrat_state);
2859 * Make sure we run as the user again
2861 ok = change_to_user_and_service_by_fsp(state->dir_fsp);
2864 state->retval = state->recv_fn(subreq,
2867 &state->xattr_value);
2868 TALLOC_FREE(subreq);
2869 if (state->retval == -1) {
2870 tevent_req_error(req, state->aio_state.error);
2874 tevent_req_done(req);
2877 ssize_t smb_vfs_call_getxattrat_recv(struct tevent_req *req,
2878 struct vfs_aio_state *aio_state,
2879 TALLOC_CTX *mem_ctx,
2880 uint8_t **xattr_value)
2882 struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2883 req, struct smb_vfs_call_getxattrat_state);
2886 if (tevent_req_is_unix_error(req, &aio_state->error)) {
2887 tevent_req_received(req);
2891 *aio_state = state->aio_state;
2892 xattr_size = state->retval;
2893 if (xattr_value != NULL) {
2894 *xattr_value = talloc_move(mem_ctx, &state->xattr_value);
2897 tevent_req_received(req);
2901 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2902 struct files_struct *fsp, const char *name,
2903 void *value, size_t size)
2905 VFS_FIND(fgetxattr);
2906 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2909 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2910 const struct smb_filename *smb_fname,
2914 VFS_FIND(listxattr);
2915 return handle->fns->listxattr_fn(handle, smb_fname, list, size);
2918 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2919 struct files_struct *fsp, char *list,
2922 VFS_FIND(flistxattr);
2923 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2926 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2927 const struct smb_filename *smb_fname,
2930 VFS_FIND(removexattr);
2931 return handle->fns->removexattr_fn(handle, smb_fname, name);
2934 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2935 struct files_struct *fsp, const char *name)
2937 VFS_FIND(fremovexattr);
2938 return handle->fns->fremovexattr_fn(handle, fsp, name);
2941 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle,
2942 const struct smb_filename *smb_fname,
2949 return handle->fns->setxattr_fn(handle, smb_fname,
2950 name, value, size, flags);
2953 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2954 struct files_struct *fsp, const char *name,
2955 const void *value, size_t size, int flags)
2957 VFS_FIND(fsetxattr);
2958 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2961 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2962 struct files_struct *fsp)
2964 VFS_FIND(aio_force);
2965 return handle->fns->aio_force_fn(handle, fsp);
2968 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2969 struct files_struct *fsp,
2970 TALLOC_CTX *mem_ctx,
2973 VFS_FIND(durable_cookie);
2974 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2977 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2978 struct files_struct *fsp,
2979 const DATA_BLOB old_cookie,
2980 TALLOC_CTX *mem_ctx,
2981 DATA_BLOB *new_cookie)
2983 VFS_FIND(durable_disconnect);
2984 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2985 mem_ctx, new_cookie);
2988 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2989 struct smb_request *smb1req,
2990 struct smbXsrv_open *op,
2991 const DATA_BLOB old_cookie,
2992 TALLOC_CTX *mem_ctx,
2993 struct files_struct **fsp,
2994 DATA_BLOB *new_cookie)
2996 VFS_FIND(durable_reconnect);
2997 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2998 old_cookie, mem_ctx, fsp,
3002 NTSTATUS smb_vfs_call_readdir_attr(struct vfs_handle_struct *handle,
3003 const struct smb_filename *fname,
3004 TALLOC_CTX *mem_ctx,
3005 struct readdir_attr_data **attr_data)
3007 VFS_FIND(readdir_attr);
3008 return handle->fns->readdir_attr_fn(handle, fname, mem_ctx, attr_data);