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;
1148 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
1149 smb_fname->base_name,
1150 conn->connectpath));
1152 status = SMB_VFS_PARENT_PATHNAME(conn,
1157 if (!NT_STATUS_IS_OK(status)) {
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
1578 NTSTATUS vfs_fstreaminfo(struct files_struct *fsp,
1579 TALLOC_CTX *mem_ctx,
1580 unsigned int *num_streams,
1581 struct stream_struct **streams)
1588 * Callers may pass fsp == NULL when passing smb_fname->fsp of a
1589 * symlink. This is ok, handle it here, by just return no
1590 * streams on a symlink.
1592 return NT_STATUS_OK;
1595 if (fsp_get_pathref_fd(fsp) == -1) {
1597 * No streams on non-real files/directories.
1599 return NT_STATUS_OK;
1602 return SMB_VFS_FSTREAMINFO(fsp,
1608 int vfs_fake_fd(void)
1614 * Return a valid fd, but ensure any attempt to use
1615 * it returns an error (EPIPE).
1617 ret = pipe(pipe_fds);
1627 * This is just a helper to make
1628 * users of vfs_fake_fd() more symetric
1630 int vfs_fake_fd_close(int fd)
1636 generate a file_id from a stat structure
1638 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1640 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1643 NTSTATUS vfs_at_fspcwd(TALLOC_CTX *mem_ctx,
1644 struct connection_struct *conn,
1645 struct files_struct **_fsp)
1647 struct files_struct *fsp = NULL;
1649 fsp = talloc_zero(mem_ctx, struct files_struct);
1651 return NT_STATUS_NO_MEMORY;
1654 fsp->fsp_name = synthetic_smb_fname(fsp, ".", NULL, NULL, 0, 0);
1655 if (fsp->fsp_name == NULL) {
1657 return NT_STATUS_NO_MEMORY;
1660 fsp->fh = fd_handle_create(fsp);
1661 if (fsp->fh == NULL) {
1663 return NT_STATUS_NO_MEMORY;
1666 fsp_set_fd(fsp, AT_FDCWD);
1667 fsp->fnum = FNUM_FIELD_INVALID;
1671 return NT_STATUS_OK;
1674 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1675 const char *service, const char *user)
1678 return handle->fns->connect_fn(handle, service, user);
1681 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1683 VFS_FIND(disconnect);
1684 handle->fns->disconnect_fn(handle);
1687 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1688 const struct smb_filename *smb_fname,
1693 VFS_FIND(disk_free);
1694 return handle->fns->disk_free_fn(handle, smb_fname,
1695 bsize, dfree, dsize);
1698 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1699 const struct smb_filename *smb_fname,
1700 enum SMB_QUOTA_TYPE qtype,
1704 VFS_FIND(get_quota);
1705 return handle->fns->get_quota_fn(handle, smb_fname, qtype, id, qt);
1708 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1709 enum SMB_QUOTA_TYPE qtype, unid_t id,
1712 VFS_FIND(set_quota);
1713 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1716 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1717 struct files_struct *fsp,
1718 struct shadow_copy_data *shadow_copy_data,
1721 VFS_FIND(get_shadow_copy_data);
1722 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1726 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle,
1727 const struct smb_filename *smb_fname,
1728 struct vfs_statvfs_struct *statbuf)
1731 return handle->fns->statvfs_fn(handle, smb_fname, statbuf);
1734 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1735 enum timestamp_set_resolution *p_ts_res)
1737 VFS_FIND(fs_capabilities);
1738 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1741 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1742 struct dfs_GetDFSReferral *r)
1744 VFS_FIND(get_dfs_referrals);
1745 return handle->fns->get_dfs_referrals_fn(handle, r);
1748 NTSTATUS smb_vfs_call_create_dfs_pathat(struct vfs_handle_struct *handle,
1749 struct files_struct *dirfsp,
1750 const struct smb_filename *smb_fname,
1751 const struct referral *reflist,
1752 size_t referral_count)
1754 VFS_FIND(create_dfs_pathat);
1755 return handle->fns->create_dfs_pathat_fn(handle,
1762 NTSTATUS smb_vfs_call_read_dfs_pathat(struct vfs_handle_struct *handle,
1763 TALLOC_CTX *mem_ctx,
1764 struct files_struct *dirfsp,
1765 struct smb_filename *smb_fname,
1766 struct referral **ppreflist,
1767 size_t *preferral_count)
1769 VFS_FIND(read_dfs_pathat);
1770 return handle->fns->read_dfs_pathat_fn(handle,
1778 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1779 struct files_struct *fsp,
1781 uint32_t attributes)
1783 VFS_FIND(fdopendir);
1784 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1787 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1788 struct files_struct *dirfsp,
1790 SMB_STRUCT_STAT *sbuf)
1793 return handle->fns->readdir_fn(handle, dirfsp, dirp, sbuf);
1796 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1797 DIR *dirp, long offset)
1800 handle->fns->seekdir_fn(handle, dirp, offset);
1803 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1807 return handle->fns->telldir_fn(handle, dirp);
1810 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1813 VFS_FIND(rewind_dir);
1814 handle->fns->rewind_dir_fn(handle, dirp);
1817 int smb_vfs_call_mkdirat(struct vfs_handle_struct *handle,
1818 struct files_struct *dirfsp,
1819 const struct smb_filename *smb_fname,
1823 return handle->fns->mkdirat_fn(handle,
1829 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1833 return handle->fns->closedir_fn(handle, dir);
1836 int smb_vfs_call_openat(struct vfs_handle_struct *handle,
1837 const struct files_struct *dirfsp,
1838 const struct smb_filename *smb_fname,
1839 struct files_struct *fsp,
1844 return handle->fns->openat_fn(handle,
1852 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1853 struct smb_request *req,
1854 struct smb_filename *smb_fname,
1855 uint32_t access_mask,
1856 uint32_t share_access,
1857 uint32_t create_disposition,
1858 uint32_t create_options,
1859 uint32_t file_attributes,
1860 uint32_t oplock_request,
1861 const struct smb2_lease *lease,
1862 uint64_t allocation_size,
1863 uint32_t private_flags,
1864 struct security_descriptor *sd,
1865 struct ea_list *ea_list,
1866 files_struct **result,
1868 const struct smb2_create_blobs *in_context_blobs,
1869 struct smb2_create_blobs *out_context_blobs)
1871 VFS_FIND(create_file);
1872 return handle->fns->create_file_fn(
1873 handle, req, smb_fname,
1874 access_mask, share_access, create_disposition, create_options,
1875 file_attributes, oplock_request, lease, allocation_size,
1876 private_flags, sd, ea_list,
1877 result, pinfo, in_context_blobs, out_context_blobs);
1880 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1881 struct files_struct *fsp)
1884 return handle->fns->close_fn(handle, fsp);
1887 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1888 struct files_struct *fsp, void *data, size_t n,
1892 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1895 struct smb_vfs_call_pread_state {
1896 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1898 struct vfs_aio_state vfs_aio_state;
1901 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1903 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1904 TALLOC_CTX *mem_ctx,
1905 struct tevent_context *ev,
1906 struct files_struct *fsp,
1908 size_t n, off_t offset)
1910 struct tevent_req *req, *subreq;
1911 struct smb_vfs_call_pread_state *state;
1913 req = tevent_req_create(mem_ctx, &state,
1914 struct smb_vfs_call_pread_state);
1918 VFS_FIND(pread_send);
1919 state->recv_fn = handle->fns->pread_recv_fn;
1921 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1923 if (tevent_req_nomem(subreq, req)) {
1924 return tevent_req_post(req, ev);
1926 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1930 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1932 struct tevent_req *req = tevent_req_callback_data(
1933 subreq, struct tevent_req);
1934 struct smb_vfs_call_pread_state *state = tevent_req_data(
1935 req, struct smb_vfs_call_pread_state);
1937 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1938 TALLOC_FREE(subreq);
1939 if (state->retval == -1) {
1940 tevent_req_error(req, state->vfs_aio_state.error);
1943 tevent_req_done(req);
1946 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req,
1947 struct vfs_aio_state *vfs_aio_state)
1949 struct smb_vfs_call_pread_state *state = tevent_req_data(
1950 req, struct smb_vfs_call_pread_state);
1953 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1954 tevent_req_received(req);
1957 *vfs_aio_state = state->vfs_aio_state;
1958 retval = state->retval;
1959 tevent_req_received(req);
1963 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1964 struct files_struct *fsp, const void *data,
1965 size_t n, off_t offset)
1968 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1971 struct smb_vfs_call_pwrite_state {
1972 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1974 struct vfs_aio_state vfs_aio_state;
1977 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1979 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1980 TALLOC_CTX *mem_ctx,
1981 struct tevent_context *ev,
1982 struct files_struct *fsp,
1984 size_t n, off_t offset)
1986 struct tevent_req *req, *subreq;
1987 struct smb_vfs_call_pwrite_state *state;
1989 req = tevent_req_create(mem_ctx, &state,
1990 struct smb_vfs_call_pwrite_state);
1994 VFS_FIND(pwrite_send);
1995 state->recv_fn = handle->fns->pwrite_recv_fn;
1997 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1999 if (tevent_req_nomem(subreq, req)) {
2000 return tevent_req_post(req, ev);
2002 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
2006 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
2008 struct tevent_req *req = tevent_req_callback_data(
2009 subreq, struct tevent_req);
2010 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
2011 req, struct smb_vfs_call_pwrite_state);
2013 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
2014 TALLOC_FREE(subreq);
2015 if (state->retval == -1) {
2016 tevent_req_error(req, state->vfs_aio_state.error);
2019 tevent_req_done(req);
2022 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req,
2023 struct vfs_aio_state *vfs_aio_state)
2025 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
2026 req, struct smb_vfs_call_pwrite_state);
2029 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
2030 tevent_req_received(req);
2033 *vfs_aio_state = state->vfs_aio_state;
2034 retval = state->retval;
2035 tevent_req_received(req);
2039 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
2040 struct files_struct *fsp, off_t offset,
2044 return handle->fns->lseek_fn(handle, fsp, offset, whence);
2047 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
2048 files_struct *fromfsp, const DATA_BLOB *header,
2049 off_t offset, size_t count)
2052 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
2056 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
2057 files_struct *tofsp, off_t offset,
2061 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
2064 int smb_vfs_call_renameat(struct vfs_handle_struct *handle,
2065 files_struct *srcfsp,
2066 const struct smb_filename *smb_fname_src,
2067 files_struct *dstfsp,
2068 const struct smb_filename *smb_fname_dst)
2071 return handle->fns->renameat_fn(handle,
2078 struct smb_vfs_call_fsync_state {
2079 int (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
2081 struct vfs_aio_state vfs_aio_state;
2084 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
2086 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
2087 TALLOC_CTX *mem_ctx,
2088 struct tevent_context *ev,
2089 struct files_struct *fsp)
2091 struct tevent_req *req, *subreq;
2092 struct smb_vfs_call_fsync_state *state;
2094 req = tevent_req_create(mem_ctx, &state,
2095 struct smb_vfs_call_fsync_state);
2099 VFS_FIND(fsync_send);
2100 state->recv_fn = handle->fns->fsync_recv_fn;
2102 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
2103 if (tevent_req_nomem(subreq, req)) {
2104 return tevent_req_post(req, ev);
2106 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
2110 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
2112 struct tevent_req *req = tevent_req_callback_data(
2113 subreq, struct tevent_req);
2114 struct smb_vfs_call_fsync_state *state = tevent_req_data(
2115 req, struct smb_vfs_call_fsync_state);
2117 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
2118 TALLOC_FREE(subreq);
2119 if (state->retval == -1) {
2120 tevent_req_error(req, state->vfs_aio_state.error);
2123 tevent_req_done(req);
2126 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state)
2128 struct smb_vfs_call_fsync_state *state = tevent_req_data(
2129 req, struct smb_vfs_call_fsync_state);
2132 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
2133 tevent_req_received(req);
2136 *vfs_aio_state = state->vfs_aio_state;
2137 retval = state->retval;
2138 tevent_req_received(req);
2143 * Synchronous version of fsync, built from backend
2144 * async VFS primitives. Uses a temporary sub-event
2145 * context (NOT NESTED).
2148 int smb_vfs_fsync_sync(files_struct *fsp)
2150 TALLOC_CTX *frame = talloc_stackframe();
2151 struct tevent_req *req = NULL;
2152 struct vfs_aio_state aio_state = { 0 };
2155 struct tevent_context *ev = samba_tevent_context_init(frame);
2161 req = SMB_VFS_FSYNC_SEND(talloc_tos(), ev, fsp);
2166 ok = tevent_req_poll(req, ev);
2171 ret = SMB_VFS_FSYNC_RECV(req, &aio_state);
2176 if (aio_state.error != 0) {
2177 errno = aio_state.error;
2182 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
2183 struct smb_filename *smb_fname)
2186 return handle->fns->stat_fn(handle, smb_fname);
2189 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
2190 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
2193 return handle->fns->fstat_fn(handle, fsp, sbuf);
2196 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
2197 struct smb_filename *smb_filename)
2200 return handle->fns->lstat_fn(handle, smb_filename);
2203 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
2204 struct files_struct *fsp,
2205 const SMB_STRUCT_STAT *sbuf)
2207 VFS_FIND(get_alloc_size);
2208 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
2211 int smb_vfs_call_unlinkat(struct vfs_handle_struct *handle,
2212 struct files_struct *dirfsp,
2213 const struct smb_filename *smb_fname,
2217 return handle->fns->unlinkat_fn(handle,
2223 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
2224 struct files_struct *fsp, mode_t mode)
2227 return handle->fns->fchmod_fn(handle, fsp, mode);
2230 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
2231 struct files_struct *fsp, uid_t uid, gid_t gid)
2234 return handle->fns->fchown_fn(handle, fsp, uid, gid);
2237 int smb_vfs_call_lchown(struct vfs_handle_struct *handle,
2238 const struct smb_filename *smb_fname,
2243 return handle->fns->lchown_fn(handle, smb_fname, uid, gid);
2246 int smb_vfs_call_chdir(struct vfs_handle_struct *handle,
2247 const struct smb_filename *smb_fname)
2250 return handle->fns->chdir_fn(handle, smb_fname);
2253 struct smb_filename *smb_vfs_call_getwd(struct vfs_handle_struct *handle,
2257 return handle->fns->getwd_fn(handle, ctx);
2260 int smb_vfs_call_fntimes(struct vfs_handle_struct *handle,
2261 struct files_struct *fsp,
2262 struct smb_file_time *ft)
2265 return handle->fns->fntimes_fn(handle, fsp, ft);
2268 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2269 struct files_struct *fsp, off_t offset)
2271 VFS_FIND(ftruncate);
2272 return handle->fns->ftruncate_fn(handle, fsp, offset);
2275 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2276 struct files_struct *fsp,
2281 VFS_FIND(fallocate);
2282 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2285 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2286 struct files_struct *fsp, uint32_t share_mode,
2287 uint32_t access_mask)
2289 VFS_FIND(kernel_flock);
2290 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2294 int smb_vfs_call_fcntl(struct vfs_handle_struct *handle,
2295 struct files_struct *fsp, int cmd, ...)
2302 va_start(cmd_arg, cmd);
2303 result = handle->fns->fcntl_fn(handle, fsp, cmd, cmd_arg);
2309 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2310 struct files_struct *fsp, int leasetype)
2312 VFS_FIND(linux_setlease);
2313 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2316 int smb_vfs_call_symlinkat(struct vfs_handle_struct *handle,
2317 const struct smb_filename *link_target,
2318 struct files_struct *dirfsp,
2319 const struct smb_filename *new_smb_fname)
2321 VFS_FIND(symlinkat);
2322 return handle->fns->symlinkat_fn(handle,
2328 int smb_vfs_call_readlinkat(struct vfs_handle_struct *handle,
2329 const struct files_struct *dirfsp,
2330 const struct smb_filename *smb_fname,
2334 VFS_FIND(readlinkat);
2335 return handle->fns->readlinkat_fn(handle,
2342 int smb_vfs_call_linkat(struct vfs_handle_struct *handle,
2343 struct files_struct *srcfsp,
2344 const struct smb_filename *old_smb_fname,
2345 struct files_struct *dstfsp,
2346 const struct smb_filename *new_smb_fname,
2350 return handle->fns->linkat_fn(handle,
2358 int smb_vfs_call_mknodat(struct vfs_handle_struct *handle,
2359 struct files_struct *dirfsp,
2360 const struct smb_filename *smb_fname,
2365 return handle->fns->mknodat_fn(handle,
2372 struct smb_filename *smb_vfs_call_realpath(struct vfs_handle_struct *handle,
2374 const struct smb_filename *smb_fname)
2377 return handle->fns->realpath_fn(handle, ctx, smb_fname);
2380 int smb_vfs_call_chflags(struct vfs_handle_struct *handle,
2381 const struct smb_filename *smb_fname,
2385 return handle->fns->chflags_fn(handle, smb_fname, flags);
2388 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2389 const SMB_STRUCT_STAT *sbuf)
2391 VFS_FIND(file_id_create);
2392 return handle->fns->file_id_create_fn(handle, sbuf);
2395 uint64_t smb_vfs_call_fs_file_id(struct vfs_handle_struct *handle,
2396 const SMB_STRUCT_STAT *sbuf)
2398 VFS_FIND(fs_file_id);
2399 return handle->fns->fs_file_id_fn(handle, sbuf);
2402 NTSTATUS smb_vfs_call_fstreaminfo(struct vfs_handle_struct *handle,
2403 struct files_struct *fsp,
2404 TALLOC_CTX *mem_ctx,
2405 unsigned int *num_streams,
2406 struct stream_struct **streams)
2408 VFS_FIND(fstreaminfo);
2409 return handle->fns->fstreaminfo_fn(handle, fsp, mem_ctx,
2410 num_streams, streams);
2413 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2414 const struct smb_filename *path,
2416 TALLOC_CTX *mem_ctx,
2419 VFS_FIND(get_real_filename);
2420 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2424 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2425 const struct smb_filename *smb_fname)
2427 VFS_FIND(connectpath);
2428 return handle->fns->connectpath_fn(handle, smb_fname);
2431 bool smb_vfs_call_strict_lock_check(struct vfs_handle_struct *handle,
2432 struct files_struct *fsp,
2433 struct lock_struct *plock)
2435 VFS_FIND(strict_lock_check);
2436 return handle->fns->strict_lock_check_fn(handle, fsp, plock);
2439 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2441 enum vfs_translate_direction direction,
2442 TALLOC_CTX *mem_ctx,
2445 VFS_FIND(translate_name);
2446 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2450 NTSTATUS smb_vfs_call_parent_pathname(struct vfs_handle_struct *handle,
2451 TALLOC_CTX *mem_ctx,
2452 const struct smb_filename *smb_fname_in,
2453 struct smb_filename **parent_dir_out,
2454 struct smb_filename **atname_out)
2456 VFS_FIND(parent_pathname);
2457 return handle->fns->parent_pathname_fn(handle,
2464 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2465 struct files_struct *fsp,
2469 const uint8_t *in_data,
2472 uint32_t max_out_len,
2476 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2477 in_data, in_len, out_data, max_out_len,
2481 NTSTATUS smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct *handle,
2482 struct files_struct *fsp,
2485 VFS_FIND(fget_dos_attributes);
2486 return handle->fns->fget_dos_attributes_fn(handle, fsp, dosmode);
2489 NTSTATUS smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct *handle,
2490 struct files_struct *fsp,
2493 VFS_FIND(fset_dos_attributes);
2494 return handle->fns->fset_dos_attributes_fn(handle, fsp, dosmode);
2497 struct tevent_req *smb_vfs_call_offload_read_send(TALLOC_CTX *mem_ctx,
2498 struct tevent_context *ev,
2499 struct vfs_handle_struct *handle,
2500 struct files_struct *fsp,
2506 VFS_FIND(offload_read_send);
2507 return handle->fns->offload_read_send_fn(mem_ctx, ev, handle,
2509 ttl, offset, to_copy);
2512 NTSTATUS smb_vfs_call_offload_read_recv(struct tevent_req *req,
2513 struct vfs_handle_struct *handle,
2514 TALLOC_CTX *mem_ctx,
2515 DATA_BLOB *token_blob)
2517 VFS_FIND(offload_read_recv);
2518 return handle->fns->offload_read_recv_fn(req, handle, mem_ctx, token_blob);
2521 struct tevent_req *smb_vfs_call_offload_write_send(struct vfs_handle_struct *handle,
2522 TALLOC_CTX *mem_ctx,
2523 struct tevent_context *ev,
2526 off_t transfer_offset,
2527 struct files_struct *dest_fsp,
2531 VFS_FIND(offload_write_send);
2532 return handle->fns->offload_write_send_fn(handle, mem_ctx, ev, fsctl,
2533 token, transfer_offset,
2534 dest_fsp, dest_off, num);
2537 NTSTATUS smb_vfs_call_offload_write_recv(struct vfs_handle_struct *handle,
2538 struct tevent_req *req,
2541 VFS_FIND(offload_write_recv);
2542 return handle->fns->offload_write_recv_fn(handle, req, copied);
2545 struct smb_vfs_call_get_dos_attributes_state {
2546 files_struct *dir_fsp;
2547 NTSTATUS (*recv_fn)(struct tevent_req *req,
2548 struct vfs_aio_state *aio_state,
2550 struct vfs_aio_state aio_state;
2551 uint32_t dos_attributes;
2554 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq);
2556 struct tevent_req *smb_vfs_call_get_dos_attributes_send(
2557 TALLOC_CTX *mem_ctx,
2558 struct tevent_context *ev,
2559 struct vfs_handle_struct *handle,
2560 files_struct *dir_fsp,
2561 struct smb_filename *smb_fname)
2563 struct tevent_req *req = NULL;
2564 struct smb_vfs_call_get_dos_attributes_state *state = NULL;
2565 struct tevent_req *subreq = NULL;
2567 req = tevent_req_create(mem_ctx, &state,
2568 struct smb_vfs_call_get_dos_attributes_state);
2573 VFS_FIND(get_dos_attributes_send);
2575 *state = (struct smb_vfs_call_get_dos_attributes_state) {
2577 .recv_fn = handle->fns->get_dos_attributes_recv_fn,
2580 subreq = handle->fns->get_dos_attributes_send_fn(mem_ctx,
2585 if (tevent_req_nomem(subreq, req)) {
2586 return tevent_req_post(req, ev);
2588 tevent_req_defer_callback(req, ev);
2590 tevent_req_set_callback(subreq,
2591 smb_vfs_call_get_dos_attributes_done,
2597 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq)
2599 struct tevent_req *req =
2600 tevent_req_callback_data(subreq,
2602 struct smb_vfs_call_get_dos_attributes_state *state =
2603 tevent_req_data(req,
2604 struct smb_vfs_call_get_dos_attributes_state);
2609 * Make sure we run as the user again
2611 ok = change_to_user_and_service_by_fsp(state->dir_fsp);
2614 status = state->recv_fn(subreq,
2616 &state->dos_attributes);
2617 TALLOC_FREE(subreq);
2618 if (tevent_req_nterror(req, status)) {
2622 tevent_req_done(req);
2625 NTSTATUS smb_vfs_call_get_dos_attributes_recv(
2626 struct tevent_req *req,
2627 struct vfs_aio_state *aio_state,
2628 uint32_t *dos_attributes)
2630 struct smb_vfs_call_get_dos_attributes_state *state =
2631 tevent_req_data(req,
2632 struct smb_vfs_call_get_dos_attributes_state);
2635 if (tevent_req_is_nterror(req, &status)) {
2636 tevent_req_received(req);
2640 *aio_state = state->aio_state;
2641 *dos_attributes = state->dos_attributes;
2642 tevent_req_received(req);
2643 return NT_STATUS_OK;
2646 NTSTATUS smb_vfs_call_fget_compression(vfs_handle_struct *handle,
2647 TALLOC_CTX *mem_ctx,
2648 struct files_struct *fsp,
2649 uint16_t *_compression_fmt)
2651 VFS_FIND(fget_compression);
2652 return handle->fns->fget_compression_fn(handle, mem_ctx, fsp,
2656 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2657 TALLOC_CTX *mem_ctx,
2658 struct files_struct *fsp,
2659 uint16_t compression_fmt)
2661 VFS_FIND(set_compression);
2662 return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2666 NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
2667 TALLOC_CTX *mem_ctx,
2668 const char *service_path,
2671 VFS_FIND(snap_check_path);
2672 return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path,
2676 NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle,
2677 TALLOC_CTX *mem_ctx,
2678 const char *base_volume,
2684 VFS_FIND(snap_create);
2685 return handle->fns->snap_create_fn(handle, mem_ctx, base_volume, tstamp,
2686 rw, base_path, snap_path);
2689 NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle,
2690 TALLOC_CTX *mem_ctx,
2694 VFS_FIND(snap_delete);
2695 return handle->fns->snap_delete_fn(handle, mem_ctx, base_path,
2699 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2700 struct files_struct *fsp,
2701 uint32_t security_info,
2702 TALLOC_CTX *mem_ctx,
2703 struct security_descriptor **ppdesc)
2705 VFS_FIND(fget_nt_acl);
2706 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2710 NTSTATUS smb_vfs_call_get_nt_acl_at(struct vfs_handle_struct *handle,
2711 struct files_struct *dirfsp,
2712 const struct smb_filename *smb_fname,
2713 uint32_t security_info,
2714 TALLOC_CTX *mem_ctx,
2715 struct security_descriptor **ppdesc)
2717 VFS_FIND(get_nt_acl_at);
2718 return handle->fns->get_nt_acl_at_fn(handle,
2726 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2727 struct files_struct *fsp,
2728 uint32_t security_info_sent,
2729 const struct security_descriptor *psd)
2731 VFS_FIND(fset_nt_acl);
2732 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2736 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2737 struct smb_filename *file,
2738 struct security_acl *sacl,
2739 uint32_t access_requested,
2740 uint32_t access_denied)
2742 VFS_FIND(audit_file);
2743 return handle->fns->audit_file_fn(handle,
2750 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2751 const struct smb_filename *smb_fname,
2752 SMB_ACL_TYPE_T type,
2753 TALLOC_CTX *mem_ctx)
2755 VFS_FIND(sys_acl_get_file);
2756 return handle->fns->sys_acl_get_file_fn(handle, smb_fname, type, mem_ctx);
2759 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2760 struct files_struct *fsp,
2761 TALLOC_CTX *mem_ctx)
2763 VFS_FIND(sys_acl_get_fd);
2764 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2767 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2768 const struct smb_filename *smb_fname,
2769 TALLOC_CTX *mem_ctx,
2770 char **blob_description,
2773 VFS_FIND(sys_acl_blob_get_file);
2774 return handle->fns->sys_acl_blob_get_file_fn(handle, smb_fname,
2775 mem_ctx, blob_description, blob);
2778 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2779 struct files_struct *fsp,
2780 TALLOC_CTX *mem_ctx,
2781 char **blob_description,
2784 VFS_FIND(sys_acl_blob_get_fd);
2785 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2788 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2789 struct files_struct *fsp,
2790 SMB_ACL_TYPE_T type,
2793 VFS_FIND(sys_acl_set_fd);
2794 return handle->fns->sys_acl_set_fd_fn(handle, fsp, type, theacl);
2797 int smb_vfs_call_sys_acl_delete_def_fd(struct vfs_handle_struct *handle,
2798 struct files_struct *fsp)
2800 VFS_FIND(sys_acl_delete_def_fd);
2801 return handle->fns->sys_acl_delete_def_fd_fn(handle, fsp);
2804 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2805 const struct smb_filename *smb_fname,
2811 return handle->fns->getxattr_fn(handle, smb_fname, name, value, size);
2815 struct smb_vfs_call_getxattrat_state {
2816 files_struct *dir_fsp;
2817 ssize_t (*recv_fn)(struct tevent_req *req,
2818 struct vfs_aio_state *aio_state,
2819 TALLOC_CTX *mem_ctx,
2820 uint8_t **xattr_value);
2822 uint8_t *xattr_value;
2823 struct vfs_aio_state aio_state;
2826 static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq);
2828 struct tevent_req *smb_vfs_call_getxattrat_send(
2829 TALLOC_CTX *mem_ctx,
2830 struct tevent_context *ev,
2831 struct vfs_handle_struct *handle,
2832 files_struct *dir_fsp,
2833 const struct smb_filename *smb_fname,
2834 const char *xattr_name,
2837 struct tevent_req *req = NULL;
2838 struct smb_vfs_call_getxattrat_state *state = NULL;
2839 struct tevent_req *subreq = NULL;
2841 req = tevent_req_create(mem_ctx, &state,
2842 struct smb_vfs_call_getxattrat_state);
2847 VFS_FIND(getxattrat_send);
2849 *state = (struct smb_vfs_call_getxattrat_state) {
2851 .recv_fn = handle->fns->getxattrat_recv_fn,
2854 subreq = handle->fns->getxattrat_send_fn(mem_ctx,
2861 if (tevent_req_nomem(subreq, req)) {
2862 return tevent_req_post(req, ev);
2864 tevent_req_defer_callback(req, ev);
2866 tevent_req_set_callback(subreq, smb_vfs_call_getxattrat_done, req);
2870 static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq)
2872 struct tevent_req *req = tevent_req_callback_data(
2873 subreq, struct tevent_req);
2874 struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2875 req, struct smb_vfs_call_getxattrat_state);
2879 * Make sure we run as the user again
2881 ok = change_to_user_and_service_by_fsp(state->dir_fsp);
2884 state->retval = state->recv_fn(subreq,
2887 &state->xattr_value);
2888 TALLOC_FREE(subreq);
2889 if (state->retval == -1) {
2890 tevent_req_error(req, state->aio_state.error);
2894 tevent_req_done(req);
2897 ssize_t smb_vfs_call_getxattrat_recv(struct tevent_req *req,
2898 struct vfs_aio_state *aio_state,
2899 TALLOC_CTX *mem_ctx,
2900 uint8_t **xattr_value)
2902 struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2903 req, struct smb_vfs_call_getxattrat_state);
2906 if (tevent_req_is_unix_error(req, &aio_state->error)) {
2907 tevent_req_received(req);
2911 *aio_state = state->aio_state;
2912 xattr_size = state->retval;
2913 if (xattr_value != NULL) {
2914 *xattr_value = talloc_move(mem_ctx, &state->xattr_value);
2917 tevent_req_received(req);
2921 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2922 struct files_struct *fsp, const char *name,
2923 void *value, size_t size)
2925 VFS_FIND(fgetxattr);
2926 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2929 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2930 struct files_struct *fsp, char *list,
2933 VFS_FIND(flistxattr);
2934 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2937 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2938 struct files_struct *fsp, const char *name)
2940 VFS_FIND(fremovexattr);
2941 return handle->fns->fremovexattr_fn(handle, fsp, name);
2944 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2945 struct files_struct *fsp, const char *name,
2946 const void *value, size_t size, int flags)
2948 VFS_FIND(fsetxattr);
2949 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2952 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2953 struct files_struct *fsp)
2955 VFS_FIND(aio_force);
2956 return handle->fns->aio_force_fn(handle, fsp);
2959 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2960 struct files_struct *fsp,
2961 TALLOC_CTX *mem_ctx,
2964 VFS_FIND(durable_cookie);
2965 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2968 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2969 struct files_struct *fsp,
2970 const DATA_BLOB old_cookie,
2971 TALLOC_CTX *mem_ctx,
2972 DATA_BLOB *new_cookie)
2974 VFS_FIND(durable_disconnect);
2975 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2976 mem_ctx, new_cookie);
2979 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2980 struct smb_request *smb1req,
2981 struct smbXsrv_open *op,
2982 const DATA_BLOB old_cookie,
2983 TALLOC_CTX *mem_ctx,
2984 struct files_struct **fsp,
2985 DATA_BLOB *new_cookie)
2987 VFS_FIND(durable_reconnect);
2988 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2989 old_cookie, mem_ctx, fsp,
2993 NTSTATUS smb_vfs_call_freaddir_attr(struct vfs_handle_struct *handle,
2994 struct files_struct *fsp,
2995 TALLOC_CTX *mem_ctx,
2996 struct readdir_attr_data **attr_data)
2998 VFS_FIND(freaddir_attr);
2999 return handle->fns->freaddir_attr_fn(handle,