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 = talloc_zero_size(
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,
295 const struct files_struct *fsp)
297 struct vfs_fsp_data *head;
299 for (head = fsp->vfs_extension; head; head = head->next) {
300 if (head->owner == handle) {
308 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle,
309 const struct files_struct *fsp)
311 struct vfs_fsp_data *head;
313 head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
315 return EXT_DATA_AREA(head);
324 * Ensure this module catches all VFS functions.
327 void smb_vfs_assert_all_fns(const struct vfs_fn_pointers* fns,
330 bool missing_fn = false;
332 const uintptr_t *end = (const uintptr_t *)(fns + 1);
334 for (idx = 0; ((const uintptr_t *)fns + idx) < end; idx++) {
335 if (*((const uintptr_t *)fns + idx) == 0) {
336 DBG_ERR("VFS function at index %d not implemented "
337 "in module %s\n", idx, module);
343 smb_panic("Required VFS function not implemented in module.\n");
347 void smb_vfs_assert_all_fns(const struct vfs_fn_pointers* fns,
353 /*****************************************************************
355 ******************************************************************/
357 bool smbd_vfs_init(connection_struct *conn)
359 const char **vfs_objects;
363 /* Normal share - initialise with disk access functions */
364 vfs_init_default(conn);
366 /* No need to load vfs modules for printer connections */
371 if (lp_widelinks(SNUM(conn))) {
373 * As the widelinks logic is now moving into a
374 * vfs_widelinks module, we need to custom load
375 * it after the default module is initialized.
376 * That way no changes to smb.conf files are
379 bool ok = vfs_init_custom(conn, "widelinks");
381 DBG_ERR("widelinks enabled and vfs_init_custom "
382 "failed for vfs_widelinks module\n");
387 vfs_objects = lp_vfs_objects(SNUM(conn));
389 /* Override VFS functions if 'vfs object' was not specified*/
390 if (!vfs_objects || !vfs_objects[0])
393 for (i=0; vfs_objects[i] ;) {
397 for (j=i-1; j >= 0; j--) {
398 if (!vfs_init_custom(conn, vfs_objects[j])) {
399 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
406 /*******************************************************************
407 Check if a file exists in the vfs.
408 ********************************************************************/
410 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
412 /* Only return OK if stat was successful and S_ISREG */
413 if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
414 S_ISREG(smb_fname->st.st_ex_mode)) {
418 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
421 bool vfs_valid_pread_range(off_t offset, size_t length)
423 return sys_valid_io_range(offset, length);
426 bool vfs_valid_pwrite_range(off_t offset, size_t length)
429 * See MAXFILESIZE in [MS-FSA] 2.1.5.3 Server Requests a Write
431 static const uint64_t maxfilesize = 0xfffffff0000;
432 uint64_t last_byte_ofs;
435 ok = sys_valid_io_range(offset, length);
444 last_byte_ofs = offset + length;
445 if (last_byte_ofs > maxfilesize) {
452 ssize_t vfs_pwrite_data(struct smb_request *req,
462 ok = vfs_valid_pwrite_range(offset, N);
468 if (req && req->unread_bytes) {
469 int sockfd = req->xconn->transport.sock;
470 SMB_ASSERT(req->unread_bytes == N);
471 /* VFS_RECVFILE must drain the socket
472 * before returning. */
473 req->unread_bytes = 0;
475 * Leave the socket non-blocking and
476 * use SMB_VFS_RECVFILE. If it returns
477 * EAGAIN || EWOULDBLOCK temporarily set
478 * the socket blocking and retry
482 ret = SMB_VFS_RECVFILE(sockfd,
486 if (ret == 0 || (ret == -1 &&
488 errno == EWOULDBLOCK))) {
490 /* Ensure the socket is blocking. */
491 old_flags = fcntl(sockfd, F_GETFL, 0);
492 if (set_blocking(sockfd, true) == -1) {
495 ret = SMB_VFS_RECVFILE(sockfd,
499 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
506 return (ssize_t)total;
508 /* Any other error case. */
514 return (ssize_t)total;
518 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
528 return (ssize_t)total;
530 /****************************************************************************
531 An allocate file space call using the vfs interface.
532 Allocates space for a file from a filedescriptor.
533 Returns 0 on success, -1 on failure.
534 ****************************************************************************/
536 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
539 connection_struct *conn = fsp->conn;
540 uint64_t space_avail;
541 uint64_t bsize,dfree,dsize;
546 * Actually try and commit the space on disk....
549 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
550 fsp_str_dbg(fsp), (double)len));
552 ok = vfs_valid_pwrite_range((off_t)len, 0);
554 DEBUG(0,("vfs_allocate_file_space: %s negative/invalid len "
555 "requested.\n", fsp_str_dbg(fsp)));
560 status = vfs_stat_fsp(fsp);
561 if (!NT_STATUS_IS_OK(status)) {
565 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
568 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
569 /* Shrink - use ftruncate. */
571 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
572 "size %.0f\n", fsp_str_dbg(fsp),
573 (double)fsp->fsp_name->st.st_ex_size));
575 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
577 ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len);
579 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
584 /* Grow - we need to test if we have enough space. */
586 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
588 if (lp_strict_allocate(SNUM(fsp->conn))) {
589 /* See if we have a syscall that will allocate beyond
590 end-of-file without changing EOF. */
591 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_FL_KEEP_SIZE,
597 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
600 /* We changed the allocation size on disk, but not
601 EOF - exactly as required. We're done ! */
605 if (ret == -1 && errno == ENOSPC) {
609 len -= fsp->fsp_name->st.st_ex_size;
610 len /= 1024; /* Len is now number of 1k blocks needed. */
612 get_dfree_info(conn, fsp->fsp_name, &bsize, &dfree, &dsize);
613 if (space_avail == (uint64_t)-1) {
617 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
618 "needed blocks = %.0f, space avail = %.0f\n",
619 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
620 (double)space_avail));
622 if (len > space_avail) {
630 /****************************************************************************
631 A vfs set_filelen call.
632 set the length of a file from a filedescriptor.
633 Returns 0 on success, -1 on failure.
634 ****************************************************************************/
636 int vfs_set_filelen(files_struct *fsp, off_t len)
641 ok = vfs_valid_pwrite_range(len, 0);
647 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
649 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
650 fsp_str_dbg(fsp), (double)len));
651 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
652 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
653 FILE_NOTIFY_CHANGE_SIZE
654 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
655 fsp->fsp_name->base_name);
658 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
663 /****************************************************************************
664 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
665 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
666 as this is also called from the default SMB_VFS_FTRUNCATE code.
667 Always extends the file size.
668 Returns 0 on success, -1 on failure.
669 ****************************************************************************/
671 #define SPARSE_BUF_WRITE_SIZE (32*1024)
673 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
679 ok = vfs_valid_pwrite_range(offset, len);
686 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
693 while (total < len) {
694 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
696 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
697 if (pwrite_ret == -1) {
698 int saved_errno = errno;
699 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
700 "%s failed with error %s\n",
701 fsp_str_dbg(fsp), strerror(saved_errno)));
711 /****************************************************************************
712 A vfs fill sparse call.
713 Writes zeros from the end of file to len, if len is greater than EOF.
714 Used only by strict_sync.
715 Returns 0 on success, -1 on failure.
716 ****************************************************************************/
718 int vfs_fill_sparse(files_struct *fsp, off_t len)
726 ok = vfs_valid_pwrite_range(len, 0);
732 status = vfs_stat_fsp(fsp);
733 if (!NT_STATUS_IS_OK(status)) {
737 if (len <= fsp->fsp_name->st.st_ex_size) {
742 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
747 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
748 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
749 (double)fsp->fsp_name->st.st_ex_size, (double)len,
750 (double)(len - fsp->fsp_name->st.st_ex_size)));
752 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
754 offset = fsp->fsp_name->st.st_ex_size;
755 num_to_write = len - fsp->fsp_name->st.st_ex_size;
757 /* Only do this on non-stream file handles. */
758 if (fsp->base_fsp == NULL) {
759 /* for allocation try fallocate first. This can fail on some
760 * platforms e.g. when the filesystem doesn't support it and no
761 * emulation is being done by the libc (like on AIX with JFS1). In that
762 * case we do our own emulation. fallocate implementations can
763 * return ENOTSUP or EINVAL in cases like that. */
764 ret = SMB_VFS_FALLOCATE(fsp, 0, offset, num_to_write);
765 if (ret == -1 && errno == ENOSPC) {
771 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
772 "error %d. Falling back to slow manual allocation\n", ret));
775 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
779 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
783 /*******************************************************************************
784 Set a fd into blocking/nonblocking mode through VFS
785 *******************************************************************************/
787 int vfs_set_blocking(files_struct *fsp, bool set)
791 #define FLAG_TO_SET O_NONBLOCK
794 #define FLAG_TO_SET O_NDELAY
796 #define FLAG_TO_SET FNDELAY
800 if (fsp->fsp_flags.is_pathref) {
804 val = SMB_VFS_FCNTL(fsp, F_GETFL, 0);
815 return SMB_VFS_FCNTL(fsp, F_SETFL, val);
819 /****************************************************************************
820 Transfer some data (n bytes) between two file_struct's.
821 ****************************************************************************/
823 static ssize_t vfs_pread_fn(void *file, void *buf, size_t len, off_t offset)
825 struct files_struct *fsp = (struct files_struct *)file;
827 return SMB_VFS_PREAD(fsp, buf, len, offset);
830 static ssize_t vfs_pwrite_fn(void *file, const void *buf, size_t len, off_t offset)
832 struct files_struct *fsp = (struct files_struct *)file;
834 return SMB_VFS_PWRITE(fsp, buf, len, offset);
837 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
839 return transfer_file_internal((void *)in, (void *)out, n,
840 vfs_pread_fn, vfs_pwrite_fn);
843 /*******************************************************************
844 A vfs_readdir wrapper which just returns the file name.
845 ********************************************************************/
847 const char *vfs_readdirname(connection_struct *conn,
848 struct files_struct *dirfsp,
850 SMB_STRUCT_STAT *sbuf,
853 struct dirent *ptr= NULL;
861 ptr = SMB_VFS_READDIR(conn, dirfsp, (DIR *)p, sbuf);
867 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
868 talloc_tos(), &translated);
869 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
873 *talloced = translated;
874 if (!NT_STATUS_IS_OK(status)) {
880 /*******************************************************************
881 A wrapper for vfs_chdir().
882 ********************************************************************/
884 int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
887 struct smb_filename *cwd = NULL;
890 LastDir = SMB_STRDUP("");
893 if (ISDOT(smb_fname->base_name)) {
895 * passing a '.' is a noop,
896 * and we only expect this after
897 * everything is initialized.
899 * So the first vfs_ChDir() on a given
900 * connection_struct must not be '.'.
902 * Note: conn_new() sets
903 * conn->cwd_fsp->fh->fd = -1
904 * and vfs_ChDir() leaves with
905 * conn->cwd_fsp->fh->fd = AT_FDCWD
908 if (fsp_get_pathref_fd(conn->cwd_fsp) != AT_FDCWD) {
910 * This should never happen and
911 * we might change this to
912 * SMB_ASSERT() in future.
914 DBG_ERR("Called with '.' as first operation!\n");
922 if (smb_fname->base_name[0] == '/' &&
923 strcsequal(LastDir,smb_fname->base_name))
926 * conn->cwd_fsp->fsp_name and the kernel
927 * are already correct, but conn->cwd_fsp->fh->fd
928 * might still be -1 as initialized in conn_new().
930 * This can happen when a client made a 2nd
931 * tree connect to a share with the same underlying
932 * path (may or may not the same share).
934 fsp_set_fd(conn->cwd_fsp, AT_FDCWD);
938 DEBUG(4,("vfs_ChDir to %s\n", smb_fname->base_name));
940 ret = SMB_VFS_CHDIR(conn, smb_fname);
946 * Always replace conn->cwd_fsp. We
947 * don't know if it's been modified by
948 * VFS modules in the stack.
952 cwd = vfs_GetWd(conn, conn);
955 * vfs_GetWd() failed.
956 * We must be able to read cwd.
957 * Return to original directory
960 int saved_errno = errno;
962 if (conn->cwd_fsp->fsp_name == NULL) {
964 * Failed on the very first chdir()+getwd()
965 * for this connection. We can't
968 smb_panic("conn->cwd getwd failed\n");
973 /* Return to the previous $cwd. */
974 ret = SMB_VFS_CHDIR(conn, conn->cwd_fsp->fsp_name);
976 smb_panic("conn->cwd getwd failed\n");
981 /* And fail the chdir(). */
985 /* vfs_GetWd() succeeded. */
986 /* Replace global cache. */
988 LastDir = SMB_STRDUP(smb_fname->base_name);
991 * (Indirect) Callers of vfs_ChDir() may still hold references to the
992 * old conn->cwd_fsp->fsp_name. Move it to talloc_tos(), that way
993 * callers can use it for the lifetime of the SMB request.
995 talloc_move(talloc_tos(), &conn->cwd_fsp->fsp_name);
997 conn->cwd_fsp->fsp_name = talloc_move(conn->cwd_fsp, &cwd);
998 fsp_set_fd(conn->cwd_fsp, AT_FDCWD);
1000 DBG_INFO("vfs_ChDir got %s\n", fsp_str_dbg(conn->cwd_fsp));
1005 /*******************************************************************
1006 Return the absolute current directory path - given a UNIX pathname.
1007 Note that this path is returned in DOS format, not UNIX
1008 format. Note this can be called with conn == NULL.
1009 ********************************************************************/
1011 struct smb_filename *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
1013 struct smb_filename *current_dir_fname = NULL;
1015 struct smb_filename *smb_fname_dot = NULL;
1016 struct smb_filename *smb_fname_full = NULL;
1017 struct smb_filename *result = NULL;
1019 if (!lp_getwd_cache()) {
1023 smb_fname_dot = synthetic_smb_fname(ctx,
1029 if (smb_fname_dot == NULL) {
1034 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
1036 * Known to fail for root: the directory may be NFS-mounted
1037 * and exported with root_squash (so has no root access).
1039 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
1040 "(NFS problem ?)\n", strerror(errno) ));
1044 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
1046 smb_fname_full = (struct smb_filename *)memcache_lookup_talloc(
1049 data_blob_const(&key, sizeof(key)));
1051 if (smb_fname_full == NULL) {
1055 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
1056 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
1057 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
1058 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
1061 * Note: smb_fname_full is owned by smbd_memcache()
1062 * so we must make a copy to return.
1064 result = cp_smb_filename(ctx, smb_fname_full);
1065 if (result == NULL) {
1074 * We don't have the information to hand so rely on traditional
1075 * methods. The very slow getcwd, which spawns a process on some
1076 * systems, or the not quite so bad getwd.
1079 current_dir_fname = SMB_VFS_GETWD(conn, ctx);
1080 if (current_dir_fname == NULL) {
1081 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
1086 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
1087 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
1090 * smbd_memcache() will own current_dir_fname after the
1091 * memcache_add_talloc call, so we must make
1092 * a copy on ctx to return.
1094 result = cp_smb_filename(ctx, current_dir_fname);
1095 if (result == NULL) {
1100 * Ensure the memory going into the cache
1101 * doesn't have a destructor so it can be
1104 talloc_set_destructor(current_dir_fname, NULL);
1106 memcache_add_talloc(smbd_memcache(),
1108 data_blob_const(&key, sizeof(key)),
1109 ¤t_dir_fname);
1110 /* current_dir_fname is now == NULL here. */
1112 /* current_dir_fname is already allocated on ctx. */
1113 result = current_dir_fname;
1117 TALLOC_FREE(smb_fname_dot);
1119 * Don't free current_dir_fname here. It's either been moved
1120 * to the memcache or is being returned in result.
1125 /*******************************************************************
1126 Reduce a file name, removing .. elements and checking that
1127 it is below dir in the hierarchy. This uses realpath.
1128 This function must run as root, and will return names
1129 and valid stat structs that can be checked on open.
1130 ********************************************************************/
1132 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
1133 const struct smb_filename *smb_fname,
1134 struct smb_request *smbreq)
1137 TALLOC_CTX *ctx = talloc_tos();
1138 const char *conn_rootdir;
1140 char *resolved_name = NULL;
1141 struct smb_filename *resolved_fname = NULL;
1142 struct smb_filename *saved_dir_fname = NULL;
1143 struct smb_filename *smb_fname_cwd = NULL;
1145 struct smb_filename *parent_name = NULL;
1146 struct smb_filename *file_name = NULL;
1149 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
1150 smb_fname->base_name,
1151 conn->connectpath));
1154 ok = parent_smb_fname(ctx,
1159 status = NT_STATUS_NO_MEMORY;
1163 if (SMB_VFS_STAT(conn, parent_name) != 0) {
1164 status = map_nt_error_from_unix(errno);
1167 /* Remember where we were. */
1168 saved_dir_fname = vfs_GetWd(ctx, conn);
1169 if (!saved_dir_fname) {
1170 status = map_nt_error_from_unix(errno);
1174 if (vfs_ChDir(conn, parent_name) == -1) {
1175 status = map_nt_error_from_unix(errno);
1179 smb_fname_cwd = synthetic_smb_fname(talloc_tos(),
1185 if (smb_fname_cwd == NULL) {
1186 status = NT_STATUS_NO_MEMORY;
1190 /* Get the absolute path of the parent directory. */
1191 resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname_cwd);
1192 if (resolved_fname == NULL) {
1193 status = map_nt_error_from_unix(errno);
1196 resolved_name = resolved_fname->base_name;
1198 if (*resolved_name != '/') {
1199 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1200 "doesn't return absolute paths !\n"));
1201 status = NT_STATUS_OBJECT_NAME_INVALID;
1205 DBG_DEBUG("realpath [%s] -> [%s]\n",
1206 smb_fname_str_dbg(parent_name),
1209 /* Now check the stat value is the same. */
1210 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1211 status = map_nt_error_from_unix(errno);
1215 /* Ensure we're pointing at the same place. */
1216 if (!check_same_stat(&smb_fname_cwd->st, &parent_name->st)) {
1217 DBG_ERR("device/inode/uid/gid on directory %s changed. "
1218 "Denying access !\n",
1219 smb_fname_str_dbg(parent_name));
1220 status = NT_STATUS_ACCESS_DENIED;
1224 /* Ensure we're below the connect path. */
1226 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
1227 if (conn_rootdir == NULL) {
1228 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1230 status = NT_STATUS_ACCESS_DENIED;
1234 rootdir_len = strlen(conn_rootdir);
1237 * In the case of rootdir_len == 1, we know that conn_rootdir is
1238 * "/", and we also know that resolved_name starts with a slash.
1239 * So, in this corner case, resolved_name is automatically a
1240 * sub-directory of the conn_rootdir. Thus we can skip the string
1241 * comparison and the next character checks (which are even
1242 * wrong in this case).
1244 if (rootdir_len != 1) {
1247 matched = (strncmp(conn_rootdir, resolved_name,
1250 if (!matched || (resolved_name[rootdir_len] != '/' &&
1251 resolved_name[rootdir_len] != '\0')) {
1252 DBG_WARNING("%s is a symlink outside the "
1254 smb_fname_str_dbg(parent_name));
1255 DEBUGADD(1, ("conn_rootdir =%s\n", conn_rootdir));
1256 DEBUGADD(1, ("resolved_name=%s\n", resolved_name));
1257 status = NT_STATUS_ACCESS_DENIED;
1262 /* Now ensure that the last component either doesn't
1263 exist, or is *NOT* a symlink. */
1265 ret = SMB_VFS_LSTAT(conn, file_name);
1267 /* Errno must be ENOENT for this be ok. */
1268 if (errno != ENOENT) {
1269 status = map_nt_error_from_unix(errno);
1270 DBG_WARNING("LSTAT on %s failed with %s\n",
1271 smb_fname_str_dbg(file_name),
1277 if (VALID_STAT(file_name->st) &&
1278 S_ISLNK(file_name->st.st_ex_mode))
1280 DBG_WARNING("Last component %s is a symlink. Denying"
1282 smb_fname_str_dbg(file_name));
1283 status = NT_STATUS_ACCESS_DENIED;
1287 status = NT_STATUS_OK;
1291 if (saved_dir_fname != NULL) {
1292 vfs_ChDir(conn, saved_dir_fname);
1293 TALLOC_FREE(saved_dir_fname);
1295 TALLOC_FREE(resolved_fname);
1296 TALLOC_FREE(parent_name);
1300 /*******************************************************************
1301 Reduce a file name, removing .. elements and checking that
1302 it is below dir in the hierarchy. This uses realpath.
1304 If cwd_name == NULL then fname is a client given path relative
1305 to the root path of the share.
1307 If cwd_name != NULL then fname is a client given path relative
1308 to cwd_name. cwd_name is relative to the root path of the share.
1309 ********************************************************************/
1311 NTSTATUS check_reduced_name(connection_struct *conn,
1312 const struct smb_filename *cwd_fname,
1313 const struct smb_filename *smb_fname)
1315 TALLOC_CTX *ctx = talloc_tos();
1316 const char *cwd_name = cwd_fname ? cwd_fname->base_name : NULL;
1317 const char *fname = smb_fname->base_name;
1318 struct smb_filename *resolved_fname;
1319 char *resolved_name = NULL;
1320 char *new_fname = NULL;
1321 bool allow_symlinks = true;
1322 const char *conn_rootdir;
1326 DBG_DEBUG("check_reduced_name [%s] [%s]\n", fname, conn->connectpath);
1328 resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname);
1330 if (resolved_fname == NULL) {
1331 struct smb_filename *dir_fname = NULL;
1332 struct smb_filename *last_component = NULL;
1334 if (errno == ENOTDIR) {
1335 DBG_NOTICE("Component not a directory in getting "
1336 "realpath for %s\n",
1338 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1340 if (errno != ENOENT) {
1341 NTSTATUS status = map_nt_error_from_unix(errno);
1342 DBG_NOTICE("couldn't get realpath for %s: %s\n",
1348 /* errno == ENOENT */
1351 * Last component didn't exist. Remove it and try and
1352 * canonicalise the directory name.
1355 ok = parent_smb_fname(ctx,
1360 return NT_STATUS_NO_MEMORY;
1363 resolved_fname = SMB_VFS_REALPATH(conn, ctx, dir_fname);
1364 if (resolved_fname == NULL) {
1365 NTSTATUS status = map_nt_error_from_unix(errno);
1367 if (errno == ENOENT || errno == ENOTDIR) {
1368 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1371 DBG_NOTICE("couldn't get realpath for "
1373 smb_fname_str_dbg(dir_fname),
1377 resolved_name = talloc_asprintf(ctx,
1379 resolved_fname->base_name,
1380 last_component->base_name);
1381 if (resolved_name == NULL) {
1382 return NT_STATUS_NO_MEMORY;
1385 resolved_name = resolved_fname->base_name;
1388 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1391 if (*resolved_name != '/') {
1392 DEBUG(0,("check_reduced_name: realpath doesn't return "
1393 "absolute paths !\n"));
1394 TALLOC_FREE(resolved_fname);
1395 return NT_STATUS_OBJECT_NAME_INVALID;
1398 /* Common widelinks and symlinks checks. */
1399 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
1400 if (conn_rootdir == NULL) {
1401 DBG_NOTICE("Could not get conn_rootdir\n");
1402 TALLOC_FREE(resolved_fname);
1403 return NT_STATUS_ACCESS_DENIED;
1406 rootdir_len = strlen(conn_rootdir);
1409 * In the case of rootdir_len == 1, we know that
1410 * conn_rootdir is "/", and we also know that
1411 * resolved_name starts with a slash. So, in this
1412 * corner case, resolved_name is automatically a
1413 * sub-directory of the conn_rootdir. Thus we can skip
1414 * the string comparison and the next character checks
1415 * (which are even wrong in this case).
1417 if (rootdir_len != 1) {
1420 matched = (strncmp(conn_rootdir, resolved_name,
1422 if (!matched || (resolved_name[rootdir_len] != '/' &&
1423 resolved_name[rootdir_len] != '\0')) {
1424 DBG_NOTICE("Bad access attempt: %s is a symlink "
1427 "conn_rootdir =%s\n"
1428 "resolved_name=%s\n",
1432 TALLOC_FREE(resolved_fname);
1433 return NT_STATUS_ACCESS_DENIED;
1437 /* Extra checks if all symlinks are disallowed. */
1438 allow_symlinks = lp_follow_symlinks(SNUM(conn));
1439 if (!allow_symlinks) {
1440 /* fname can't have changed in resolved_path. */
1441 const char *p = &resolved_name[rootdir_len];
1444 * UNIX filesystem semantics, names consisting
1445 * only of "." or ".." CANNOT be symlinks.
1447 if (ISDOT(fname) || ISDOTDOT(fname)) {
1452 DBG_NOTICE("logic error (%c) "
1453 "in resolved_name: %s\n",
1456 TALLOC_FREE(resolved_fname);
1457 return NT_STATUS_ACCESS_DENIED;
1463 * If cwd_name is present and not ".",
1464 * then fname is relative to that, not
1465 * the root of the share. Make sure the
1466 * path we check is the one the client
1467 * sent (cwd_name+fname).
1469 if (cwd_name != NULL && !ISDOT(cwd_name)) {
1470 new_fname = talloc_asprintf(ctx,
1474 if (new_fname == NULL) {
1475 TALLOC_FREE(resolved_fname);
1476 return NT_STATUS_NO_MEMORY;
1481 if (strcmp(fname, p)!=0) {
1482 DBG_NOTICE("Bad access "
1483 "attempt: %s is a symlink to %s\n",
1486 TALLOC_FREE(resolved_fname);
1487 TALLOC_FREE(new_fname);
1488 return NT_STATUS_ACCESS_DENIED;
1494 DBG_INFO("%s reduced to %s\n", fname, resolved_name);
1495 TALLOC_FREE(resolved_fname);
1496 TALLOC_FREE(new_fname);
1497 return NT_STATUS_OK;
1501 * Ensure LSTAT is called for POSIX paths.
1503 int vfs_stat(struct connection_struct *conn,
1504 struct smb_filename *smb_fname)
1506 if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) {
1507 return SMB_VFS_LSTAT(conn, smb_fname);
1509 return SMB_VFS_STAT(conn, smb_fname);
1513 * XXX: This is temporary and there should be no callers of this once
1514 * smb_filename is plumbed through all path based operations.
1516 * Called when we know stream name parsing has already been done.
1518 int vfs_stat_smb_basename(struct connection_struct *conn,
1519 const struct smb_filename *smb_fname_in,
1520 SMB_STRUCT_STAT *psbuf)
1522 struct smb_filename smb_fname = {
1523 .base_name = discard_const_p(char, smb_fname_in->base_name),
1524 .flags = smb_fname_in->flags,
1525 .twrp = smb_fname_in->twrp,
1529 if (smb_fname.flags & SMB_FILENAME_POSIX_PATH) {
1530 ret = SMB_VFS_LSTAT(conn, &smb_fname);
1532 ret = SMB_VFS_STAT(conn, &smb_fname);
1536 *psbuf = smb_fname.st;
1542 * Ensure LSTAT is called for POSIX paths.
1545 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1548 struct stat_ex saved_stat = fsp->fsp_name->st;
1550 if (fsp_get_pathref_fd(fsp) == -1) {
1551 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1552 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1554 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1557 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
1560 return map_nt_error_from_unix(errno);
1562 update_stat_ex_from_saved_stat(&fsp->fsp_name->st, &saved_stat);
1563 return NT_STATUS_OK;
1566 void init_smb_file_time(struct smb_file_time *ft)
1568 *ft = (struct smb_file_time) {
1569 .atime = make_omit_timespec(),
1570 .ctime = make_omit_timespec(),
1571 .mtime = make_omit_timespec(),
1572 .create_time = make_omit_timespec()
1577 * Initialize num_streams and streams, then call VFS op streaminfo
1579 NTSTATUS vfs_streaminfo(connection_struct *conn,
1580 struct files_struct *fsp,
1581 const struct smb_filename *smb_fname,
1582 TALLOC_CTX *mem_ctx,
1583 unsigned int *num_streams,
1584 struct stream_struct **streams)
1588 return SMB_VFS_STREAMINFO(conn,
1596 int vfs_fake_fd(void)
1602 * Return a valid fd, but ensure any attempt to use
1603 * it returns an error (EPIPE).
1605 ret = pipe(pipe_fds);
1615 * This is just a helper to make
1616 * users of vfs_fake_fd() more symetric
1618 int vfs_fake_fd_close(int fd)
1624 generate a file_id from a stat structure
1626 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1628 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1631 NTSTATUS vfs_at_fspcwd(TALLOC_CTX *mem_ctx,
1632 struct connection_struct *conn,
1633 struct files_struct **_fsp)
1635 struct files_struct *fsp = NULL;
1637 fsp = talloc_zero(mem_ctx, struct files_struct);
1639 return NT_STATUS_NO_MEMORY;
1642 fsp->fsp_name = synthetic_smb_fname(fsp, ".", NULL, NULL, 0, 0);
1643 if (fsp->fsp_name == NULL) {
1645 return NT_STATUS_NO_MEMORY;
1648 fsp->fh = fd_handle_create(fsp);
1649 if (fsp->fh == NULL) {
1651 return NT_STATUS_NO_MEMORY;
1654 fsp_set_fd(fsp, AT_FDCWD);
1655 fsp->fnum = FNUM_FIELD_INVALID;
1659 return NT_STATUS_OK;
1662 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1663 const char *service, const char *user)
1666 return handle->fns->connect_fn(handle, service, user);
1669 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1671 VFS_FIND(disconnect);
1672 handle->fns->disconnect_fn(handle);
1675 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1676 const struct smb_filename *smb_fname,
1681 VFS_FIND(disk_free);
1682 return handle->fns->disk_free_fn(handle, smb_fname,
1683 bsize, dfree, dsize);
1686 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1687 const struct smb_filename *smb_fname,
1688 enum SMB_QUOTA_TYPE qtype,
1692 VFS_FIND(get_quota);
1693 return handle->fns->get_quota_fn(handle, smb_fname, qtype, id, qt);
1696 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1697 enum SMB_QUOTA_TYPE qtype, unid_t id,
1700 VFS_FIND(set_quota);
1701 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1704 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1705 struct files_struct *fsp,
1706 struct shadow_copy_data *shadow_copy_data,
1709 VFS_FIND(get_shadow_copy_data);
1710 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1714 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle,
1715 const struct smb_filename *smb_fname,
1716 struct vfs_statvfs_struct *statbuf)
1719 return handle->fns->statvfs_fn(handle, smb_fname, statbuf);
1722 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1723 enum timestamp_set_resolution *p_ts_res)
1725 VFS_FIND(fs_capabilities);
1726 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1729 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1730 struct dfs_GetDFSReferral *r)
1732 VFS_FIND(get_dfs_referrals);
1733 return handle->fns->get_dfs_referrals_fn(handle, r);
1736 NTSTATUS smb_vfs_call_create_dfs_pathat(struct vfs_handle_struct *handle,
1737 struct files_struct *dirfsp,
1738 const struct smb_filename *smb_fname,
1739 const struct referral *reflist,
1740 size_t referral_count)
1742 VFS_FIND(create_dfs_pathat);
1743 return handle->fns->create_dfs_pathat_fn(handle,
1750 NTSTATUS smb_vfs_call_read_dfs_pathat(struct vfs_handle_struct *handle,
1751 TALLOC_CTX *mem_ctx,
1752 struct files_struct *dirfsp,
1753 struct smb_filename *smb_fname,
1754 struct referral **ppreflist,
1755 size_t *preferral_count)
1757 VFS_FIND(read_dfs_pathat);
1758 return handle->fns->read_dfs_pathat_fn(handle,
1766 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1767 struct files_struct *fsp,
1769 uint32_t attributes)
1771 VFS_FIND(fdopendir);
1772 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1775 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1776 struct files_struct *dirfsp,
1778 SMB_STRUCT_STAT *sbuf)
1781 return handle->fns->readdir_fn(handle, dirfsp, dirp, sbuf);
1784 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1785 DIR *dirp, long offset)
1788 handle->fns->seekdir_fn(handle, dirp, offset);
1791 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1795 return handle->fns->telldir_fn(handle, dirp);
1798 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1801 VFS_FIND(rewind_dir);
1802 handle->fns->rewind_dir_fn(handle, dirp);
1805 int smb_vfs_call_mkdirat(struct vfs_handle_struct *handle,
1806 struct files_struct *dirfsp,
1807 const struct smb_filename *smb_fname,
1811 return handle->fns->mkdirat_fn(handle,
1817 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1821 return handle->fns->closedir_fn(handle, dir);
1824 int smb_vfs_call_openat(struct vfs_handle_struct *handle,
1825 const struct files_struct *dirfsp,
1826 const struct smb_filename *smb_fname,
1827 struct files_struct *fsp,
1832 return handle->fns->openat_fn(handle,
1840 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1841 struct smb_request *req,
1842 struct smb_filename *smb_fname,
1843 uint32_t access_mask,
1844 uint32_t share_access,
1845 uint32_t create_disposition,
1846 uint32_t create_options,
1847 uint32_t file_attributes,
1848 uint32_t oplock_request,
1849 const struct smb2_lease *lease,
1850 uint64_t allocation_size,
1851 uint32_t private_flags,
1852 struct security_descriptor *sd,
1853 struct ea_list *ea_list,
1854 files_struct **result,
1856 const struct smb2_create_blobs *in_context_blobs,
1857 struct smb2_create_blobs *out_context_blobs)
1859 VFS_FIND(create_file);
1860 return handle->fns->create_file_fn(
1861 handle, req, smb_fname,
1862 access_mask, share_access, create_disposition, create_options,
1863 file_attributes, oplock_request, lease, allocation_size,
1864 private_flags, sd, ea_list,
1865 result, pinfo, in_context_blobs, out_context_blobs);
1868 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1869 struct files_struct *fsp)
1872 return handle->fns->close_fn(handle, fsp);
1875 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1876 struct files_struct *fsp, void *data, size_t n,
1880 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1883 struct smb_vfs_call_pread_state {
1884 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1886 struct vfs_aio_state vfs_aio_state;
1889 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1891 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1892 TALLOC_CTX *mem_ctx,
1893 struct tevent_context *ev,
1894 struct files_struct *fsp,
1896 size_t n, off_t offset)
1898 struct tevent_req *req, *subreq;
1899 struct smb_vfs_call_pread_state *state;
1901 req = tevent_req_create(mem_ctx, &state,
1902 struct smb_vfs_call_pread_state);
1906 VFS_FIND(pread_send);
1907 state->recv_fn = handle->fns->pread_recv_fn;
1909 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1911 if (tevent_req_nomem(subreq, req)) {
1912 return tevent_req_post(req, ev);
1914 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1918 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1920 struct tevent_req *req = tevent_req_callback_data(
1921 subreq, struct tevent_req);
1922 struct smb_vfs_call_pread_state *state = tevent_req_data(
1923 req, struct smb_vfs_call_pread_state);
1925 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1926 TALLOC_FREE(subreq);
1927 if (state->retval == -1) {
1928 tevent_req_error(req, state->vfs_aio_state.error);
1931 tevent_req_done(req);
1934 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req,
1935 struct vfs_aio_state *vfs_aio_state)
1937 struct smb_vfs_call_pread_state *state = tevent_req_data(
1938 req, struct smb_vfs_call_pread_state);
1941 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1942 tevent_req_received(req);
1945 *vfs_aio_state = state->vfs_aio_state;
1946 retval = state->retval;
1947 tevent_req_received(req);
1951 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1952 struct files_struct *fsp, const void *data,
1953 size_t n, off_t offset)
1956 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1959 struct smb_vfs_call_pwrite_state {
1960 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1962 struct vfs_aio_state vfs_aio_state;
1965 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1967 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1968 TALLOC_CTX *mem_ctx,
1969 struct tevent_context *ev,
1970 struct files_struct *fsp,
1972 size_t n, off_t offset)
1974 struct tevent_req *req, *subreq;
1975 struct smb_vfs_call_pwrite_state *state;
1977 req = tevent_req_create(mem_ctx, &state,
1978 struct smb_vfs_call_pwrite_state);
1982 VFS_FIND(pwrite_send);
1983 state->recv_fn = handle->fns->pwrite_recv_fn;
1985 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1987 if (tevent_req_nomem(subreq, req)) {
1988 return tevent_req_post(req, ev);
1990 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1994 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1996 struct tevent_req *req = tevent_req_callback_data(
1997 subreq, struct tevent_req);
1998 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1999 req, struct smb_vfs_call_pwrite_state);
2001 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
2002 TALLOC_FREE(subreq);
2003 if (state->retval == -1) {
2004 tevent_req_error(req, state->vfs_aio_state.error);
2007 tevent_req_done(req);
2010 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req,
2011 struct vfs_aio_state *vfs_aio_state)
2013 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
2014 req, struct smb_vfs_call_pwrite_state);
2017 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
2018 tevent_req_received(req);
2021 *vfs_aio_state = state->vfs_aio_state;
2022 retval = state->retval;
2023 tevent_req_received(req);
2027 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
2028 struct files_struct *fsp, off_t offset,
2032 return handle->fns->lseek_fn(handle, fsp, offset, whence);
2035 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
2036 files_struct *fromfsp, const DATA_BLOB *header,
2037 off_t offset, size_t count)
2040 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
2044 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
2045 files_struct *tofsp, off_t offset,
2049 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
2052 int smb_vfs_call_renameat(struct vfs_handle_struct *handle,
2053 files_struct *srcfsp,
2054 const struct smb_filename *smb_fname_src,
2055 files_struct *dstfsp,
2056 const struct smb_filename *smb_fname_dst)
2059 return handle->fns->renameat_fn(handle,
2066 struct smb_vfs_call_fsync_state {
2067 int (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
2069 struct vfs_aio_state vfs_aio_state;
2072 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
2074 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
2075 TALLOC_CTX *mem_ctx,
2076 struct tevent_context *ev,
2077 struct files_struct *fsp)
2079 struct tevent_req *req, *subreq;
2080 struct smb_vfs_call_fsync_state *state;
2082 req = tevent_req_create(mem_ctx, &state,
2083 struct smb_vfs_call_fsync_state);
2087 VFS_FIND(fsync_send);
2088 state->recv_fn = handle->fns->fsync_recv_fn;
2090 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
2091 if (tevent_req_nomem(subreq, req)) {
2092 return tevent_req_post(req, ev);
2094 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
2098 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
2100 struct tevent_req *req = tevent_req_callback_data(
2101 subreq, struct tevent_req);
2102 struct smb_vfs_call_fsync_state *state = tevent_req_data(
2103 req, struct smb_vfs_call_fsync_state);
2105 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
2106 TALLOC_FREE(subreq);
2107 if (state->retval == -1) {
2108 tevent_req_error(req, state->vfs_aio_state.error);
2111 tevent_req_done(req);
2114 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state)
2116 struct smb_vfs_call_fsync_state *state = tevent_req_data(
2117 req, struct smb_vfs_call_fsync_state);
2120 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
2121 tevent_req_received(req);
2124 *vfs_aio_state = state->vfs_aio_state;
2125 retval = state->retval;
2126 tevent_req_received(req);
2131 * Synchronous version of fsync, built from backend
2132 * async VFS primitives. Uses a temporary sub-event
2133 * context (NOT NESTED).
2136 int smb_vfs_fsync_sync(files_struct *fsp)
2138 TALLOC_CTX *frame = talloc_stackframe();
2139 struct tevent_req *req = NULL;
2140 struct vfs_aio_state aio_state = { 0 };
2143 struct tevent_context *ev = samba_tevent_context_init(frame);
2149 req = SMB_VFS_FSYNC_SEND(talloc_tos(), ev, fsp);
2154 ok = tevent_req_poll(req, ev);
2159 ret = SMB_VFS_FSYNC_RECV(req, &aio_state);
2164 if (aio_state.error != 0) {
2165 errno = aio_state.error;
2170 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
2171 struct smb_filename *smb_fname)
2174 return handle->fns->stat_fn(handle, smb_fname);
2177 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
2178 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
2181 return handle->fns->fstat_fn(handle, fsp, sbuf);
2184 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
2185 struct smb_filename *smb_filename)
2188 return handle->fns->lstat_fn(handle, smb_filename);
2191 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
2192 struct files_struct *fsp,
2193 const SMB_STRUCT_STAT *sbuf)
2195 VFS_FIND(get_alloc_size);
2196 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
2199 int smb_vfs_call_unlinkat(struct vfs_handle_struct *handle,
2200 struct files_struct *dirfsp,
2201 const struct smb_filename *smb_fname,
2205 return handle->fns->unlinkat_fn(handle,
2211 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
2212 struct files_struct *fsp, mode_t mode)
2215 return handle->fns->fchmod_fn(handle, fsp, mode);
2218 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
2219 struct files_struct *fsp, uid_t uid, gid_t gid)
2222 return handle->fns->fchown_fn(handle, fsp, uid, gid);
2225 int smb_vfs_call_lchown(struct vfs_handle_struct *handle,
2226 const struct smb_filename *smb_fname,
2231 return handle->fns->lchown_fn(handle, smb_fname, uid, gid);
2234 int smb_vfs_call_chdir(struct vfs_handle_struct *handle,
2235 const struct smb_filename *smb_fname)
2238 return handle->fns->chdir_fn(handle, smb_fname);
2241 struct smb_filename *smb_vfs_call_getwd(struct vfs_handle_struct *handle,
2245 return handle->fns->getwd_fn(handle, ctx);
2248 int smb_vfs_call_fntimes(struct vfs_handle_struct *handle,
2249 struct files_struct *fsp,
2250 struct smb_file_time *ft)
2253 return handle->fns->fntimes_fn(handle, fsp, ft);
2256 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2257 struct files_struct *fsp, off_t offset)
2259 VFS_FIND(ftruncate);
2260 return handle->fns->ftruncate_fn(handle, fsp, offset);
2263 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2264 struct files_struct *fsp,
2269 VFS_FIND(fallocate);
2270 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2273 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2274 struct files_struct *fsp, uint32_t share_mode,
2275 uint32_t access_mask)
2277 VFS_FIND(kernel_flock);
2278 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2282 int smb_vfs_call_fcntl(struct vfs_handle_struct *handle,
2283 struct files_struct *fsp, int cmd, ...)
2290 va_start(cmd_arg, cmd);
2291 result = handle->fns->fcntl_fn(handle, fsp, cmd, cmd_arg);
2297 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2298 struct files_struct *fsp, int leasetype)
2300 VFS_FIND(linux_setlease);
2301 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2304 int smb_vfs_call_symlinkat(struct vfs_handle_struct *handle,
2305 const struct smb_filename *link_target,
2306 struct files_struct *dirfsp,
2307 const struct smb_filename *new_smb_fname)
2309 VFS_FIND(symlinkat);
2310 return handle->fns->symlinkat_fn(handle,
2316 int smb_vfs_call_readlinkat(struct vfs_handle_struct *handle,
2317 const struct files_struct *dirfsp,
2318 const struct smb_filename *smb_fname,
2322 VFS_FIND(readlinkat);
2323 return handle->fns->readlinkat_fn(handle,
2330 int smb_vfs_call_linkat(struct vfs_handle_struct *handle,
2331 struct files_struct *srcfsp,
2332 const struct smb_filename *old_smb_fname,
2333 struct files_struct *dstfsp,
2334 const struct smb_filename *new_smb_fname,
2338 return handle->fns->linkat_fn(handle,
2346 int smb_vfs_call_mknodat(struct vfs_handle_struct *handle,
2347 struct files_struct *dirfsp,
2348 const struct smb_filename *smb_fname,
2353 return handle->fns->mknodat_fn(handle,
2360 struct smb_filename *smb_vfs_call_realpath(struct vfs_handle_struct *handle,
2362 const struct smb_filename *smb_fname)
2365 return handle->fns->realpath_fn(handle, ctx, smb_fname);
2368 int smb_vfs_call_chflags(struct vfs_handle_struct *handle,
2369 const struct smb_filename *smb_fname,
2373 return handle->fns->chflags_fn(handle, smb_fname, flags);
2376 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2377 const SMB_STRUCT_STAT *sbuf)
2379 VFS_FIND(file_id_create);
2380 return handle->fns->file_id_create_fn(handle, sbuf);
2383 uint64_t smb_vfs_call_fs_file_id(struct vfs_handle_struct *handle,
2384 const SMB_STRUCT_STAT *sbuf)
2386 VFS_FIND(fs_file_id);
2387 return handle->fns->fs_file_id_fn(handle, sbuf);
2390 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2391 struct files_struct *fsp,
2392 const struct smb_filename *smb_fname,
2393 TALLOC_CTX *mem_ctx,
2394 unsigned int *num_streams,
2395 struct stream_struct **streams)
2397 VFS_FIND(streaminfo);
2398 return handle->fns->streaminfo_fn(handle, fsp, smb_fname, mem_ctx,
2399 num_streams, streams);
2402 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2403 const struct smb_filename *path,
2405 TALLOC_CTX *mem_ctx,
2408 VFS_FIND(get_real_filename);
2409 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2413 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2414 const struct smb_filename *smb_fname)
2416 VFS_FIND(connectpath);
2417 return handle->fns->connectpath_fn(handle, smb_fname);
2420 bool smb_vfs_call_strict_lock_check(struct vfs_handle_struct *handle,
2421 struct files_struct *fsp,
2422 struct lock_struct *plock)
2424 VFS_FIND(strict_lock_check);
2425 return handle->fns->strict_lock_check_fn(handle, fsp, plock);
2428 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2430 enum vfs_translate_direction direction,
2431 TALLOC_CTX *mem_ctx,
2434 VFS_FIND(translate_name);
2435 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2439 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2440 struct files_struct *fsp,
2444 const uint8_t *in_data,
2447 uint32_t max_out_len,
2451 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2452 in_data, in_len, out_data, max_out_len,
2456 NTSTATUS smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct *handle,
2457 struct files_struct *fsp,
2460 VFS_FIND(fget_dos_attributes);
2461 return handle->fns->fget_dos_attributes_fn(handle, fsp, dosmode);
2464 NTSTATUS smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct *handle,
2465 struct files_struct *fsp,
2468 VFS_FIND(fset_dos_attributes);
2469 return handle->fns->fset_dos_attributes_fn(handle, fsp, dosmode);
2472 struct tevent_req *smb_vfs_call_offload_read_send(TALLOC_CTX *mem_ctx,
2473 struct tevent_context *ev,
2474 struct vfs_handle_struct *handle,
2475 struct files_struct *fsp,
2481 VFS_FIND(offload_read_send);
2482 return handle->fns->offload_read_send_fn(mem_ctx, ev, handle,
2484 ttl, offset, to_copy);
2487 NTSTATUS smb_vfs_call_offload_read_recv(struct tevent_req *req,
2488 struct vfs_handle_struct *handle,
2489 TALLOC_CTX *mem_ctx,
2490 DATA_BLOB *token_blob)
2492 VFS_FIND(offload_read_recv);
2493 return handle->fns->offload_read_recv_fn(req, handle, mem_ctx, token_blob);
2496 struct tevent_req *smb_vfs_call_offload_write_send(struct vfs_handle_struct *handle,
2497 TALLOC_CTX *mem_ctx,
2498 struct tevent_context *ev,
2501 off_t transfer_offset,
2502 struct files_struct *dest_fsp,
2506 VFS_FIND(offload_write_send);
2507 return handle->fns->offload_write_send_fn(handle, mem_ctx, ev, fsctl,
2508 token, transfer_offset,
2509 dest_fsp, dest_off, num);
2512 NTSTATUS smb_vfs_call_offload_write_recv(struct vfs_handle_struct *handle,
2513 struct tevent_req *req,
2516 VFS_FIND(offload_write_recv);
2517 return handle->fns->offload_write_recv_fn(handle, req, copied);
2520 struct smb_vfs_call_get_dos_attributes_state {
2521 files_struct *dir_fsp;
2522 NTSTATUS (*recv_fn)(struct tevent_req *req,
2523 struct vfs_aio_state *aio_state,
2525 struct vfs_aio_state aio_state;
2526 uint32_t dos_attributes;
2529 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq);
2531 struct tevent_req *smb_vfs_call_get_dos_attributes_send(
2532 TALLOC_CTX *mem_ctx,
2533 struct tevent_context *ev,
2534 struct vfs_handle_struct *handle,
2535 files_struct *dir_fsp,
2536 struct smb_filename *smb_fname)
2538 struct tevent_req *req = NULL;
2539 struct smb_vfs_call_get_dos_attributes_state *state = NULL;
2540 struct tevent_req *subreq = NULL;
2542 req = tevent_req_create(mem_ctx, &state,
2543 struct smb_vfs_call_get_dos_attributes_state);
2548 VFS_FIND(get_dos_attributes_send);
2550 *state = (struct smb_vfs_call_get_dos_attributes_state) {
2552 .recv_fn = handle->fns->get_dos_attributes_recv_fn,
2555 subreq = handle->fns->get_dos_attributes_send_fn(mem_ctx,
2560 if (tevent_req_nomem(subreq, req)) {
2561 return tevent_req_post(req, ev);
2563 tevent_req_defer_callback(req, ev);
2565 tevent_req_set_callback(subreq,
2566 smb_vfs_call_get_dos_attributes_done,
2572 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq)
2574 struct tevent_req *req =
2575 tevent_req_callback_data(subreq,
2577 struct smb_vfs_call_get_dos_attributes_state *state =
2578 tevent_req_data(req,
2579 struct smb_vfs_call_get_dos_attributes_state);
2584 * Make sure we run as the user again
2586 ok = change_to_user_and_service_by_fsp(state->dir_fsp);
2589 status = state->recv_fn(subreq,
2591 &state->dos_attributes);
2592 TALLOC_FREE(subreq);
2593 if (tevent_req_nterror(req, status)) {
2597 tevent_req_done(req);
2600 NTSTATUS smb_vfs_call_get_dos_attributes_recv(
2601 struct tevent_req *req,
2602 struct vfs_aio_state *aio_state,
2603 uint32_t *dos_attributes)
2605 struct smb_vfs_call_get_dos_attributes_state *state =
2606 tevent_req_data(req,
2607 struct smb_vfs_call_get_dos_attributes_state);
2610 if (tevent_req_is_nterror(req, &status)) {
2611 tevent_req_received(req);
2615 *aio_state = state->aio_state;
2616 *dos_attributes = state->dos_attributes;
2617 tevent_req_received(req);
2618 return NT_STATUS_OK;
2621 NTSTATUS smb_vfs_call_fget_compression(vfs_handle_struct *handle,
2622 TALLOC_CTX *mem_ctx,
2623 struct files_struct *fsp,
2624 uint16_t *_compression_fmt)
2626 VFS_FIND(fget_compression);
2627 return handle->fns->fget_compression_fn(handle, mem_ctx, fsp,
2631 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2632 TALLOC_CTX *mem_ctx,
2633 struct files_struct *fsp,
2634 uint16_t compression_fmt)
2636 VFS_FIND(set_compression);
2637 return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2641 NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
2642 TALLOC_CTX *mem_ctx,
2643 const char *service_path,
2646 VFS_FIND(snap_check_path);
2647 return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path,
2651 NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle,
2652 TALLOC_CTX *mem_ctx,
2653 const char *base_volume,
2659 VFS_FIND(snap_create);
2660 return handle->fns->snap_create_fn(handle, mem_ctx, base_volume, tstamp,
2661 rw, base_path, snap_path);
2664 NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle,
2665 TALLOC_CTX *mem_ctx,
2669 VFS_FIND(snap_delete);
2670 return handle->fns->snap_delete_fn(handle, mem_ctx, base_path,
2674 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2675 struct files_struct *fsp,
2676 uint32_t security_info,
2677 TALLOC_CTX *mem_ctx,
2678 struct security_descriptor **ppdesc)
2680 VFS_FIND(fget_nt_acl);
2681 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2685 NTSTATUS smb_vfs_call_get_nt_acl_at(struct vfs_handle_struct *handle,
2686 struct files_struct *dirfsp,
2687 const struct smb_filename *smb_fname,
2688 uint32_t security_info,
2689 TALLOC_CTX *mem_ctx,
2690 struct security_descriptor **ppdesc)
2692 VFS_FIND(get_nt_acl_at);
2693 return handle->fns->get_nt_acl_at_fn(handle,
2701 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2702 struct files_struct *fsp,
2703 uint32_t security_info_sent,
2704 const struct security_descriptor *psd)
2706 VFS_FIND(fset_nt_acl);
2707 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2711 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2712 struct smb_filename *file,
2713 struct security_acl *sacl,
2714 uint32_t access_requested,
2715 uint32_t access_denied)
2717 VFS_FIND(audit_file);
2718 return handle->fns->audit_file_fn(handle,
2725 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2726 const struct smb_filename *smb_fname,
2727 SMB_ACL_TYPE_T type,
2728 TALLOC_CTX *mem_ctx)
2730 VFS_FIND(sys_acl_get_file);
2731 return handle->fns->sys_acl_get_file_fn(handle, smb_fname, type, mem_ctx);
2734 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2735 struct files_struct *fsp,
2736 TALLOC_CTX *mem_ctx)
2738 VFS_FIND(sys_acl_get_fd);
2739 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2742 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2743 const struct smb_filename *smb_fname,
2744 TALLOC_CTX *mem_ctx,
2745 char **blob_description,
2748 VFS_FIND(sys_acl_blob_get_file);
2749 return handle->fns->sys_acl_blob_get_file_fn(handle, smb_fname,
2750 mem_ctx, blob_description, blob);
2753 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2754 struct files_struct *fsp,
2755 TALLOC_CTX *mem_ctx,
2756 char **blob_description,
2759 VFS_FIND(sys_acl_blob_get_fd);
2760 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2763 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2764 struct files_struct *fsp,
2765 SMB_ACL_TYPE_T type,
2768 VFS_FIND(sys_acl_set_fd);
2769 return handle->fns->sys_acl_set_fd_fn(handle, fsp, type, theacl);
2772 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2773 const struct smb_filename *smb_fname)
2775 VFS_FIND(sys_acl_delete_def_file);
2776 return handle->fns->sys_acl_delete_def_file_fn(handle, smb_fname);
2779 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2780 const struct smb_filename *smb_fname,
2786 return handle->fns->getxattr_fn(handle, smb_fname, name, value, size);
2790 struct smb_vfs_call_getxattrat_state {
2791 files_struct *dir_fsp;
2792 ssize_t (*recv_fn)(struct tevent_req *req,
2793 struct vfs_aio_state *aio_state,
2794 TALLOC_CTX *mem_ctx,
2795 uint8_t **xattr_value);
2797 uint8_t *xattr_value;
2798 struct vfs_aio_state aio_state;
2801 static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq);
2803 struct tevent_req *smb_vfs_call_getxattrat_send(
2804 TALLOC_CTX *mem_ctx,
2805 struct tevent_context *ev,
2806 struct vfs_handle_struct *handle,
2807 files_struct *dir_fsp,
2808 const struct smb_filename *smb_fname,
2809 const char *xattr_name,
2812 struct tevent_req *req = NULL;
2813 struct smb_vfs_call_getxattrat_state *state = NULL;
2814 struct tevent_req *subreq = NULL;
2816 req = tevent_req_create(mem_ctx, &state,
2817 struct smb_vfs_call_getxattrat_state);
2822 VFS_FIND(getxattrat_send);
2824 *state = (struct smb_vfs_call_getxattrat_state) {
2826 .recv_fn = handle->fns->getxattrat_recv_fn,
2829 subreq = handle->fns->getxattrat_send_fn(mem_ctx,
2836 if (tevent_req_nomem(subreq, req)) {
2837 return tevent_req_post(req, ev);
2839 tevent_req_defer_callback(req, ev);
2841 tevent_req_set_callback(subreq, smb_vfs_call_getxattrat_done, req);
2845 static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq)
2847 struct tevent_req *req = tevent_req_callback_data(
2848 subreq, struct tevent_req);
2849 struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2850 req, struct smb_vfs_call_getxattrat_state);
2854 * Make sure we run as the user again
2856 ok = change_to_user_and_service_by_fsp(state->dir_fsp);
2859 state->retval = state->recv_fn(subreq,
2862 &state->xattr_value);
2863 TALLOC_FREE(subreq);
2864 if (state->retval == -1) {
2865 tevent_req_error(req, state->aio_state.error);
2869 tevent_req_done(req);
2872 ssize_t smb_vfs_call_getxattrat_recv(struct tevent_req *req,
2873 struct vfs_aio_state *aio_state,
2874 TALLOC_CTX *mem_ctx,
2875 uint8_t **xattr_value)
2877 struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2878 req, struct smb_vfs_call_getxattrat_state);
2881 if (tevent_req_is_unix_error(req, &aio_state->error)) {
2882 tevent_req_received(req);
2886 *aio_state = state->aio_state;
2887 xattr_size = state->retval;
2888 if (xattr_value != NULL) {
2889 *xattr_value = talloc_move(mem_ctx, &state->xattr_value);
2892 tevent_req_received(req);
2896 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2897 struct files_struct *fsp, const char *name,
2898 void *value, size_t size)
2900 VFS_FIND(fgetxattr);
2901 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2904 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2905 struct files_struct *fsp, char *list,
2908 VFS_FIND(flistxattr);
2909 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2912 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2913 struct files_struct *fsp, const char *name)
2915 VFS_FIND(fremovexattr);
2916 return handle->fns->fremovexattr_fn(handle, fsp, name);
2919 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2920 struct files_struct *fsp, const char *name,
2921 const void *value, size_t size, int flags)
2923 VFS_FIND(fsetxattr);
2924 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2927 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2928 struct files_struct *fsp)
2930 VFS_FIND(aio_force);
2931 return handle->fns->aio_force_fn(handle, fsp);
2934 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2935 struct files_struct *fsp,
2936 TALLOC_CTX *mem_ctx,
2939 VFS_FIND(durable_cookie);
2940 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2943 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2944 struct files_struct *fsp,
2945 const DATA_BLOB old_cookie,
2946 TALLOC_CTX *mem_ctx,
2947 DATA_BLOB *new_cookie)
2949 VFS_FIND(durable_disconnect);
2950 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2951 mem_ctx, new_cookie);
2954 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2955 struct smb_request *smb1req,
2956 struct smbXsrv_open *op,
2957 const DATA_BLOB old_cookie,
2958 TALLOC_CTX *mem_ctx,
2959 struct files_struct **fsp,
2960 DATA_BLOB *new_cookie)
2962 VFS_FIND(durable_reconnect);
2963 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2964 old_cookie, mem_ctx, fsp,
2968 NTSTATUS smb_vfs_call_readdir_attr(struct vfs_handle_struct *handle,
2969 const struct smb_filename *fname,
2970 TALLOC_CTX *mem_ctx,
2971 struct readdir_attr_data **attr_data)
2973 VFS_FIND(readdir_attr);
2974 return handle->fns->readdir_attr_fn(handle, fname, mem_ctx, attr_data);