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_link(struct vfs_handle_struct *handle,
2214 const struct smb_filename *old_smb_fname,
2215 const struct smb_filename *new_smb_fname)
2218 return handle->fns->link_fn(handle, old_smb_fname, new_smb_fname);
2221 int smb_vfs_call_linkat(struct vfs_handle_struct *handle,
2222 struct files_struct *srcfsp,
2223 const struct smb_filename *old_smb_fname,
2224 struct files_struct *dstfsp,
2225 const struct smb_filename *new_smb_fname,
2229 return handle->fns->linkat_fn(handle,
2237 int smb_vfs_call_mknod(struct vfs_handle_struct *handle,
2238 const struct smb_filename *smb_fname,
2243 return handle->fns->mknod_fn(handle, smb_fname, mode, dev);
2246 struct smb_filename *smb_vfs_call_realpath(struct vfs_handle_struct *handle,
2248 const struct smb_filename *smb_fname)
2251 return handle->fns->realpath_fn(handle, ctx, smb_fname);
2254 int smb_vfs_call_chflags(struct vfs_handle_struct *handle,
2255 const struct smb_filename *smb_fname,
2259 return handle->fns->chflags_fn(handle, smb_fname, flags);
2262 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2263 const SMB_STRUCT_STAT *sbuf)
2265 VFS_FIND(file_id_create);
2266 return handle->fns->file_id_create_fn(handle, sbuf);
2269 uint64_t smb_vfs_call_fs_file_id(struct vfs_handle_struct *handle,
2270 const SMB_STRUCT_STAT *sbuf)
2272 VFS_FIND(fs_file_id);
2273 return handle->fns->fs_file_id_fn(handle, sbuf);
2276 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2277 struct files_struct *fsp,
2278 const struct smb_filename *smb_fname,
2279 TALLOC_CTX *mem_ctx,
2280 unsigned int *num_streams,
2281 struct stream_struct **streams)
2283 VFS_FIND(streaminfo);
2284 return handle->fns->streaminfo_fn(handle, fsp, smb_fname, mem_ctx,
2285 num_streams, streams);
2288 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2289 const char *path, const char *name,
2290 TALLOC_CTX *mem_ctx, char **found_name)
2292 VFS_FIND(get_real_filename);
2293 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2297 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2298 const struct smb_filename *smb_fname)
2300 VFS_FIND(connectpath);
2301 return handle->fns->connectpath_fn(handle, smb_fname);
2304 bool smb_vfs_call_strict_lock_check(struct vfs_handle_struct *handle,
2305 struct files_struct *fsp,
2306 struct lock_struct *plock)
2308 VFS_FIND(strict_lock_check);
2309 return handle->fns->strict_lock_check_fn(handle, fsp, plock);
2312 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2314 enum vfs_translate_direction direction,
2315 TALLOC_CTX *mem_ctx,
2318 VFS_FIND(translate_name);
2319 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2323 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2324 struct files_struct *fsp,
2328 const uint8_t *in_data,
2331 uint32_t max_out_len,
2335 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2336 in_data, in_len, out_data, max_out_len,
2340 NTSTATUS smb_vfs_call_get_dos_attributes(struct vfs_handle_struct *handle,
2341 struct smb_filename *smb_fname,
2344 VFS_FIND(get_dos_attributes);
2345 return handle->fns->get_dos_attributes_fn(handle, smb_fname, dosmode);
2348 NTSTATUS smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct *handle,
2349 struct files_struct *fsp,
2352 VFS_FIND(fget_dos_attributes);
2353 return handle->fns->fget_dos_attributes_fn(handle, fsp, dosmode);
2356 NTSTATUS smb_vfs_call_set_dos_attributes(struct vfs_handle_struct *handle,
2357 const struct smb_filename *smb_fname,
2360 VFS_FIND(set_dos_attributes);
2361 return handle->fns->set_dos_attributes_fn(handle, smb_fname, dosmode);
2364 NTSTATUS smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct *handle,
2365 struct files_struct *fsp,
2368 VFS_FIND(set_dos_attributes);
2369 return handle->fns->fset_dos_attributes_fn(handle, fsp, dosmode);
2372 struct tevent_req *smb_vfs_call_offload_read_send(TALLOC_CTX *mem_ctx,
2373 struct tevent_context *ev,
2374 struct vfs_handle_struct *handle,
2375 struct files_struct *fsp,
2381 VFS_FIND(offload_read_send);
2382 return handle->fns->offload_read_send_fn(mem_ctx, ev, handle,
2384 ttl, offset, to_copy);
2387 NTSTATUS smb_vfs_call_offload_read_recv(struct tevent_req *req,
2388 struct vfs_handle_struct *handle,
2389 TALLOC_CTX *mem_ctx,
2390 DATA_BLOB *token_blob)
2392 VFS_FIND(offload_read_recv);
2393 return handle->fns->offload_read_recv_fn(req, handle, mem_ctx, token_blob);
2396 struct tevent_req *smb_vfs_call_offload_write_send(struct vfs_handle_struct *handle,
2397 TALLOC_CTX *mem_ctx,
2398 struct tevent_context *ev,
2401 off_t transfer_offset,
2402 struct files_struct *dest_fsp,
2406 VFS_FIND(offload_write_send);
2407 return handle->fns->offload_write_send_fn(handle, mem_ctx, ev, fsctl,
2408 token, transfer_offset,
2409 dest_fsp, dest_off, num);
2412 NTSTATUS smb_vfs_call_offload_write_recv(struct vfs_handle_struct *handle,
2413 struct tevent_req *req,
2416 VFS_FIND(offload_write_recv);
2417 return handle->fns->offload_write_recv_fn(handle, req, copied);
2420 struct smb_vfs_call_get_dos_attributes_state {
2421 files_struct *dir_fsp;
2422 NTSTATUS (*recv_fn)(struct tevent_req *req,
2423 struct vfs_aio_state *aio_state,
2425 struct vfs_aio_state aio_state;
2426 uint32_t dos_attributes;
2429 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq);
2431 struct tevent_req *smb_vfs_call_get_dos_attributes_send(
2432 TALLOC_CTX *mem_ctx,
2433 struct tevent_context *ev,
2434 struct vfs_handle_struct *handle,
2435 files_struct *dir_fsp,
2436 struct smb_filename *smb_fname)
2438 struct tevent_req *req = NULL;
2439 struct smb_vfs_call_get_dos_attributes_state *state = NULL;
2440 struct tevent_req *subreq = NULL;
2442 req = tevent_req_create(mem_ctx, &state,
2443 struct smb_vfs_call_get_dos_attributes_state);
2448 VFS_FIND(get_dos_attributes_send);
2450 *state = (struct smb_vfs_call_get_dos_attributes_state) {
2452 .recv_fn = handle->fns->get_dos_attributes_recv_fn,
2455 subreq = handle->fns->get_dos_attributes_send_fn(mem_ctx,
2460 if (tevent_req_nomem(subreq, req)) {
2461 return tevent_req_post(req, ev);
2463 tevent_req_defer_callback(req, ev);
2465 tevent_req_set_callback(subreq,
2466 smb_vfs_call_get_dos_attributes_done,
2472 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq)
2474 struct tevent_req *req =
2475 tevent_req_callback_data(subreq,
2477 struct smb_vfs_call_get_dos_attributes_state *state =
2478 tevent_req_data(req,
2479 struct smb_vfs_call_get_dos_attributes_state);
2484 * Make sure we run as the user again
2486 ok = change_to_user_by_fsp(state->dir_fsp);
2489 status = state->recv_fn(subreq,
2491 &state->dos_attributes);
2492 TALLOC_FREE(subreq);
2493 if (tevent_req_nterror(req, status)) {
2497 tevent_req_done(req);
2500 NTSTATUS smb_vfs_call_get_dos_attributes_recv(
2501 struct tevent_req *req,
2502 struct vfs_aio_state *aio_state,
2503 uint32_t *dos_attributes)
2505 struct smb_vfs_call_get_dos_attributes_state *state =
2506 tevent_req_data(req,
2507 struct smb_vfs_call_get_dos_attributes_state);
2510 if (tevent_req_is_nterror(req, &status)) {
2511 tevent_req_received(req);
2515 *aio_state = state->aio_state;
2516 *dos_attributes = state->dos_attributes;
2517 tevent_req_received(req);
2518 return NT_STATUS_OK;
2521 NTSTATUS smb_vfs_call_get_compression(vfs_handle_struct *handle,
2522 TALLOC_CTX *mem_ctx,
2523 struct files_struct *fsp,
2524 struct smb_filename *smb_fname,
2525 uint16_t *_compression_fmt)
2527 VFS_FIND(get_compression);
2528 return handle->fns->get_compression_fn(handle, mem_ctx, fsp, smb_fname,
2532 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2533 TALLOC_CTX *mem_ctx,
2534 struct files_struct *fsp,
2535 uint16_t compression_fmt)
2537 VFS_FIND(set_compression);
2538 return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2542 NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
2543 TALLOC_CTX *mem_ctx,
2544 const char *service_path,
2547 VFS_FIND(snap_check_path);
2548 return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path,
2552 NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle,
2553 TALLOC_CTX *mem_ctx,
2554 const char *base_volume,
2560 VFS_FIND(snap_create);
2561 return handle->fns->snap_create_fn(handle, mem_ctx, base_volume, tstamp,
2562 rw, base_path, snap_path);
2565 NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle,
2566 TALLOC_CTX *mem_ctx,
2570 VFS_FIND(snap_delete);
2571 return handle->fns->snap_delete_fn(handle, mem_ctx, base_path,
2575 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2576 struct files_struct *fsp,
2577 uint32_t security_info,
2578 TALLOC_CTX *mem_ctx,
2579 struct security_descriptor **ppdesc)
2581 VFS_FIND(fget_nt_acl);
2582 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2586 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2587 const struct smb_filename *smb_fname,
2588 uint32_t security_info,
2589 TALLOC_CTX *mem_ctx,
2590 struct security_descriptor **ppdesc)
2592 VFS_FIND(get_nt_acl);
2593 return handle->fns->get_nt_acl_fn(handle,
2600 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2601 struct files_struct *fsp,
2602 uint32_t security_info_sent,
2603 const struct security_descriptor *psd)
2605 VFS_FIND(fset_nt_acl);
2606 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2610 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2611 struct smb_filename *file,
2612 struct security_acl *sacl,
2613 uint32_t access_requested,
2614 uint32_t access_denied)
2616 VFS_FIND(audit_file);
2617 return handle->fns->audit_file_fn(handle,
2624 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2625 const struct smb_filename *smb_fname,
2626 SMB_ACL_TYPE_T type,
2627 TALLOC_CTX *mem_ctx)
2629 VFS_FIND(sys_acl_get_file);
2630 return handle->fns->sys_acl_get_file_fn(handle, smb_fname, type, mem_ctx);
2633 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2634 struct files_struct *fsp,
2635 TALLOC_CTX *mem_ctx)
2637 VFS_FIND(sys_acl_get_fd);
2638 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2641 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2642 const struct smb_filename *smb_fname,
2643 TALLOC_CTX *mem_ctx,
2644 char **blob_description,
2647 VFS_FIND(sys_acl_blob_get_file);
2648 return handle->fns->sys_acl_blob_get_file_fn(handle, smb_fname,
2649 mem_ctx, blob_description, blob);
2652 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2653 struct files_struct *fsp,
2654 TALLOC_CTX *mem_ctx,
2655 char **blob_description,
2658 VFS_FIND(sys_acl_blob_get_fd);
2659 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2662 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2663 const struct smb_filename *smb_fname,
2664 SMB_ACL_TYPE_T acltype,
2667 VFS_FIND(sys_acl_set_file);
2668 return handle->fns->sys_acl_set_file_fn(handle, smb_fname,
2672 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2673 struct files_struct *fsp, SMB_ACL_T theacl)
2675 VFS_FIND(sys_acl_set_fd);
2676 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2679 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2680 const struct smb_filename *smb_fname)
2682 VFS_FIND(sys_acl_delete_def_file);
2683 return handle->fns->sys_acl_delete_def_file_fn(handle, smb_fname);
2686 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2687 const struct smb_filename *smb_fname,
2693 return handle->fns->getxattr_fn(handle, smb_fname, name, value, size);
2697 struct smb_vfs_call_getxattrat_state {
2698 files_struct *dir_fsp;
2699 ssize_t (*recv_fn)(struct tevent_req *req,
2700 struct vfs_aio_state *aio_state,
2701 TALLOC_CTX *mem_ctx,
2702 uint8_t **xattr_value);
2704 uint8_t *xattr_value;
2705 struct vfs_aio_state aio_state;
2708 static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq);
2710 struct tevent_req *smb_vfs_call_getxattrat_send(
2711 TALLOC_CTX *mem_ctx,
2712 struct tevent_context *ev,
2713 struct vfs_handle_struct *handle,
2714 files_struct *dir_fsp,
2715 const struct smb_filename *smb_fname,
2716 const char *xattr_name,
2719 struct tevent_req *req = NULL;
2720 struct smb_vfs_call_getxattrat_state *state = NULL;
2721 struct tevent_req *subreq = NULL;
2723 req = tevent_req_create(mem_ctx, &state,
2724 struct smb_vfs_call_getxattrat_state);
2729 VFS_FIND(getxattrat_send);
2731 *state = (struct smb_vfs_call_getxattrat_state) {
2733 .recv_fn = handle->fns->getxattrat_recv_fn,
2736 subreq = handle->fns->getxattrat_send_fn(mem_ctx,
2743 if (tevent_req_nomem(subreq, req)) {
2744 return tevent_req_post(req, ev);
2746 tevent_req_defer_callback(req, ev);
2748 tevent_req_set_callback(subreq, smb_vfs_call_getxattrat_done, req);
2752 static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq)
2754 struct tevent_req *req = tevent_req_callback_data(
2755 subreq, struct tevent_req);
2756 struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2757 req, struct smb_vfs_call_getxattrat_state);
2761 * Make sure we run as the user again
2763 ok = change_to_user_by_fsp(state->dir_fsp);
2766 state->retval = state->recv_fn(subreq,
2769 &state->xattr_value);
2770 TALLOC_FREE(subreq);
2771 if (state->retval == -1) {
2772 tevent_req_error(req, state->aio_state.error);
2776 tevent_req_done(req);
2779 ssize_t smb_vfs_call_getxattrat_recv(struct tevent_req *req,
2780 struct vfs_aio_state *aio_state,
2781 TALLOC_CTX *mem_ctx,
2782 uint8_t **xattr_value)
2784 struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2785 req, struct smb_vfs_call_getxattrat_state);
2788 if (tevent_req_is_unix_error(req, &aio_state->error)) {
2789 tevent_req_received(req);
2793 *aio_state = state->aio_state;
2794 xattr_size = state->retval;
2795 if (xattr_value != NULL) {
2796 *xattr_value = talloc_move(mem_ctx, &state->xattr_value);
2799 tevent_req_received(req);
2803 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2804 struct files_struct *fsp, const char *name,
2805 void *value, size_t size)
2807 VFS_FIND(fgetxattr);
2808 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2811 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2812 const struct smb_filename *smb_fname,
2816 VFS_FIND(listxattr);
2817 return handle->fns->listxattr_fn(handle, smb_fname, list, size);
2820 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2821 struct files_struct *fsp, char *list,
2824 VFS_FIND(flistxattr);
2825 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2828 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2829 const struct smb_filename *smb_fname,
2832 VFS_FIND(removexattr);
2833 return handle->fns->removexattr_fn(handle, smb_fname, name);
2836 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2837 struct files_struct *fsp, const char *name)
2839 VFS_FIND(fremovexattr);
2840 return handle->fns->fremovexattr_fn(handle, fsp, name);
2843 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle,
2844 const struct smb_filename *smb_fname,
2851 return handle->fns->setxattr_fn(handle, smb_fname,
2852 name, value, size, flags);
2855 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2856 struct files_struct *fsp, const char *name,
2857 const void *value, size_t size, int flags)
2859 VFS_FIND(fsetxattr);
2860 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2863 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2864 struct files_struct *fsp)
2866 VFS_FIND(aio_force);
2867 return handle->fns->aio_force_fn(handle, fsp);
2870 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2871 struct files_struct *fsp,
2872 TALLOC_CTX *mem_ctx,
2875 VFS_FIND(durable_cookie);
2876 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2879 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2880 struct files_struct *fsp,
2881 const DATA_BLOB old_cookie,
2882 TALLOC_CTX *mem_ctx,
2883 DATA_BLOB *new_cookie)
2885 VFS_FIND(durable_disconnect);
2886 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2887 mem_ctx, new_cookie);
2890 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2891 struct smb_request *smb1req,
2892 struct smbXsrv_open *op,
2893 const DATA_BLOB old_cookie,
2894 TALLOC_CTX *mem_ctx,
2895 struct files_struct **fsp,
2896 DATA_BLOB *new_cookie)
2898 VFS_FIND(durable_reconnect);
2899 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2900 old_cookie, mem_ctx, fsp,
2904 NTSTATUS smb_vfs_call_readdir_attr(struct vfs_handle_struct *handle,
2905 const struct smb_filename *fname,
2906 TALLOC_CTX *mem_ctx,
2907 struct readdir_attr_data **attr_data)
2909 VFS_FIND(readdir_attr);
2910 return handle->fns->readdir_attr_fn(handle, fname, mem_ctx, attr_data);