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"
37 #define DBGC_CLASS DBGC_VFS
42 struct vfs_fsp_data *next;
43 struct vfs_handle_struct *owner;
44 void (*destroy)(void *p_data);
46 /* NOTE: This structure contains four pointers so that we can guarantee
47 * that the end of the structure is always both 4-byte and 8-byte aligned.
51 struct vfs_init_function_entry {
53 struct vfs_init_function_entry *prev, *next;
54 const struct vfs_fn_pointers *fns;
57 /****************************************************************************
58 maintain the list of available backends
59 ****************************************************************************/
61 static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
63 struct vfs_init_function_entry *entry = backends;
65 DEBUG(10, ("vfs_find_backend_entry called for %s\n", name));
68 if (strcmp(entry->name, name)==0) return entry;
75 NTSTATUS smb_register_vfs(int version, const char *name,
76 const struct vfs_fn_pointers *fns)
78 struct vfs_init_function_entry *entry = backends;
80 if ((version != SMB_VFS_INTERFACE_VERSION)) {
81 DEBUG(0, ("Failed to register vfs module.\n"
82 "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
83 "current SMB_VFS_INTERFACE_VERSION is %d.\n"
84 "Please recompile against the current Samba Version!\n",
85 version, SMB_VFS_INTERFACE_VERSION));
86 return NT_STATUS_OBJECT_TYPE_MISMATCH;
89 if (!name || !name[0]) {
90 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
91 return NT_STATUS_INVALID_PARAMETER;
94 if (vfs_find_backend_entry(name)) {
95 DEBUG(0,("VFS module %s already loaded!\n", name));
96 return NT_STATUS_OBJECT_NAME_COLLISION;
99 entry = SMB_XMALLOC_P(struct vfs_init_function_entry);
100 entry->name = smb_xstrdup(name);
103 DLIST_ADD(backends, entry);
104 DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
108 /****************************************************************************
109 initialise default vfs hooks
110 ****************************************************************************/
112 static void vfs_init_default(connection_struct *conn)
114 DEBUG(3, ("Initialising default vfs hooks\n"));
115 vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME);
118 /****************************************************************************
119 initialise custom vfs hooks
120 ****************************************************************************/
122 bool vfs_init_custom(connection_struct *conn, const char *vfs_object)
124 char *module_path = NULL;
125 char *module_name = NULL;
126 char *module_param = NULL, *p;
127 vfs_handle_struct *handle;
128 const struct vfs_init_function_entry *entry;
130 if (!conn||!vfs_object||!vfs_object[0]) {
131 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
132 "empty vfs_object!\n"));
137 static_init_vfs(NULL);
140 DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
142 module_path = smb_xstrdup(vfs_object);
144 p = strchr_m(module_path, ':');
149 trim_char(module_param, ' ', ' ');
152 trim_char(module_path, ' ', ' ');
154 module_name = smb_xstrdup(module_path);
156 if ((module_name[0] == '/') &&
157 (strcmp(module_path, DEFAULT_VFS_MODULE_NAME) != 0)) {
160 * Extract the module name from the path. Just use the base
161 * name of the last path component.
164 SAFE_FREE(module_name);
165 module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
167 p = strchr_m(module_name, '.');
174 /* First, try to load the module with the new module system */
175 entry = vfs_find_backend_entry(module_name);
179 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
182 status = smb_load_module("vfs", module_path);
183 if (!NT_STATUS_IS_OK(status)) {
184 DEBUG(0, ("error probing vfs module '%s': %s\n",
185 module_path, nt_errstr(status)));
189 entry = vfs_find_backend_entry(module_name);
191 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
196 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
198 handle = talloc_zero(conn, vfs_handle_struct);
200 DEBUG(0,("TALLOC_ZERO() failed!\n"));
204 handle->fns = entry->fns;
206 handle->param = talloc_strdup(conn, module_param);
208 DLIST_ADD(conn->vfs_handles, handle);
210 SAFE_FREE(module_path);
211 SAFE_FREE(module_name);
215 SAFE_FREE(module_path);
216 SAFE_FREE(module_name);
220 /*****************************************************************
221 Allow VFS modules to extend files_struct with VFS-specific state.
222 This will be ok for small numbers of extensions, but might need to
223 be refactored if it becomes more widely used.
224 ******************************************************************/
226 #define EXT_DATA_AREA(e) ((uint8_t *)(e) + sizeof(struct vfs_fsp_data))
228 void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle,
229 files_struct *fsp, size_t ext_size,
230 void (*destroy_fn)(void *p_data))
232 struct vfs_fsp_data *ext;
235 /* Prevent VFS modules adding multiple extensions. */
236 if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
240 ext = (struct vfs_fsp_data *)TALLOC_ZERO(
241 handle->conn, sizeof(struct vfs_fsp_data) + ext_size);
247 ext->next = fsp->vfs_extension;
248 ext->destroy = destroy_fn;
249 fsp->vfs_extension = ext;
250 return EXT_DATA_AREA(ext);
253 void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
255 struct vfs_fsp_data *curr;
256 struct vfs_fsp_data *prev;
258 for (curr = fsp->vfs_extension, prev = NULL;
260 prev = curr, curr = curr->next) {
261 if (curr->owner == handle) {
263 prev->next = curr->next;
265 fsp->vfs_extension = curr->next;
268 curr->destroy(EXT_DATA_AREA(curr));
276 void vfs_remove_all_fsp_extensions(files_struct *fsp)
278 struct vfs_fsp_data *curr;
279 struct vfs_fsp_data *next;
281 for (curr = fsp->vfs_extension; curr; curr = next) {
284 fsp->vfs_extension = next;
287 curr->destroy(EXT_DATA_AREA(curr));
293 void *vfs_memctx_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
295 struct vfs_fsp_data *head;
297 for (head = fsp->vfs_extension; head; head = head->next) {
298 if (head->owner == handle) {
306 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
308 struct vfs_fsp_data *head;
310 head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
312 return EXT_DATA_AREA(head);
321 * Ensure this module catches all VFS functions.
324 void smb_vfs_assert_all_fns(const struct vfs_fn_pointers* fns,
327 bool missing_fn = false;
329 const uintptr_t *end = (const uintptr_t *)(fns + 1);
331 for (idx = 0; ((const uintptr_t *)fns + idx) < end; idx++) {
332 if (*((const uintptr_t *)fns + idx) == 0) {
333 DBG_ERR("VFS function at index %d not implemented "
334 "in module %s\n", idx, module);
340 smb_panic("Required VFS function not implemented in module.\n");
344 void smb_vfs_assert_all_fns(const struct vfs_fn_pointers* fns,
350 /*****************************************************************
352 ******************************************************************/
354 bool smbd_vfs_init(connection_struct *conn)
356 const char **vfs_objects;
360 /* Normal share - initialise with disk access functions */
361 vfs_init_default(conn);
363 /* No need to load vfs modules for printer connections */
368 vfs_objects = lp_vfs_objects(SNUM(conn));
370 /* Override VFS functions if 'vfs object' was not specified*/
371 if (!vfs_objects || !vfs_objects[0])
374 for (i=0; vfs_objects[i] ;) {
378 for (j=i-1; j >= 0; j--) {
379 if (!vfs_init_custom(conn, vfs_objects[j])) {
380 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
387 /*******************************************************************
388 Check if a file exists in the vfs.
389 ********************************************************************/
391 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
393 /* Only return OK if stat was successful and S_ISREG */
394 if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
395 S_ISREG(smb_fname->st.st_ex_mode)) {
399 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
402 ssize_t vfs_pwrite_data(struct smb_request *req,
411 if (req && req->unread_bytes) {
412 int sockfd = req->xconn->transport.sock;
413 SMB_ASSERT(req->unread_bytes == N);
414 /* VFS_RECVFILE must drain the socket
415 * before returning. */
416 req->unread_bytes = 0;
418 * Leave the socket non-blocking and
419 * use SMB_VFS_RECVFILE. If it returns
420 * EAGAIN || EWOULDBLOCK temporarily set
421 * the socket blocking and retry
425 ret = SMB_VFS_RECVFILE(sockfd,
429 if (ret == 0 || (ret == -1 &&
431 errno == EWOULDBLOCK))) {
433 /* Ensure the socket is blocking. */
434 old_flags = fcntl(sockfd, F_GETFL, 0);
435 if (set_blocking(sockfd, true) == -1) {
438 ret = SMB_VFS_RECVFILE(sockfd,
442 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
449 return (ssize_t)total;
451 /* Any other error case. */
457 return (ssize_t)total;
461 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
471 return (ssize_t)total;
473 /****************************************************************************
474 An allocate file space call using the vfs interface.
475 Allocates space for a file from a filedescriptor.
476 Returns 0 on success, -1 on failure.
477 ****************************************************************************/
479 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
482 connection_struct *conn = fsp->conn;
483 uint64_t space_avail;
484 uint64_t bsize,dfree,dsize;
488 * Actually try and commit the space on disk....
491 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
492 fsp_str_dbg(fsp), (double)len));
494 if (((off_t)len) < 0) {
495 DEBUG(0,("vfs_allocate_file_space: %s negative len "
496 "requested.\n", fsp_str_dbg(fsp)));
501 status = vfs_stat_fsp(fsp);
502 if (!NT_STATUS_IS_OK(status)) {
506 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
509 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
510 /* Shrink - use ftruncate. */
512 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
513 "size %.0f\n", fsp_str_dbg(fsp),
514 (double)fsp->fsp_name->st.st_ex_size));
516 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
518 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
519 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
520 set_filelen_write_cache(fsp, len);
523 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
528 /* Grow - we need to test if we have enough space. */
530 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
532 if (lp_strict_allocate(SNUM(fsp->conn))) {
533 /* See if we have a syscall that will allocate beyond
534 end-of-file without changing EOF. */
535 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_FL_KEEP_SIZE,
541 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
544 /* We changed the allocation size on disk, but not
545 EOF - exactly as required. We're done ! */
549 if (ret == -1 && errno == ENOSPC) {
553 len -= fsp->fsp_name->st.st_ex_size;
554 len /= 1024; /* Len is now number of 1k blocks needed. */
556 get_dfree_info(conn, fsp->fsp_name, &bsize, &dfree, &dsize);
557 if (space_avail == (uint64_t)-1) {
561 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
562 "needed blocks = %.0f, space avail = %.0f\n",
563 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
564 (double)space_avail));
566 if (len > space_avail) {
574 /****************************************************************************
575 A vfs set_filelen call.
576 set the length of a file from a filedescriptor.
577 Returns 0 on success, -1 on failure.
578 ****************************************************************************/
580 int vfs_set_filelen(files_struct *fsp, off_t len)
584 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
586 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
587 fsp_str_dbg(fsp), (double)len));
588 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
589 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
590 set_filelen_write_cache(fsp, len);
591 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
592 FILE_NOTIFY_CHANGE_SIZE
593 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
594 fsp->fsp_name->base_name);
597 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
602 /****************************************************************************
603 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
604 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
605 as this is also called from the default SMB_VFS_FTRUNCATE code.
606 Always extends the file size.
607 Returns 0 on success, -1 on failure.
608 ****************************************************************************/
610 #define SPARSE_BUF_WRITE_SIZE (32*1024)
612 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
618 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
625 while (total < len) {
626 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
628 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
629 if (pwrite_ret == -1) {
630 int saved_errno = errno;
631 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
632 "%s failed with error %s\n",
633 fsp_str_dbg(fsp), strerror(saved_errno)));
643 /****************************************************************************
644 A vfs fill sparse call.
645 Writes zeros from the end of file to len, if len is greater than EOF.
646 Used only by strict_sync.
647 Returns 0 on success, -1 on failure.
648 ****************************************************************************/
650 int vfs_fill_sparse(files_struct *fsp, off_t len)
657 status = vfs_stat_fsp(fsp);
658 if (!NT_STATUS_IS_OK(status)) {
662 if (len <= fsp->fsp_name->st.st_ex_size) {
667 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
672 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
673 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
674 (double)fsp->fsp_name->st.st_ex_size, (double)len,
675 (double)(len - fsp->fsp_name->st.st_ex_size)));
677 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
679 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
681 offset = fsp->fsp_name->st.st_ex_size;
682 num_to_write = len - fsp->fsp_name->st.st_ex_size;
684 /* Only do this on non-stream file handles. */
685 if (fsp->base_fsp == NULL) {
686 /* for allocation try fallocate first. This can fail on some
687 * platforms e.g. when the filesystem doesn't support it and no
688 * emulation is being done by the libc (like on AIX with JFS1). In that
689 * case we do our own emulation. fallocate implementations can
690 * return ENOTSUP or EINVAL in cases like that. */
691 ret = SMB_VFS_FALLOCATE(fsp, 0, offset, num_to_write);
692 if (ret == -1 && errno == ENOSPC) {
698 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
699 "error %d. Falling back to slow manual allocation\n", ret));
702 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
707 set_filelen_write_cache(fsp, len);
710 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
714 /****************************************************************************
715 Transfer some data (n bytes) between two file_struct's.
716 ****************************************************************************/
718 static ssize_t vfs_pread_fn(void *file, void *buf, size_t len, off_t offset)
720 struct files_struct *fsp = (struct files_struct *)file;
722 return SMB_VFS_PREAD(fsp, buf, len, offset);
725 static ssize_t vfs_pwrite_fn(void *file, const void *buf, size_t len, off_t offset)
727 struct files_struct *fsp = (struct files_struct *)file;
729 return SMB_VFS_PWRITE(fsp, buf, len, offset);
732 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
734 return transfer_file_internal((void *)in, (void *)out, n,
735 vfs_pread_fn, vfs_pwrite_fn);
738 /*******************************************************************
739 A vfs_readdir wrapper which just returns the file name.
740 ********************************************************************/
742 const char *vfs_readdirname(connection_struct *conn, void *p,
743 SMB_STRUCT_STAT *sbuf, char **talloced)
745 struct dirent *ptr= NULL;
753 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
765 #ifdef HAVE_BROKEN_READDIR_NAME
766 /* using /usr/ucb/cc is BAD */
770 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
771 talloc_tos(), &translated);
772 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
776 *talloced = translated;
777 if (!NT_STATUS_IS_OK(status)) {
783 /*******************************************************************
784 A wrapper for vfs_chdir().
785 ********************************************************************/
787 int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
790 struct smb_filename *cwd = NULL;
793 LastDir = SMB_STRDUP("");
796 if (ISDOT(smb_fname->base_name)) {
800 if (*smb_fname->base_name == '/' &&
801 strcsequal(LastDir,smb_fname->base_name)) {
805 DEBUG(4,("vfs_ChDir to %s\n", smb_fname->base_name));
807 ret = SMB_VFS_CHDIR(conn, smb_fname);
813 * Always replace conn->cwd_fsp. We
814 * don't know if it's been modified by
815 * VFS modules in the stack.
819 cwd = vfs_GetWd(conn, conn);
822 * vfs_GetWd() failed.
823 * We must be able to read cwd.
824 * Return to original directory
827 int saved_errno = errno;
829 if (conn->cwd_fsp->fsp_name == NULL) {
831 * Failed on the very first chdir()+getwd()
832 * for this connection. We can't
835 smb_panic("conn->cwd getwd failed\n");
840 /* Return to the previous $cwd. */
841 ret = SMB_VFS_CHDIR(conn, conn->cwd_fsp->fsp_name);
843 smb_panic("conn->cwd getwd failed\n");
848 /* And fail the chdir(). */
852 /* vfs_GetWd() succeeded. */
853 /* Replace global cache. */
855 LastDir = SMB_STRDUP(smb_fname->base_name);
858 * (Indirect) Callers of vfs_ChDir() may still hold references to the
859 * old conn->cwd_fsp->fsp_name. Move it to talloc_tos(), that way
860 * callers can use it for the lifetime of the SMB request.
862 talloc_move(talloc_tos(), &conn->cwd_fsp->fsp_name);
864 conn->cwd_fsp->fsp_name = talloc_move(conn->cwd_fsp, &cwd);
865 conn->cwd_fsp->fh->fd = AT_FDCWD;
867 DBG_INFO("vfs_ChDir got %s\n", fsp_str_dbg(conn->cwd_fsp));
872 /*******************************************************************
873 Return the absolute current directory path - given a UNIX pathname.
874 Note that this path is returned in DOS format, not UNIX
875 format. Note this can be called with conn == NULL.
876 ********************************************************************/
878 struct smb_filename *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
880 struct smb_filename *current_dir_fname = NULL;
882 struct smb_filename *smb_fname_dot = NULL;
883 struct smb_filename *smb_fname_full = NULL;
884 struct smb_filename *result = NULL;
886 if (!lp_getwd_cache()) {
890 smb_fname_dot = synthetic_smb_fname(ctx, ".", NULL, NULL, 0);
891 if (smb_fname_dot == NULL) {
896 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
898 * Known to fail for root: the directory may be NFS-mounted
899 * and exported with root_squash (so has no root access).
901 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
902 "(NFS problem ?)\n", strerror(errno) ));
906 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
908 smb_fname_full = (struct smb_filename *)memcache_lookup_talloc(
911 data_blob_const(&key, sizeof(key)));
913 if (smb_fname_full == NULL) {
917 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
918 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
919 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
920 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
923 * Note: smb_fname_full is owned by smbd_memcache()
924 * so we must make a copy to return.
926 result = cp_smb_filename(ctx, smb_fname_full);
927 if (result == NULL) {
936 * We don't have the information to hand so rely on traditional
937 * methods. The very slow getcwd, which spawns a process on some
938 * systems, or the not quite so bad getwd.
941 current_dir_fname = SMB_VFS_GETWD(conn, ctx);
942 if (current_dir_fname == NULL) {
943 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
948 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
949 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
952 * smbd_memcache() will own current_dir_fname after the
953 * memcache_add_talloc call, so we must make
954 * a copy on ctx to return.
956 result = cp_smb_filename(ctx, current_dir_fname);
957 if (result == NULL) {
962 * Ensure the memory going into the cache
963 * doesn't have a destructor so it can be
966 talloc_set_destructor(current_dir_fname, NULL);
968 memcache_add_talloc(smbd_memcache(),
970 data_blob_const(&key, sizeof(key)),
972 /* current_dir_fname is now == NULL here. */
974 /* current_dir_fname is already allocated on ctx. */
975 result = current_dir_fname;
979 TALLOC_FREE(smb_fname_dot);
981 * Don't free current_dir_fname here. It's either been moved
982 * to the memcache or is being returned in result.
987 /*******************************************************************
988 Reduce a file name, removing .. elements and checking that
989 it is below dir in the hierarchy. This uses realpath.
990 This function must run as root, and will return names
991 and valid stat structs that can be checked on open.
992 ********************************************************************/
994 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
995 const struct smb_filename *smb_fname,
996 struct smb_request *smbreq)
999 TALLOC_CTX *ctx = talloc_tos();
1000 const char *conn_rootdir;
1002 char *dir_name = NULL;
1003 char *resolved_name = NULL;
1004 const char *last_component = NULL;
1005 struct smb_filename *resolved_fname = NULL;
1006 struct smb_filename *saved_dir_fname = NULL;
1007 struct smb_filename *smb_fname_cwd = NULL;
1008 struct privilege_paths *priv_paths = NULL;
1011 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
1012 smb_fname->base_name,
1013 conn->connectpath));
1016 priv_paths = talloc_zero(smbreq, struct privilege_paths);
1018 status = NT_STATUS_NO_MEMORY;
1022 if (!parent_dirname(ctx, smb_fname->base_name,
1023 &dir_name, &last_component)) {
1024 status = NT_STATUS_NO_MEMORY;
1028 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
1029 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
1031 if (priv_paths->parent_name.base_name == NULL ||
1032 priv_paths->file_name.base_name == NULL) {
1033 status = NT_STATUS_NO_MEMORY;
1037 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
1038 status = map_nt_error_from_unix(errno);
1041 /* Remember where we were. */
1042 saved_dir_fname = vfs_GetWd(ctx, conn);
1043 if (!saved_dir_fname) {
1044 status = map_nt_error_from_unix(errno);
1048 if (vfs_ChDir(conn, &priv_paths->parent_name) == -1) {
1049 status = map_nt_error_from_unix(errno);
1053 smb_fname_cwd = synthetic_smb_fname(talloc_tos(), ".", NULL, NULL, 0);
1054 if (smb_fname_cwd == NULL) {
1055 status = NT_STATUS_NO_MEMORY;
1059 /* Get the absolute path of the parent directory. */
1060 resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname_cwd);
1061 if (resolved_fname == NULL) {
1062 status = map_nt_error_from_unix(errno);
1065 resolved_name = resolved_fname->base_name;
1067 if (*resolved_name != '/') {
1068 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1069 "doesn't return absolute paths !\n"));
1070 status = NT_STATUS_OBJECT_NAME_INVALID;
1074 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1075 priv_paths->parent_name.base_name,
1078 /* Now check the stat value is the same. */
1079 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1080 status = map_nt_error_from_unix(errno);
1084 /* Ensure we're pointing at the same place. */
1085 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1086 DEBUG(0,("check_reduced_name_with_privilege: "
1087 "device/inode/uid/gid on directory %s changed. "
1088 "Denying access !\n",
1089 priv_paths->parent_name.base_name));
1090 status = NT_STATUS_ACCESS_DENIED;
1094 /* Ensure we're below the connect path. */
1096 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
1097 if (conn_rootdir == NULL) {
1098 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1100 status = NT_STATUS_ACCESS_DENIED;
1104 rootdir_len = strlen(conn_rootdir);
1107 * In the case of rootdir_len == 1, we know that conn_rootdir is
1108 * "/", and we also know that resolved_name starts with a slash.
1109 * So, in this corner case, resolved_name is automatically a
1110 * sub-directory of the conn_rootdir. Thus we can skip the string
1111 * comparison and the next character checks (which are even
1112 * wrong in this case).
1114 if (rootdir_len != 1) {
1117 matched = (strncmp(conn_rootdir, resolved_name,
1120 if (!matched || (resolved_name[rootdir_len] != '/' &&
1121 resolved_name[rootdir_len] != '\0')) {
1122 DEBUG(2, ("check_reduced_name_with_privilege: Bad "
1123 "access attempt: %s is a symlink outside the "
1126 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1127 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1128 status = NT_STATUS_ACCESS_DENIED;
1133 /* Now ensure that the last component either doesn't
1134 exist, or is *NOT* a symlink. */
1136 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1138 /* Errno must be ENOENT for this be ok. */
1139 if (errno != ENOENT) {
1140 status = map_nt_error_from_unix(errno);
1141 DEBUG(2, ("check_reduced_name_with_privilege: "
1142 "LSTAT on %s failed with %s\n",
1143 priv_paths->file_name.base_name,
1144 nt_errstr(status)));
1149 if (VALID_STAT(priv_paths->file_name.st) &&
1150 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1151 DEBUG(2, ("check_reduced_name_with_privilege: "
1152 "Last component %s is a symlink. Denying"
1154 priv_paths->file_name.base_name));
1155 status = NT_STATUS_ACCESS_DENIED;
1159 smbreq->priv_paths = priv_paths;
1160 status = NT_STATUS_OK;
1164 if (saved_dir_fname != NULL) {
1165 vfs_ChDir(conn, saved_dir_fname);
1166 TALLOC_FREE(saved_dir_fname);
1168 TALLOC_FREE(resolved_fname);
1169 if (!NT_STATUS_IS_OK(status)) {
1170 TALLOC_FREE(priv_paths);
1172 TALLOC_FREE(dir_name);
1176 /*******************************************************************
1177 Reduce a file name, removing .. elements and checking that
1178 it is below dir in the hierarchy. This uses realpath.
1180 If cwd_name == NULL then fname is a client given path relative
1181 to the root path of the share.
1183 If cwd_name != NULL then fname is a client given path relative
1184 to cwd_name. cwd_name is relative to the root path of the share.
1185 ********************************************************************/
1187 NTSTATUS check_reduced_name(connection_struct *conn,
1188 const struct smb_filename *cwd_fname,
1189 const struct smb_filename *smb_fname)
1191 TALLOC_CTX *ctx = talloc_tos();
1192 const char *cwd_name = cwd_fname ? cwd_fname->base_name : NULL;
1193 const char *fname = smb_fname->base_name;
1194 struct smb_filename *resolved_fname;
1195 char *resolved_name = NULL;
1196 char *new_fname = NULL;
1197 bool allow_symlinks = true;
1198 bool allow_widelinks = false;
1200 DBG_DEBUG("check_reduced_name [%s] [%s]\n", fname, conn->connectpath);
1202 resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname);
1204 if (resolved_fname == NULL) {
1207 DEBUG(3,("check_reduced_name: Component not a "
1208 "directory in getting realpath for "
1210 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1213 char *dir_name = NULL;
1214 struct smb_filename dir_fname = {0};
1215 const char *last_component = NULL;
1217 /* Last component didn't exist.
1218 Remove it and try and canonicalise
1219 the directory name. */
1220 if (!parent_dirname(ctx, fname,
1223 return NT_STATUS_NO_MEMORY;
1226 dir_fname = (struct smb_filename)
1227 { .base_name = dir_name };
1228 resolved_fname = SMB_VFS_REALPATH(conn,
1231 if (resolved_fname == NULL) {
1232 NTSTATUS status = map_nt_error_from_unix(errno);
1234 if (errno == ENOENT || errno == ENOTDIR) {
1235 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1238 DEBUG(3,("check_reduce_name: "
1239 "couldn't get realpath for "
1242 nt_errstr(status)));
1245 resolved_name = talloc_asprintf(ctx,
1247 resolved_fname->base_name,
1249 if (resolved_name == NULL) {
1250 return NT_STATUS_NO_MEMORY;
1255 DEBUG(3,("check_reduced_name: couldn't get "
1256 "realpath for %s\n", fname));
1257 return map_nt_error_from_unix(errno);
1260 resolved_name = resolved_fname->base_name;
1263 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1266 if (*resolved_name != '/') {
1267 DEBUG(0,("check_reduced_name: realpath doesn't return "
1268 "absolute paths !\n"));
1269 TALLOC_FREE(resolved_fname);
1270 return NT_STATUS_OBJECT_NAME_INVALID;
1273 allow_widelinks = lp_widelinks(SNUM(conn));
1274 allow_symlinks = lp_follow_symlinks(SNUM(conn));
1276 /* Common widelinks and symlinks checks. */
1277 if (!allow_widelinks || !allow_symlinks) {
1278 const char *conn_rootdir;
1281 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
1282 if (conn_rootdir == NULL) {
1283 DEBUG(2, ("check_reduced_name: Could not get "
1285 TALLOC_FREE(resolved_fname);
1286 return NT_STATUS_ACCESS_DENIED;
1289 rootdir_len = strlen(conn_rootdir);
1292 * In the case of rootdir_len == 1, we know that
1293 * conn_rootdir is "/", and we also know that
1294 * resolved_name starts with a slash. So, in this
1295 * corner case, resolved_name is automatically a
1296 * sub-directory of the conn_rootdir. Thus we can skip
1297 * the string comparison and the next character checks
1298 * (which are even wrong in this case).
1300 if (rootdir_len != 1) {
1303 matched = (strncmp(conn_rootdir, resolved_name,
1305 if (!matched || (resolved_name[rootdir_len] != '/' &&
1306 resolved_name[rootdir_len] != '\0')) {
1307 DEBUG(2, ("check_reduced_name: Bad access "
1308 "attempt: %s is a symlink outside the "
1309 "share path\n", fname));
1310 DEBUGADD(2, ("conn_rootdir =%s\n",
1312 DEBUGADD(2, ("resolved_name=%s\n",
1314 TALLOC_FREE(resolved_fname);
1315 return NT_STATUS_ACCESS_DENIED;
1319 /* Extra checks if all symlinks are disallowed. */
1320 if (!allow_symlinks) {
1321 /* fname can't have changed in resolved_path. */
1322 const char *p = &resolved_name[rootdir_len];
1325 * UNIX filesystem semantics, names consisting
1326 * only of "." or ".." CANNOT be symlinks.
1328 if (ISDOT(fname) || ISDOTDOT(fname)) {
1333 DEBUG(2, ("check_reduced_name: logic error (%c) "
1334 "in resolved_name: %s\n",
1337 TALLOC_FREE(resolved_fname);
1338 return NT_STATUS_ACCESS_DENIED;
1344 * If cwd_name is present and not ".",
1345 * then fname is relative to that, not
1346 * the root of the share. Make sure the
1347 * path we check is the one the client
1348 * sent (cwd_name+fname).
1350 if (cwd_name != NULL && !ISDOT(cwd_name)) {
1351 new_fname = talloc_asprintf(ctx,
1355 if (new_fname == NULL) {
1356 TALLOC_FREE(resolved_fname);
1357 return NT_STATUS_NO_MEMORY;
1362 if (strcmp(fname, p)!=0) {
1363 DEBUG(2, ("check_reduced_name: Bad access "
1364 "attempt: %s is a symlink to %s\n",
1366 TALLOC_FREE(resolved_fname);
1367 TALLOC_FREE(new_fname);
1368 return NT_STATUS_ACCESS_DENIED;
1375 DBG_INFO("%s reduced to %s\n", fname, resolved_name);
1376 TALLOC_FREE(resolved_fname);
1377 TALLOC_FREE(new_fname);
1378 return NT_STATUS_OK;
1382 * XXX: This is temporary and there should be no callers of this once
1383 * smb_filename is plumbed through all path based operations.
1385 * Called when we know stream name parsing has already been done.
1387 int vfs_stat_smb_basename(struct connection_struct *conn,
1388 const struct smb_filename *smb_fname_in,
1389 SMB_STRUCT_STAT *psbuf)
1391 struct smb_filename smb_fname = {
1392 .base_name = discard_const_p(char, smb_fname_in->base_name),
1393 .flags = smb_fname_in->flags
1397 if (smb_fname.flags & SMB_FILENAME_POSIX_PATH) {
1398 ret = SMB_VFS_LSTAT(conn, &smb_fname);
1400 ret = SMB_VFS_STAT(conn, &smb_fname);
1404 *psbuf = smb_fname.st;
1410 * Ensure LSTAT is called for POSIX paths.
1413 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1417 if(fsp->fh->fd == -1) {
1418 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1419 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1421 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1424 return map_nt_error_from_unix(errno);
1427 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1428 return map_nt_error_from_unix(errno);
1431 return NT_STATUS_OK;
1435 * Initialize num_streams and streams, then call VFS op streaminfo
1437 NTSTATUS vfs_streaminfo(connection_struct *conn,
1438 struct files_struct *fsp,
1439 const struct smb_filename *smb_fname,
1440 TALLOC_CTX *mem_ctx,
1441 unsigned int *num_streams,
1442 struct stream_struct **streams)
1446 return SMB_VFS_STREAMINFO(conn,
1455 generate a file_id from a stat structure
1457 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1459 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1462 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1463 const char *service, const char *user)
1466 return handle->fns->connect_fn(handle, service, user);
1469 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1471 VFS_FIND(disconnect);
1472 handle->fns->disconnect_fn(handle);
1475 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1476 const struct smb_filename *smb_fname,
1481 VFS_FIND(disk_free);
1482 return handle->fns->disk_free_fn(handle, smb_fname,
1483 bsize, dfree, dsize);
1486 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1487 const struct smb_filename *smb_fname,
1488 enum SMB_QUOTA_TYPE qtype,
1492 VFS_FIND(get_quota);
1493 return handle->fns->get_quota_fn(handle, smb_fname, qtype, id, qt);
1496 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1497 enum SMB_QUOTA_TYPE qtype, unid_t id,
1500 VFS_FIND(set_quota);
1501 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1504 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1505 struct files_struct *fsp,
1506 struct shadow_copy_data *shadow_copy_data,
1509 VFS_FIND(get_shadow_copy_data);
1510 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1514 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle,
1515 const struct smb_filename *smb_fname,
1516 struct vfs_statvfs_struct *statbuf)
1519 return handle->fns->statvfs_fn(handle, smb_fname, statbuf);
1522 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1523 enum timestamp_set_resolution *p_ts_res)
1525 VFS_FIND(fs_capabilities);
1526 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1529 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1530 struct dfs_GetDFSReferral *r)
1532 VFS_FIND(get_dfs_referrals);
1533 return handle->fns->get_dfs_referrals_fn(handle, r);
1536 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1537 const struct smb_filename *smb_fname,
1539 uint32_t attributes)
1542 return handle->fns->opendir_fn(handle, smb_fname, mask, attributes);
1545 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1546 struct files_struct *fsp,
1548 uint32_t attributes)
1550 VFS_FIND(fdopendir);
1551 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1554 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1556 SMB_STRUCT_STAT *sbuf)
1559 return handle->fns->readdir_fn(handle, dirp, sbuf);
1562 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1563 DIR *dirp, long offset)
1566 handle->fns->seekdir_fn(handle, dirp, offset);
1569 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1573 return handle->fns->telldir_fn(handle, dirp);
1576 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1579 VFS_FIND(rewind_dir);
1580 handle->fns->rewind_dir_fn(handle, dirp);
1583 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle,
1584 const struct smb_filename *smb_fname,
1588 return handle->fns->mkdir_fn(handle, smb_fname, mode);
1591 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle,
1592 const struct smb_filename *smb_fname)
1595 return handle->fns->rmdir_fn(handle, smb_fname);
1598 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1602 return handle->fns->closedir_fn(handle, dir);
1605 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1606 struct smb_filename *smb_fname, struct files_struct *fsp,
1607 int flags, mode_t mode)
1610 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1613 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1614 struct smb_request *req,
1615 uint16_t root_dir_fid,
1616 struct smb_filename *smb_fname,
1617 uint32_t access_mask,
1618 uint32_t share_access,
1619 uint32_t create_disposition,
1620 uint32_t create_options,
1621 uint32_t file_attributes,
1622 uint32_t oplock_request,
1623 const struct smb2_lease *lease,
1624 uint64_t allocation_size,
1625 uint32_t private_flags,
1626 struct security_descriptor *sd,
1627 struct ea_list *ea_list,
1628 files_struct **result,
1630 const struct smb2_create_blobs *in_context_blobs,
1631 struct smb2_create_blobs *out_context_blobs)
1633 VFS_FIND(create_file);
1634 return handle->fns->create_file_fn(
1635 handle, req, root_dir_fid, smb_fname, access_mask,
1636 share_access, create_disposition, create_options,
1637 file_attributes, oplock_request, lease, allocation_size,
1638 private_flags, sd, ea_list,
1639 result, pinfo, in_context_blobs, out_context_blobs);
1642 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1643 struct files_struct *fsp)
1646 return handle->fns->close_fn(handle, fsp);
1649 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1650 struct files_struct *fsp, void *data, size_t n,
1654 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1657 struct smb_vfs_call_pread_state {
1658 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1660 struct vfs_aio_state vfs_aio_state;
1663 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1665 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1666 TALLOC_CTX *mem_ctx,
1667 struct tevent_context *ev,
1668 struct files_struct *fsp,
1670 size_t n, off_t offset)
1672 struct tevent_req *req, *subreq;
1673 struct smb_vfs_call_pread_state *state;
1675 req = tevent_req_create(mem_ctx, &state,
1676 struct smb_vfs_call_pread_state);
1680 VFS_FIND(pread_send);
1681 state->recv_fn = handle->fns->pread_recv_fn;
1683 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1685 if (tevent_req_nomem(subreq, req)) {
1686 return tevent_req_post(req, ev);
1688 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1692 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1694 struct tevent_req *req = tevent_req_callback_data(
1695 subreq, struct tevent_req);
1696 struct smb_vfs_call_pread_state *state = tevent_req_data(
1697 req, struct smb_vfs_call_pread_state);
1699 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1700 TALLOC_FREE(subreq);
1701 if (state->retval == -1) {
1702 tevent_req_error(req, state->vfs_aio_state.error);
1705 tevent_req_done(req);
1708 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req,
1709 struct vfs_aio_state *vfs_aio_state)
1711 struct smb_vfs_call_pread_state *state = tevent_req_data(
1712 req, struct smb_vfs_call_pread_state);
1715 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1716 tevent_req_received(req);
1719 *vfs_aio_state = state->vfs_aio_state;
1720 retval = state->retval;
1721 tevent_req_received(req);
1725 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1726 struct files_struct *fsp, const void *data,
1727 size_t n, off_t offset)
1730 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1733 struct smb_vfs_call_pwrite_state {
1734 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1736 struct vfs_aio_state vfs_aio_state;
1739 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1741 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1742 TALLOC_CTX *mem_ctx,
1743 struct tevent_context *ev,
1744 struct files_struct *fsp,
1746 size_t n, off_t offset)
1748 struct tevent_req *req, *subreq;
1749 struct smb_vfs_call_pwrite_state *state;
1751 req = tevent_req_create(mem_ctx, &state,
1752 struct smb_vfs_call_pwrite_state);
1756 VFS_FIND(pwrite_send);
1757 state->recv_fn = handle->fns->pwrite_recv_fn;
1759 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1761 if (tevent_req_nomem(subreq, req)) {
1762 return tevent_req_post(req, ev);
1764 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1768 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1770 struct tevent_req *req = tevent_req_callback_data(
1771 subreq, struct tevent_req);
1772 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1773 req, struct smb_vfs_call_pwrite_state);
1775 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1776 TALLOC_FREE(subreq);
1777 if (state->retval == -1) {
1778 tevent_req_error(req, state->vfs_aio_state.error);
1781 tevent_req_done(req);
1784 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req,
1785 struct vfs_aio_state *vfs_aio_state)
1787 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1788 req, struct smb_vfs_call_pwrite_state);
1791 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1792 tevent_req_received(req);
1795 *vfs_aio_state = state->vfs_aio_state;
1796 retval = state->retval;
1797 tevent_req_received(req);
1801 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1802 struct files_struct *fsp, off_t offset,
1806 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1809 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1810 files_struct *fromfsp, const DATA_BLOB *header,
1811 off_t offset, size_t count)
1814 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1818 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1819 files_struct *tofsp, off_t offset,
1823 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1826 int smb_vfs_call_renameat(struct vfs_handle_struct *handle,
1827 files_struct *srcfsp,
1828 const struct smb_filename *smb_fname_src,
1829 files_struct *dstfsp,
1830 const struct smb_filename *smb_fname_dst)
1833 return handle->fns->renameat_fn(handle,
1840 struct smb_vfs_call_fsync_state {
1841 int (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1843 struct vfs_aio_state vfs_aio_state;
1846 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1848 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1849 TALLOC_CTX *mem_ctx,
1850 struct tevent_context *ev,
1851 struct files_struct *fsp)
1853 struct tevent_req *req, *subreq;
1854 struct smb_vfs_call_fsync_state *state;
1856 req = tevent_req_create(mem_ctx, &state,
1857 struct smb_vfs_call_fsync_state);
1861 VFS_FIND(fsync_send);
1862 state->recv_fn = handle->fns->fsync_recv_fn;
1864 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1865 if (tevent_req_nomem(subreq, req)) {
1866 return tevent_req_post(req, ev);
1868 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1872 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1874 struct tevent_req *req = tevent_req_callback_data(
1875 subreq, struct tevent_req);
1876 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1877 req, struct smb_vfs_call_fsync_state);
1879 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1880 TALLOC_FREE(subreq);
1881 if (state->retval == -1) {
1882 tevent_req_error(req, state->vfs_aio_state.error);
1885 tevent_req_done(req);
1888 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state)
1890 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1891 req, struct smb_vfs_call_fsync_state);
1894 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1895 tevent_req_received(req);
1898 *vfs_aio_state = state->vfs_aio_state;
1899 retval = state->retval;
1900 tevent_req_received(req);
1905 * Synchronous version of fsync, built from backend
1906 * async VFS primitives. Uses a temporary sub-event
1907 * context (NOT NESTED).
1910 int smb_vfs_fsync_sync(files_struct *fsp)
1912 TALLOC_CTX *frame = talloc_stackframe();
1913 struct tevent_req *req = NULL;
1914 struct vfs_aio_state aio_state = { 0 };
1917 struct tevent_context *ev = samba_tevent_context_init(frame);
1923 req = SMB_VFS_FSYNC_SEND(talloc_tos(), ev, fsp);
1928 ok = tevent_req_poll(req, ev);
1933 ret = SMB_VFS_FSYNC_RECV(req, &aio_state);
1938 if (aio_state.error != 0) {
1939 errno = aio_state.error;
1944 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1945 struct smb_filename *smb_fname)
1948 return handle->fns->stat_fn(handle, smb_fname);
1951 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1952 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1955 return handle->fns->fstat_fn(handle, fsp, sbuf);
1958 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1959 struct smb_filename *smb_filename)
1962 return handle->fns->lstat_fn(handle, smb_filename);
1965 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1966 struct files_struct *fsp,
1967 const SMB_STRUCT_STAT *sbuf)
1969 VFS_FIND(get_alloc_size);
1970 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1973 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1974 const struct smb_filename *smb_fname)
1977 return handle->fns->unlink_fn(handle, smb_fname);
1980 int smb_vfs_call_chmod(struct vfs_handle_struct *handle,
1981 const struct smb_filename *smb_fname,
1985 return handle->fns->chmod_fn(handle, smb_fname, mode);
1988 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1989 struct files_struct *fsp, mode_t mode)
1992 return handle->fns->fchmod_fn(handle, fsp, mode);
1995 int smb_vfs_call_chown(struct vfs_handle_struct *handle,
1996 const struct smb_filename *smb_fname,
2001 return handle->fns->chown_fn(handle, smb_fname, uid, gid);
2004 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
2005 struct files_struct *fsp, uid_t uid, gid_t gid)
2008 return handle->fns->fchown_fn(handle, fsp, uid, gid);
2011 int smb_vfs_call_lchown(struct vfs_handle_struct *handle,
2012 const struct smb_filename *smb_fname,
2017 return handle->fns->lchown_fn(handle, smb_fname, uid, gid);
2020 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
2023 bool as_root = false;
2026 if (fsp->fh->fd != -1) {
2028 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
2030 return NT_STATUS_OK;
2032 if (ret == -1 && errno != ENOSYS) {
2033 return map_nt_error_from_unix(errno);
2037 as_root = (geteuid() == 0);
2041 * We are being asked to chown as root. Make
2042 * sure we chdir() into the path to pin it,
2043 * and always act using lchown to ensure we
2044 * don't deref any symbolic links.
2046 char *parent_dir = NULL;
2047 const char *final_component = NULL;
2048 struct smb_filename *local_smb_fname = NULL;
2049 struct smb_filename parent_dir_fname = {0};
2050 struct smb_filename *saved_dir_fname = NULL;
2052 saved_dir_fname = vfs_GetWd(talloc_tos(),fsp->conn);
2053 if (!saved_dir_fname) {
2054 status = map_nt_error_from_unix(errno);
2055 DEBUG(0,("vfs_chown_fsp: failed to get "
2056 "current working directory. Error was %s\n",
2061 if (!parent_dirname(talloc_tos(),
2062 fsp->fsp_name->base_name,
2064 &final_component)) {
2065 return NT_STATUS_NO_MEMORY;
2068 parent_dir_fname = (struct smb_filename) {
2069 .base_name = parent_dir,
2070 .flags = fsp->fsp_name->flags
2073 /* cd into the parent dir to pin it. */
2074 ret = vfs_ChDir(fsp->conn, &parent_dir_fname);
2076 return map_nt_error_from_unix(errno);
2079 local_smb_fname = synthetic_smb_fname(talloc_tos(),
2083 fsp->fsp_name->flags);
2084 if (local_smb_fname == NULL) {
2085 status = NT_STATUS_NO_MEMORY;
2089 /* Must use lstat here. */
2090 ret = SMB_VFS_LSTAT(fsp->conn, local_smb_fname);
2092 status = map_nt_error_from_unix(errno);
2096 /* Ensure it matches the fsp stat. */
2097 if (!check_same_stat(&local_smb_fname->st,
2098 &fsp->fsp_name->st)) {
2099 status = NT_STATUS_ACCESS_DENIED;
2103 ret = SMB_VFS_LCHOWN(fsp->conn,
2108 status = NT_STATUS_OK;
2110 status = map_nt_error_from_unix(errno);
2115 vfs_ChDir(fsp->conn, saved_dir_fname);
2116 TALLOC_FREE(local_smb_fname);
2117 TALLOC_FREE(saved_dir_fname);
2118 TALLOC_FREE(parent_dir);
2123 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
2124 ret = SMB_VFS_LCHOWN(fsp->conn,
2128 ret = SMB_VFS_CHOWN(fsp->conn,
2134 status = NT_STATUS_OK;
2136 status = map_nt_error_from_unix(errno);
2141 int smb_vfs_call_chdir(struct vfs_handle_struct *handle,
2142 const struct smb_filename *smb_fname)
2145 return handle->fns->chdir_fn(handle, smb_fname);
2148 struct smb_filename *smb_vfs_call_getwd(struct vfs_handle_struct *handle,
2152 return handle->fns->getwd_fn(handle, ctx);
2155 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
2156 const struct smb_filename *smb_fname,
2157 struct smb_file_time *ft)
2160 return handle->fns->ntimes_fn(handle, smb_fname, ft);
2163 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2164 struct files_struct *fsp, off_t offset)
2166 VFS_FIND(ftruncate);
2167 return handle->fns->ftruncate_fn(handle, fsp, offset);
2170 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2171 struct files_struct *fsp,
2176 VFS_FIND(fallocate);
2177 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2180 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2181 struct files_struct *fsp, uint32_t share_mode,
2182 uint32_t access_mask)
2184 VFS_FIND(kernel_flock);
2185 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2189 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2190 struct files_struct *fsp, int leasetype)
2192 VFS_FIND(linux_setlease);
2193 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2196 int smb_vfs_call_symlink(struct vfs_handle_struct *handle,
2197 const char *link_target,
2198 const struct smb_filename *new_smb_fname)
2201 return handle->fns->symlink_fn(handle, link_target, new_smb_fname);
2204 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2205 const struct smb_filename *smb_fname,
2210 return handle->fns->readlink_fn(handle, smb_fname, buf, bufsiz);
2213 int smb_vfs_call_readlinkat(struct vfs_handle_struct *handle,
2214 struct files_struct *dirfsp,
2215 const struct smb_filename *smb_fname,
2219 VFS_FIND(readlinkat);
2220 return handle->fns->readlinkat_fn(handle,
2227 int smb_vfs_call_linkat(struct vfs_handle_struct *handle,
2228 struct files_struct *srcfsp,
2229 const struct smb_filename *old_smb_fname,
2230 struct files_struct *dstfsp,
2231 const struct smb_filename *new_smb_fname,
2235 return handle->fns->linkat_fn(handle,
2243 int smb_vfs_call_mknodat(struct vfs_handle_struct *handle,
2244 struct files_struct *dirfsp,
2245 const struct smb_filename *smb_fname,
2250 return handle->fns->mknodat_fn(handle,
2257 struct smb_filename *smb_vfs_call_realpath(struct vfs_handle_struct *handle,
2259 const struct smb_filename *smb_fname)
2262 return handle->fns->realpath_fn(handle, ctx, smb_fname);
2265 int smb_vfs_call_chflags(struct vfs_handle_struct *handle,
2266 const struct smb_filename *smb_fname,
2270 return handle->fns->chflags_fn(handle, smb_fname, flags);
2273 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2274 const SMB_STRUCT_STAT *sbuf)
2276 VFS_FIND(file_id_create);
2277 return handle->fns->file_id_create_fn(handle, sbuf);
2280 uint64_t smb_vfs_call_fs_file_id(struct vfs_handle_struct *handle,
2281 const SMB_STRUCT_STAT *sbuf)
2283 VFS_FIND(fs_file_id);
2284 return handle->fns->fs_file_id_fn(handle, sbuf);
2287 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2288 struct files_struct *fsp,
2289 const struct smb_filename *smb_fname,
2290 TALLOC_CTX *mem_ctx,
2291 unsigned int *num_streams,
2292 struct stream_struct **streams)
2294 VFS_FIND(streaminfo);
2295 return handle->fns->streaminfo_fn(handle, fsp, smb_fname, mem_ctx,
2296 num_streams, streams);
2299 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2300 const char *path, const char *name,
2301 TALLOC_CTX *mem_ctx, char **found_name)
2303 VFS_FIND(get_real_filename);
2304 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2308 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2309 const struct smb_filename *smb_fname)
2311 VFS_FIND(connectpath);
2312 return handle->fns->connectpath_fn(handle, smb_fname);
2315 bool smb_vfs_call_strict_lock_check(struct vfs_handle_struct *handle,
2316 struct files_struct *fsp,
2317 struct lock_struct *plock)
2319 VFS_FIND(strict_lock_check);
2320 return handle->fns->strict_lock_check_fn(handle, fsp, plock);
2323 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2325 enum vfs_translate_direction direction,
2326 TALLOC_CTX *mem_ctx,
2329 VFS_FIND(translate_name);
2330 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2334 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2335 struct files_struct *fsp,
2339 const uint8_t *in_data,
2342 uint32_t max_out_len,
2346 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2347 in_data, in_len, out_data, max_out_len,
2351 NTSTATUS smb_vfs_call_get_dos_attributes(struct vfs_handle_struct *handle,
2352 struct smb_filename *smb_fname,
2355 VFS_FIND(get_dos_attributes);
2356 return handle->fns->get_dos_attributes_fn(handle, smb_fname, dosmode);
2359 NTSTATUS smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct *handle,
2360 struct files_struct *fsp,
2363 VFS_FIND(fget_dos_attributes);
2364 return handle->fns->fget_dos_attributes_fn(handle, fsp, dosmode);
2367 NTSTATUS smb_vfs_call_set_dos_attributes(struct vfs_handle_struct *handle,
2368 const struct smb_filename *smb_fname,
2371 VFS_FIND(set_dos_attributes);
2372 return handle->fns->set_dos_attributes_fn(handle, smb_fname, dosmode);
2375 NTSTATUS smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct *handle,
2376 struct files_struct *fsp,
2379 VFS_FIND(set_dos_attributes);
2380 return handle->fns->fset_dos_attributes_fn(handle, fsp, dosmode);
2383 struct tevent_req *smb_vfs_call_offload_read_send(TALLOC_CTX *mem_ctx,
2384 struct tevent_context *ev,
2385 struct vfs_handle_struct *handle,
2386 struct files_struct *fsp,
2392 VFS_FIND(offload_read_send);
2393 return handle->fns->offload_read_send_fn(mem_ctx, ev, handle,
2395 ttl, offset, to_copy);
2398 NTSTATUS smb_vfs_call_offload_read_recv(struct tevent_req *req,
2399 struct vfs_handle_struct *handle,
2400 TALLOC_CTX *mem_ctx,
2401 DATA_BLOB *token_blob)
2403 VFS_FIND(offload_read_recv);
2404 return handle->fns->offload_read_recv_fn(req, handle, mem_ctx, token_blob);
2407 struct tevent_req *smb_vfs_call_offload_write_send(struct vfs_handle_struct *handle,
2408 TALLOC_CTX *mem_ctx,
2409 struct tevent_context *ev,
2412 off_t transfer_offset,
2413 struct files_struct *dest_fsp,
2417 VFS_FIND(offload_write_send);
2418 return handle->fns->offload_write_send_fn(handle, mem_ctx, ev, fsctl,
2419 token, transfer_offset,
2420 dest_fsp, dest_off, num);
2423 NTSTATUS smb_vfs_call_offload_write_recv(struct vfs_handle_struct *handle,
2424 struct tevent_req *req,
2427 VFS_FIND(offload_write_recv);
2428 return handle->fns->offload_write_recv_fn(handle, req, copied);
2431 struct smb_vfs_call_get_dos_attributes_state {
2432 files_struct *dir_fsp;
2433 NTSTATUS (*recv_fn)(struct tevent_req *req,
2434 struct vfs_aio_state *aio_state,
2436 struct vfs_aio_state aio_state;
2437 uint32_t dos_attributes;
2440 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq);
2442 struct tevent_req *smb_vfs_call_get_dos_attributes_send(
2443 TALLOC_CTX *mem_ctx,
2444 struct tevent_context *ev,
2445 struct vfs_handle_struct *handle,
2446 files_struct *dir_fsp,
2447 struct smb_filename *smb_fname)
2449 struct tevent_req *req = NULL;
2450 struct smb_vfs_call_get_dos_attributes_state *state = NULL;
2451 struct tevent_req *subreq = NULL;
2453 req = tevent_req_create(mem_ctx, &state,
2454 struct smb_vfs_call_get_dos_attributes_state);
2459 VFS_FIND(get_dos_attributes_send);
2461 *state = (struct smb_vfs_call_get_dos_attributes_state) {
2463 .recv_fn = handle->fns->get_dos_attributes_recv_fn,
2466 subreq = handle->fns->get_dos_attributes_send_fn(mem_ctx,
2471 if (tevent_req_nomem(subreq, req)) {
2472 return tevent_req_post(req, ev);
2474 tevent_req_defer_callback(req, ev);
2476 tevent_req_set_callback(subreq,
2477 smb_vfs_call_get_dos_attributes_done,
2483 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq)
2485 struct tevent_req *req =
2486 tevent_req_callback_data(subreq,
2488 struct smb_vfs_call_get_dos_attributes_state *state =
2489 tevent_req_data(req,
2490 struct smb_vfs_call_get_dos_attributes_state);
2495 * Make sure we run as the user again
2497 ok = change_to_user_by_fsp(state->dir_fsp);
2500 status = state->recv_fn(subreq,
2502 &state->dos_attributes);
2503 TALLOC_FREE(subreq);
2504 if (tevent_req_nterror(req, status)) {
2508 tevent_req_done(req);
2511 NTSTATUS smb_vfs_call_get_dos_attributes_recv(
2512 struct tevent_req *req,
2513 struct vfs_aio_state *aio_state,
2514 uint32_t *dos_attributes)
2516 struct smb_vfs_call_get_dos_attributes_state *state =
2517 tevent_req_data(req,
2518 struct smb_vfs_call_get_dos_attributes_state);
2521 if (tevent_req_is_nterror(req, &status)) {
2522 tevent_req_received(req);
2526 *aio_state = state->aio_state;
2527 *dos_attributes = state->dos_attributes;
2528 tevent_req_received(req);
2529 return NT_STATUS_OK;
2532 NTSTATUS smb_vfs_call_get_compression(vfs_handle_struct *handle,
2533 TALLOC_CTX *mem_ctx,
2534 struct files_struct *fsp,
2535 struct smb_filename *smb_fname,
2536 uint16_t *_compression_fmt)
2538 VFS_FIND(get_compression);
2539 return handle->fns->get_compression_fn(handle, mem_ctx, fsp, smb_fname,
2543 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2544 TALLOC_CTX *mem_ctx,
2545 struct files_struct *fsp,
2546 uint16_t compression_fmt)
2548 VFS_FIND(set_compression);
2549 return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2553 NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
2554 TALLOC_CTX *mem_ctx,
2555 const char *service_path,
2558 VFS_FIND(snap_check_path);
2559 return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path,
2563 NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle,
2564 TALLOC_CTX *mem_ctx,
2565 const char *base_volume,
2571 VFS_FIND(snap_create);
2572 return handle->fns->snap_create_fn(handle, mem_ctx, base_volume, tstamp,
2573 rw, base_path, snap_path);
2576 NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle,
2577 TALLOC_CTX *mem_ctx,
2581 VFS_FIND(snap_delete);
2582 return handle->fns->snap_delete_fn(handle, mem_ctx, base_path,
2586 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2587 struct files_struct *fsp,
2588 uint32_t security_info,
2589 TALLOC_CTX *mem_ctx,
2590 struct security_descriptor **ppdesc)
2592 VFS_FIND(fget_nt_acl);
2593 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2597 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2598 const struct smb_filename *smb_fname,
2599 uint32_t security_info,
2600 TALLOC_CTX *mem_ctx,
2601 struct security_descriptor **ppdesc)
2603 VFS_FIND(get_nt_acl);
2604 return handle->fns->get_nt_acl_fn(handle,
2611 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2612 struct files_struct *fsp,
2613 uint32_t security_info_sent,
2614 const struct security_descriptor *psd)
2616 VFS_FIND(fset_nt_acl);
2617 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2621 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2622 struct smb_filename *file,
2623 struct security_acl *sacl,
2624 uint32_t access_requested,
2625 uint32_t access_denied)
2627 VFS_FIND(audit_file);
2628 return handle->fns->audit_file_fn(handle,
2635 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2636 const struct smb_filename *smb_fname,
2637 SMB_ACL_TYPE_T type,
2638 TALLOC_CTX *mem_ctx)
2640 VFS_FIND(sys_acl_get_file);
2641 return handle->fns->sys_acl_get_file_fn(handle, smb_fname, type, mem_ctx);
2644 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2645 struct files_struct *fsp,
2646 TALLOC_CTX *mem_ctx)
2648 VFS_FIND(sys_acl_get_fd);
2649 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2652 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2653 const struct smb_filename *smb_fname,
2654 TALLOC_CTX *mem_ctx,
2655 char **blob_description,
2658 VFS_FIND(sys_acl_blob_get_file);
2659 return handle->fns->sys_acl_blob_get_file_fn(handle, smb_fname,
2660 mem_ctx, blob_description, blob);
2663 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2664 struct files_struct *fsp,
2665 TALLOC_CTX *mem_ctx,
2666 char **blob_description,
2669 VFS_FIND(sys_acl_blob_get_fd);
2670 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2673 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2674 const struct smb_filename *smb_fname,
2675 SMB_ACL_TYPE_T acltype,
2678 VFS_FIND(sys_acl_set_file);
2679 return handle->fns->sys_acl_set_file_fn(handle, smb_fname,
2683 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2684 struct files_struct *fsp, SMB_ACL_T theacl)
2686 VFS_FIND(sys_acl_set_fd);
2687 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2690 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2691 const struct smb_filename *smb_fname)
2693 VFS_FIND(sys_acl_delete_def_file);
2694 return handle->fns->sys_acl_delete_def_file_fn(handle, smb_fname);
2697 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2698 const struct smb_filename *smb_fname,
2704 return handle->fns->getxattr_fn(handle, smb_fname, name, value, size);
2708 struct smb_vfs_call_getxattrat_state {
2709 files_struct *dir_fsp;
2710 ssize_t (*recv_fn)(struct tevent_req *req,
2711 struct vfs_aio_state *aio_state,
2712 TALLOC_CTX *mem_ctx,
2713 uint8_t **xattr_value);
2715 uint8_t *xattr_value;
2716 struct vfs_aio_state aio_state;
2719 static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq);
2721 struct tevent_req *smb_vfs_call_getxattrat_send(
2722 TALLOC_CTX *mem_ctx,
2723 struct tevent_context *ev,
2724 struct vfs_handle_struct *handle,
2725 files_struct *dir_fsp,
2726 const struct smb_filename *smb_fname,
2727 const char *xattr_name,
2730 struct tevent_req *req = NULL;
2731 struct smb_vfs_call_getxattrat_state *state = NULL;
2732 struct tevent_req *subreq = NULL;
2734 req = tevent_req_create(mem_ctx, &state,
2735 struct smb_vfs_call_getxattrat_state);
2740 VFS_FIND(getxattrat_send);
2742 *state = (struct smb_vfs_call_getxattrat_state) {
2744 .recv_fn = handle->fns->getxattrat_recv_fn,
2747 subreq = handle->fns->getxattrat_send_fn(mem_ctx,
2754 if (tevent_req_nomem(subreq, req)) {
2755 return tevent_req_post(req, ev);
2757 tevent_req_defer_callback(req, ev);
2759 tevent_req_set_callback(subreq, smb_vfs_call_getxattrat_done, req);
2763 static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq)
2765 struct tevent_req *req = tevent_req_callback_data(
2766 subreq, struct tevent_req);
2767 struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2768 req, struct smb_vfs_call_getxattrat_state);
2772 * Make sure we run as the user again
2774 ok = change_to_user_by_fsp(state->dir_fsp);
2777 state->retval = state->recv_fn(subreq,
2780 &state->xattr_value);
2781 TALLOC_FREE(subreq);
2782 if (state->retval == -1) {
2783 tevent_req_error(req, state->aio_state.error);
2787 tevent_req_done(req);
2790 ssize_t smb_vfs_call_getxattrat_recv(struct tevent_req *req,
2791 struct vfs_aio_state *aio_state,
2792 TALLOC_CTX *mem_ctx,
2793 uint8_t **xattr_value)
2795 struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2796 req, struct smb_vfs_call_getxattrat_state);
2799 if (tevent_req_is_unix_error(req, &aio_state->error)) {
2800 tevent_req_received(req);
2804 *aio_state = state->aio_state;
2805 xattr_size = state->retval;
2806 if (xattr_value != NULL) {
2807 *xattr_value = talloc_move(mem_ctx, &state->xattr_value);
2810 tevent_req_received(req);
2814 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2815 struct files_struct *fsp, const char *name,
2816 void *value, size_t size)
2818 VFS_FIND(fgetxattr);
2819 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2822 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2823 const struct smb_filename *smb_fname,
2827 VFS_FIND(listxattr);
2828 return handle->fns->listxattr_fn(handle, smb_fname, list, size);
2831 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2832 struct files_struct *fsp, char *list,
2835 VFS_FIND(flistxattr);
2836 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2839 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2840 const struct smb_filename *smb_fname,
2843 VFS_FIND(removexattr);
2844 return handle->fns->removexattr_fn(handle, smb_fname, name);
2847 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2848 struct files_struct *fsp, const char *name)
2850 VFS_FIND(fremovexattr);
2851 return handle->fns->fremovexattr_fn(handle, fsp, name);
2854 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle,
2855 const struct smb_filename *smb_fname,
2862 return handle->fns->setxattr_fn(handle, smb_fname,
2863 name, value, size, flags);
2866 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2867 struct files_struct *fsp, const char *name,
2868 const void *value, size_t size, int flags)
2870 VFS_FIND(fsetxattr);
2871 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2874 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2875 struct files_struct *fsp)
2877 VFS_FIND(aio_force);
2878 return handle->fns->aio_force_fn(handle, fsp);
2881 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2882 struct files_struct *fsp,
2883 TALLOC_CTX *mem_ctx,
2886 VFS_FIND(durable_cookie);
2887 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2890 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2891 struct files_struct *fsp,
2892 const DATA_BLOB old_cookie,
2893 TALLOC_CTX *mem_ctx,
2894 DATA_BLOB *new_cookie)
2896 VFS_FIND(durable_disconnect);
2897 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2898 mem_ctx, new_cookie);
2901 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2902 struct smb_request *smb1req,
2903 struct smbXsrv_open *op,
2904 const DATA_BLOB old_cookie,
2905 TALLOC_CTX *mem_ctx,
2906 struct files_struct **fsp,
2907 DATA_BLOB *new_cookie)
2909 VFS_FIND(durable_reconnect);
2910 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2911 old_cookie, mem_ctx, fsp,
2915 NTSTATUS smb_vfs_call_readdir_attr(struct vfs_handle_struct *handle,
2916 const struct smb_filename *fname,
2917 TALLOC_CTX *mem_ctx,
2918 struct readdir_attr_data **attr_data)
2920 VFS_FIND(readdir_attr);
2921 return handle->fns->readdir_attr_fn(handle, fname, mem_ctx, attr_data);