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)
1416 struct stat_ex saved_stat = fsp->fsp_name->st;
1418 if(fsp->fh->fd == -1) {
1419 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1420 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1422 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1425 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
1428 return map_nt_error_from_unix(errno);
1430 update_stat_ex_from_saved_stat(&fsp->fsp_name->st, &saved_stat);
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_mkdirat(struct vfs_handle_struct *handle,
1584 struct files_struct *dirfsp,
1585 const struct smb_filename *smb_fname,
1589 return handle->fns->mkdirat_fn(handle,
1595 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle,
1596 const struct smb_filename *smb_fname)
1599 return handle->fns->rmdir_fn(handle, smb_fname);
1602 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1606 return handle->fns->closedir_fn(handle, dir);
1609 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1610 struct smb_filename *smb_fname, struct files_struct *fsp,
1611 int flags, mode_t mode)
1614 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1617 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1618 struct smb_request *req,
1619 uint16_t root_dir_fid,
1620 struct smb_filename *smb_fname,
1621 uint32_t access_mask,
1622 uint32_t share_access,
1623 uint32_t create_disposition,
1624 uint32_t create_options,
1625 uint32_t file_attributes,
1626 uint32_t oplock_request,
1627 const struct smb2_lease *lease,
1628 uint64_t allocation_size,
1629 uint32_t private_flags,
1630 struct security_descriptor *sd,
1631 struct ea_list *ea_list,
1632 files_struct **result,
1634 const struct smb2_create_blobs *in_context_blobs,
1635 struct smb2_create_blobs *out_context_blobs)
1637 VFS_FIND(create_file);
1638 return handle->fns->create_file_fn(
1639 handle, req, root_dir_fid, smb_fname, access_mask,
1640 share_access, create_disposition, create_options,
1641 file_attributes, oplock_request, lease, allocation_size,
1642 private_flags, sd, ea_list,
1643 result, pinfo, in_context_blobs, out_context_blobs);
1646 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1647 struct files_struct *fsp)
1650 return handle->fns->close_fn(handle, fsp);
1653 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1654 struct files_struct *fsp, void *data, size_t n,
1658 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1661 struct smb_vfs_call_pread_state {
1662 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1664 struct vfs_aio_state vfs_aio_state;
1667 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1669 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1670 TALLOC_CTX *mem_ctx,
1671 struct tevent_context *ev,
1672 struct files_struct *fsp,
1674 size_t n, off_t offset)
1676 struct tevent_req *req, *subreq;
1677 struct smb_vfs_call_pread_state *state;
1679 req = tevent_req_create(mem_ctx, &state,
1680 struct smb_vfs_call_pread_state);
1684 VFS_FIND(pread_send);
1685 state->recv_fn = handle->fns->pread_recv_fn;
1687 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1689 if (tevent_req_nomem(subreq, req)) {
1690 return tevent_req_post(req, ev);
1692 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1696 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1698 struct tevent_req *req = tevent_req_callback_data(
1699 subreq, struct tevent_req);
1700 struct smb_vfs_call_pread_state *state = tevent_req_data(
1701 req, struct smb_vfs_call_pread_state);
1703 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1704 TALLOC_FREE(subreq);
1705 if (state->retval == -1) {
1706 tevent_req_error(req, state->vfs_aio_state.error);
1709 tevent_req_done(req);
1712 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req,
1713 struct vfs_aio_state *vfs_aio_state)
1715 struct smb_vfs_call_pread_state *state = tevent_req_data(
1716 req, struct smb_vfs_call_pread_state);
1719 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1720 tevent_req_received(req);
1723 *vfs_aio_state = state->vfs_aio_state;
1724 retval = state->retval;
1725 tevent_req_received(req);
1729 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1730 struct files_struct *fsp, const void *data,
1731 size_t n, off_t offset)
1734 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1737 struct smb_vfs_call_pwrite_state {
1738 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1740 struct vfs_aio_state vfs_aio_state;
1743 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1745 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1746 TALLOC_CTX *mem_ctx,
1747 struct tevent_context *ev,
1748 struct files_struct *fsp,
1750 size_t n, off_t offset)
1752 struct tevent_req *req, *subreq;
1753 struct smb_vfs_call_pwrite_state *state;
1755 req = tevent_req_create(mem_ctx, &state,
1756 struct smb_vfs_call_pwrite_state);
1760 VFS_FIND(pwrite_send);
1761 state->recv_fn = handle->fns->pwrite_recv_fn;
1763 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1765 if (tevent_req_nomem(subreq, req)) {
1766 return tevent_req_post(req, ev);
1768 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1772 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1774 struct tevent_req *req = tevent_req_callback_data(
1775 subreq, struct tevent_req);
1776 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1777 req, struct smb_vfs_call_pwrite_state);
1779 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1780 TALLOC_FREE(subreq);
1781 if (state->retval == -1) {
1782 tevent_req_error(req, state->vfs_aio_state.error);
1785 tevent_req_done(req);
1788 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req,
1789 struct vfs_aio_state *vfs_aio_state)
1791 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1792 req, struct smb_vfs_call_pwrite_state);
1795 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1796 tevent_req_received(req);
1799 *vfs_aio_state = state->vfs_aio_state;
1800 retval = state->retval;
1801 tevent_req_received(req);
1805 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1806 struct files_struct *fsp, off_t offset,
1810 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1813 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1814 files_struct *fromfsp, const DATA_BLOB *header,
1815 off_t offset, size_t count)
1818 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1822 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1823 files_struct *tofsp, off_t offset,
1827 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1830 int smb_vfs_call_renameat(struct vfs_handle_struct *handle,
1831 files_struct *srcfsp,
1832 const struct smb_filename *smb_fname_src,
1833 files_struct *dstfsp,
1834 const struct smb_filename *smb_fname_dst)
1837 return handle->fns->renameat_fn(handle,
1844 struct smb_vfs_call_fsync_state {
1845 int (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1847 struct vfs_aio_state vfs_aio_state;
1850 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1852 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1853 TALLOC_CTX *mem_ctx,
1854 struct tevent_context *ev,
1855 struct files_struct *fsp)
1857 struct tevent_req *req, *subreq;
1858 struct smb_vfs_call_fsync_state *state;
1860 req = tevent_req_create(mem_ctx, &state,
1861 struct smb_vfs_call_fsync_state);
1865 VFS_FIND(fsync_send);
1866 state->recv_fn = handle->fns->fsync_recv_fn;
1868 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1869 if (tevent_req_nomem(subreq, req)) {
1870 return tevent_req_post(req, ev);
1872 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1876 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1878 struct tevent_req *req = tevent_req_callback_data(
1879 subreq, struct tevent_req);
1880 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1881 req, struct smb_vfs_call_fsync_state);
1883 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1884 TALLOC_FREE(subreq);
1885 if (state->retval == -1) {
1886 tevent_req_error(req, state->vfs_aio_state.error);
1889 tevent_req_done(req);
1892 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state)
1894 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1895 req, struct smb_vfs_call_fsync_state);
1898 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1899 tevent_req_received(req);
1902 *vfs_aio_state = state->vfs_aio_state;
1903 retval = state->retval;
1904 tevent_req_received(req);
1909 * Synchronous version of fsync, built from backend
1910 * async VFS primitives. Uses a temporary sub-event
1911 * context (NOT NESTED).
1914 int smb_vfs_fsync_sync(files_struct *fsp)
1916 TALLOC_CTX *frame = talloc_stackframe();
1917 struct tevent_req *req = NULL;
1918 struct vfs_aio_state aio_state = { 0 };
1921 struct tevent_context *ev = samba_tevent_context_init(frame);
1927 req = SMB_VFS_FSYNC_SEND(talloc_tos(), ev, fsp);
1932 ok = tevent_req_poll(req, ev);
1937 ret = SMB_VFS_FSYNC_RECV(req, &aio_state);
1942 if (aio_state.error != 0) {
1943 errno = aio_state.error;
1948 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1949 struct smb_filename *smb_fname)
1952 return handle->fns->stat_fn(handle, smb_fname);
1955 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1956 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1959 return handle->fns->fstat_fn(handle, fsp, sbuf);
1962 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1963 struct smb_filename *smb_filename)
1966 return handle->fns->lstat_fn(handle, smb_filename);
1969 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1970 struct files_struct *fsp,
1971 const SMB_STRUCT_STAT *sbuf)
1973 VFS_FIND(get_alloc_size);
1974 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1977 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1978 const struct smb_filename *smb_fname)
1981 return handle->fns->unlink_fn(handle, smb_fname);
1984 int smb_vfs_call_chmod(struct vfs_handle_struct *handle,
1985 const struct smb_filename *smb_fname,
1989 return handle->fns->chmod_fn(handle, smb_fname, mode);
1992 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1993 struct files_struct *fsp, mode_t mode)
1996 return handle->fns->fchmod_fn(handle, fsp, mode);
1999 int smb_vfs_call_chown(struct vfs_handle_struct *handle,
2000 const struct smb_filename *smb_fname,
2005 return handle->fns->chown_fn(handle, smb_fname, uid, gid);
2008 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
2009 struct files_struct *fsp, uid_t uid, gid_t gid)
2012 return handle->fns->fchown_fn(handle, fsp, uid, gid);
2015 int smb_vfs_call_lchown(struct vfs_handle_struct *handle,
2016 const struct smb_filename *smb_fname,
2021 return handle->fns->lchown_fn(handle, smb_fname, uid, gid);
2024 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
2027 bool as_root = false;
2030 if (fsp->fh->fd != -1) {
2032 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
2034 return NT_STATUS_OK;
2036 if (ret == -1 && errno != ENOSYS) {
2037 return map_nt_error_from_unix(errno);
2041 as_root = (geteuid() == 0);
2045 * We are being asked to chown as root. Make
2046 * sure we chdir() into the path to pin it,
2047 * and always act using lchown to ensure we
2048 * don't deref any symbolic links.
2050 char *parent_dir = NULL;
2051 const char *final_component = NULL;
2052 struct smb_filename *local_smb_fname = NULL;
2053 struct smb_filename parent_dir_fname = {0};
2054 struct smb_filename *saved_dir_fname = NULL;
2056 saved_dir_fname = vfs_GetWd(talloc_tos(),fsp->conn);
2057 if (!saved_dir_fname) {
2058 status = map_nt_error_from_unix(errno);
2059 DEBUG(0,("vfs_chown_fsp: failed to get "
2060 "current working directory. Error was %s\n",
2065 if (!parent_dirname(talloc_tos(),
2066 fsp->fsp_name->base_name,
2068 &final_component)) {
2069 return NT_STATUS_NO_MEMORY;
2072 parent_dir_fname = (struct smb_filename) {
2073 .base_name = parent_dir,
2074 .flags = fsp->fsp_name->flags
2077 /* cd into the parent dir to pin it. */
2078 ret = vfs_ChDir(fsp->conn, &parent_dir_fname);
2080 return map_nt_error_from_unix(errno);
2083 local_smb_fname = synthetic_smb_fname(talloc_tos(),
2087 fsp->fsp_name->flags);
2088 if (local_smb_fname == NULL) {
2089 status = NT_STATUS_NO_MEMORY;
2093 /* Must use lstat here. */
2094 ret = SMB_VFS_LSTAT(fsp->conn, local_smb_fname);
2096 status = map_nt_error_from_unix(errno);
2100 /* Ensure it matches the fsp stat. */
2101 if (!check_same_stat(&local_smb_fname->st,
2102 &fsp->fsp_name->st)) {
2103 status = NT_STATUS_ACCESS_DENIED;
2107 ret = SMB_VFS_LCHOWN(fsp->conn,
2112 status = NT_STATUS_OK;
2114 status = map_nt_error_from_unix(errno);
2119 vfs_ChDir(fsp->conn, saved_dir_fname);
2120 TALLOC_FREE(local_smb_fname);
2121 TALLOC_FREE(saved_dir_fname);
2122 TALLOC_FREE(parent_dir);
2127 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
2128 ret = SMB_VFS_LCHOWN(fsp->conn,
2132 ret = SMB_VFS_CHOWN(fsp->conn,
2138 status = NT_STATUS_OK;
2140 status = map_nt_error_from_unix(errno);
2145 int smb_vfs_call_chdir(struct vfs_handle_struct *handle,
2146 const struct smb_filename *smb_fname)
2149 return handle->fns->chdir_fn(handle, smb_fname);
2152 struct smb_filename *smb_vfs_call_getwd(struct vfs_handle_struct *handle,
2156 return handle->fns->getwd_fn(handle, ctx);
2159 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
2160 const struct smb_filename *smb_fname,
2161 struct smb_file_time *ft)
2164 return handle->fns->ntimes_fn(handle, smb_fname, ft);
2167 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2168 struct files_struct *fsp, off_t offset)
2170 VFS_FIND(ftruncate);
2171 return handle->fns->ftruncate_fn(handle, fsp, offset);
2174 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2175 struct files_struct *fsp,
2180 VFS_FIND(fallocate);
2181 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2184 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2185 struct files_struct *fsp, uint32_t share_mode,
2186 uint32_t access_mask)
2188 VFS_FIND(kernel_flock);
2189 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2193 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2194 struct files_struct *fsp, int leasetype)
2196 VFS_FIND(linux_setlease);
2197 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2200 int smb_vfs_call_symlinkat(struct vfs_handle_struct *handle,
2201 const char *link_target,
2202 struct files_struct *dirfsp,
2203 const struct smb_filename *new_smb_fname)
2205 VFS_FIND(symlinkat);
2206 return handle->fns->symlinkat_fn(handle,
2212 int smb_vfs_call_readlinkat(struct vfs_handle_struct *handle,
2213 files_struct *dirfsp,
2214 const struct smb_filename *smb_fname,
2218 VFS_FIND(readlinkat);
2219 return handle->fns->readlinkat_fn(handle,
2226 int smb_vfs_call_linkat(struct vfs_handle_struct *handle,
2227 struct files_struct *srcfsp,
2228 const struct smb_filename *old_smb_fname,
2229 struct files_struct *dstfsp,
2230 const struct smb_filename *new_smb_fname,
2234 return handle->fns->linkat_fn(handle,
2242 int smb_vfs_call_mknodat(struct vfs_handle_struct *handle,
2243 struct files_struct *dirfsp,
2244 const struct smb_filename *smb_fname,
2249 return handle->fns->mknodat_fn(handle,
2256 struct smb_filename *smb_vfs_call_realpath(struct vfs_handle_struct *handle,
2258 const struct smb_filename *smb_fname)
2261 return handle->fns->realpath_fn(handle, ctx, smb_fname);
2264 int smb_vfs_call_chflags(struct vfs_handle_struct *handle,
2265 const struct smb_filename *smb_fname,
2269 return handle->fns->chflags_fn(handle, smb_fname, flags);
2272 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2273 const SMB_STRUCT_STAT *sbuf)
2275 VFS_FIND(file_id_create);
2276 return handle->fns->file_id_create_fn(handle, sbuf);
2279 uint64_t smb_vfs_call_fs_file_id(struct vfs_handle_struct *handle,
2280 const SMB_STRUCT_STAT *sbuf)
2282 VFS_FIND(fs_file_id);
2283 return handle->fns->fs_file_id_fn(handle, sbuf);
2286 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2287 struct files_struct *fsp,
2288 const struct smb_filename *smb_fname,
2289 TALLOC_CTX *mem_ctx,
2290 unsigned int *num_streams,
2291 struct stream_struct **streams)
2293 VFS_FIND(streaminfo);
2294 return handle->fns->streaminfo_fn(handle, fsp, smb_fname, mem_ctx,
2295 num_streams, streams);
2298 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2299 const char *path, const char *name,
2300 TALLOC_CTX *mem_ctx, char **found_name)
2302 VFS_FIND(get_real_filename);
2303 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2307 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2308 const struct smb_filename *smb_fname)
2310 VFS_FIND(connectpath);
2311 return handle->fns->connectpath_fn(handle, smb_fname);
2314 bool smb_vfs_call_strict_lock_check(struct vfs_handle_struct *handle,
2315 struct files_struct *fsp,
2316 struct lock_struct *plock)
2318 VFS_FIND(strict_lock_check);
2319 return handle->fns->strict_lock_check_fn(handle, fsp, plock);
2322 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2324 enum vfs_translate_direction direction,
2325 TALLOC_CTX *mem_ctx,
2328 VFS_FIND(translate_name);
2329 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2333 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2334 struct files_struct *fsp,
2338 const uint8_t *in_data,
2341 uint32_t max_out_len,
2345 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2346 in_data, in_len, out_data, max_out_len,
2350 NTSTATUS smb_vfs_call_get_dos_attributes(struct vfs_handle_struct *handle,
2351 struct smb_filename *smb_fname,
2354 VFS_FIND(get_dos_attributes);
2355 return handle->fns->get_dos_attributes_fn(handle, smb_fname, dosmode);
2358 NTSTATUS smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct *handle,
2359 struct files_struct *fsp,
2362 VFS_FIND(fget_dos_attributes);
2363 return handle->fns->fget_dos_attributes_fn(handle, fsp, dosmode);
2366 NTSTATUS smb_vfs_call_set_dos_attributes(struct vfs_handle_struct *handle,
2367 const struct smb_filename *smb_fname,
2370 VFS_FIND(set_dos_attributes);
2371 return handle->fns->set_dos_attributes_fn(handle, smb_fname, dosmode);
2374 NTSTATUS smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct *handle,
2375 struct files_struct *fsp,
2378 VFS_FIND(set_dos_attributes);
2379 return handle->fns->fset_dos_attributes_fn(handle, fsp, dosmode);
2382 struct tevent_req *smb_vfs_call_offload_read_send(TALLOC_CTX *mem_ctx,
2383 struct tevent_context *ev,
2384 struct vfs_handle_struct *handle,
2385 struct files_struct *fsp,
2391 VFS_FIND(offload_read_send);
2392 return handle->fns->offload_read_send_fn(mem_ctx, ev, handle,
2394 ttl, offset, to_copy);
2397 NTSTATUS smb_vfs_call_offload_read_recv(struct tevent_req *req,
2398 struct vfs_handle_struct *handle,
2399 TALLOC_CTX *mem_ctx,
2400 DATA_BLOB *token_blob)
2402 VFS_FIND(offload_read_recv);
2403 return handle->fns->offload_read_recv_fn(req, handle, mem_ctx, token_blob);
2406 struct tevent_req *smb_vfs_call_offload_write_send(struct vfs_handle_struct *handle,
2407 TALLOC_CTX *mem_ctx,
2408 struct tevent_context *ev,
2411 off_t transfer_offset,
2412 struct files_struct *dest_fsp,
2416 VFS_FIND(offload_write_send);
2417 return handle->fns->offload_write_send_fn(handle, mem_ctx, ev, fsctl,
2418 token, transfer_offset,
2419 dest_fsp, dest_off, num);
2422 NTSTATUS smb_vfs_call_offload_write_recv(struct vfs_handle_struct *handle,
2423 struct tevent_req *req,
2426 VFS_FIND(offload_write_recv);
2427 return handle->fns->offload_write_recv_fn(handle, req, copied);
2430 struct smb_vfs_call_get_dos_attributes_state {
2431 files_struct *dir_fsp;
2432 NTSTATUS (*recv_fn)(struct tevent_req *req,
2433 struct vfs_aio_state *aio_state,
2435 struct vfs_aio_state aio_state;
2436 uint32_t dos_attributes;
2439 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq);
2441 struct tevent_req *smb_vfs_call_get_dos_attributes_send(
2442 TALLOC_CTX *mem_ctx,
2443 struct tevent_context *ev,
2444 struct vfs_handle_struct *handle,
2445 files_struct *dir_fsp,
2446 struct smb_filename *smb_fname)
2448 struct tevent_req *req = NULL;
2449 struct smb_vfs_call_get_dos_attributes_state *state = NULL;
2450 struct tevent_req *subreq = NULL;
2452 req = tevent_req_create(mem_ctx, &state,
2453 struct smb_vfs_call_get_dos_attributes_state);
2458 VFS_FIND(get_dos_attributes_send);
2460 *state = (struct smb_vfs_call_get_dos_attributes_state) {
2462 .recv_fn = handle->fns->get_dos_attributes_recv_fn,
2465 subreq = handle->fns->get_dos_attributes_send_fn(mem_ctx,
2470 if (tevent_req_nomem(subreq, req)) {
2471 return tevent_req_post(req, ev);
2473 tevent_req_defer_callback(req, ev);
2475 tevent_req_set_callback(subreq,
2476 smb_vfs_call_get_dos_attributes_done,
2482 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq)
2484 struct tevent_req *req =
2485 tevent_req_callback_data(subreq,
2487 struct smb_vfs_call_get_dos_attributes_state *state =
2488 tevent_req_data(req,
2489 struct smb_vfs_call_get_dos_attributes_state);
2494 * Make sure we run as the user again
2496 ok = change_to_user_and_service_by_fsp(state->dir_fsp);
2499 status = state->recv_fn(subreq,
2501 &state->dos_attributes);
2502 TALLOC_FREE(subreq);
2503 if (tevent_req_nterror(req, status)) {
2507 tevent_req_done(req);
2510 NTSTATUS smb_vfs_call_get_dos_attributes_recv(
2511 struct tevent_req *req,
2512 struct vfs_aio_state *aio_state,
2513 uint32_t *dos_attributes)
2515 struct smb_vfs_call_get_dos_attributes_state *state =
2516 tevent_req_data(req,
2517 struct smb_vfs_call_get_dos_attributes_state);
2520 if (tevent_req_is_nterror(req, &status)) {
2521 tevent_req_received(req);
2525 *aio_state = state->aio_state;
2526 *dos_attributes = state->dos_attributes;
2527 tevent_req_received(req);
2528 return NT_STATUS_OK;
2531 NTSTATUS smb_vfs_call_get_compression(vfs_handle_struct *handle,
2532 TALLOC_CTX *mem_ctx,
2533 struct files_struct *fsp,
2534 struct smb_filename *smb_fname,
2535 uint16_t *_compression_fmt)
2537 VFS_FIND(get_compression);
2538 return handle->fns->get_compression_fn(handle, mem_ctx, fsp, smb_fname,
2542 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2543 TALLOC_CTX *mem_ctx,
2544 struct files_struct *fsp,
2545 uint16_t compression_fmt)
2547 VFS_FIND(set_compression);
2548 return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2552 NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
2553 TALLOC_CTX *mem_ctx,
2554 const char *service_path,
2557 VFS_FIND(snap_check_path);
2558 return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path,
2562 NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle,
2563 TALLOC_CTX *mem_ctx,
2564 const char *base_volume,
2570 VFS_FIND(snap_create);
2571 return handle->fns->snap_create_fn(handle, mem_ctx, base_volume, tstamp,
2572 rw, base_path, snap_path);
2575 NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle,
2576 TALLOC_CTX *mem_ctx,
2580 VFS_FIND(snap_delete);
2581 return handle->fns->snap_delete_fn(handle, mem_ctx, base_path,
2585 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2586 struct files_struct *fsp,
2587 uint32_t security_info,
2588 TALLOC_CTX *mem_ctx,
2589 struct security_descriptor **ppdesc)
2591 VFS_FIND(fget_nt_acl);
2592 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2596 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2597 const struct smb_filename *smb_fname,
2598 uint32_t security_info,
2599 TALLOC_CTX *mem_ctx,
2600 struct security_descriptor **ppdesc)
2602 VFS_FIND(get_nt_acl);
2603 return handle->fns->get_nt_acl_fn(handle,
2610 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2611 struct files_struct *fsp,
2612 uint32_t security_info_sent,
2613 const struct security_descriptor *psd)
2615 VFS_FIND(fset_nt_acl);
2616 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2620 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2621 struct smb_filename *file,
2622 struct security_acl *sacl,
2623 uint32_t access_requested,
2624 uint32_t access_denied)
2626 VFS_FIND(audit_file);
2627 return handle->fns->audit_file_fn(handle,
2634 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2635 const struct smb_filename *smb_fname,
2636 SMB_ACL_TYPE_T type,
2637 TALLOC_CTX *mem_ctx)
2639 VFS_FIND(sys_acl_get_file);
2640 return handle->fns->sys_acl_get_file_fn(handle, smb_fname, type, mem_ctx);
2643 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2644 struct files_struct *fsp,
2645 TALLOC_CTX *mem_ctx)
2647 VFS_FIND(sys_acl_get_fd);
2648 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2651 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2652 const struct smb_filename *smb_fname,
2653 TALLOC_CTX *mem_ctx,
2654 char **blob_description,
2657 VFS_FIND(sys_acl_blob_get_file);
2658 return handle->fns->sys_acl_blob_get_file_fn(handle, smb_fname,
2659 mem_ctx, blob_description, blob);
2662 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2663 struct files_struct *fsp,
2664 TALLOC_CTX *mem_ctx,
2665 char **blob_description,
2668 VFS_FIND(sys_acl_blob_get_fd);
2669 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2672 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2673 const struct smb_filename *smb_fname,
2674 SMB_ACL_TYPE_T acltype,
2677 VFS_FIND(sys_acl_set_file);
2678 return handle->fns->sys_acl_set_file_fn(handle, smb_fname,
2682 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2683 struct files_struct *fsp, SMB_ACL_T theacl)
2685 VFS_FIND(sys_acl_set_fd);
2686 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2689 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2690 const struct smb_filename *smb_fname)
2692 VFS_FIND(sys_acl_delete_def_file);
2693 return handle->fns->sys_acl_delete_def_file_fn(handle, smb_fname);
2696 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2697 const struct smb_filename *smb_fname,
2703 return handle->fns->getxattr_fn(handle, smb_fname, name, value, size);
2707 struct smb_vfs_call_getxattrat_state {
2708 files_struct *dir_fsp;
2709 ssize_t (*recv_fn)(struct tevent_req *req,
2710 struct vfs_aio_state *aio_state,
2711 TALLOC_CTX *mem_ctx,
2712 uint8_t **xattr_value);
2714 uint8_t *xattr_value;
2715 struct vfs_aio_state aio_state;
2718 static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq);
2720 struct tevent_req *smb_vfs_call_getxattrat_send(
2721 TALLOC_CTX *mem_ctx,
2722 struct tevent_context *ev,
2723 struct vfs_handle_struct *handle,
2724 files_struct *dir_fsp,
2725 const struct smb_filename *smb_fname,
2726 const char *xattr_name,
2729 struct tevent_req *req = NULL;
2730 struct smb_vfs_call_getxattrat_state *state = NULL;
2731 struct tevent_req *subreq = NULL;
2733 req = tevent_req_create(mem_ctx, &state,
2734 struct smb_vfs_call_getxattrat_state);
2739 VFS_FIND(getxattrat_send);
2741 *state = (struct smb_vfs_call_getxattrat_state) {
2743 .recv_fn = handle->fns->getxattrat_recv_fn,
2746 subreq = handle->fns->getxattrat_send_fn(mem_ctx,
2753 if (tevent_req_nomem(subreq, req)) {
2754 return tevent_req_post(req, ev);
2756 tevent_req_defer_callback(req, ev);
2758 tevent_req_set_callback(subreq, smb_vfs_call_getxattrat_done, req);
2762 static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq)
2764 struct tevent_req *req = tevent_req_callback_data(
2765 subreq, struct tevent_req);
2766 struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2767 req, struct smb_vfs_call_getxattrat_state);
2771 * Make sure we run as the user again
2773 ok = change_to_user_and_service_by_fsp(state->dir_fsp);
2776 state->retval = state->recv_fn(subreq,
2779 &state->xattr_value);
2780 TALLOC_FREE(subreq);
2781 if (state->retval == -1) {
2782 tevent_req_error(req, state->aio_state.error);
2786 tevent_req_done(req);
2789 ssize_t smb_vfs_call_getxattrat_recv(struct tevent_req *req,
2790 struct vfs_aio_state *aio_state,
2791 TALLOC_CTX *mem_ctx,
2792 uint8_t **xattr_value)
2794 struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2795 req, struct smb_vfs_call_getxattrat_state);
2798 if (tevent_req_is_unix_error(req, &aio_state->error)) {
2799 tevent_req_received(req);
2803 *aio_state = state->aio_state;
2804 xattr_size = state->retval;
2805 if (xattr_value != NULL) {
2806 *xattr_value = talloc_move(mem_ctx, &state->xattr_value);
2809 tevent_req_received(req);
2813 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2814 struct files_struct *fsp, const char *name,
2815 void *value, size_t size)
2817 VFS_FIND(fgetxattr);
2818 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2821 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2822 const struct smb_filename *smb_fname,
2826 VFS_FIND(listxattr);
2827 return handle->fns->listxattr_fn(handle, smb_fname, list, size);
2830 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2831 struct files_struct *fsp, char *list,
2834 VFS_FIND(flistxattr);
2835 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2838 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2839 const struct smb_filename *smb_fname,
2842 VFS_FIND(removexattr);
2843 return handle->fns->removexattr_fn(handle, smb_fname, name);
2846 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2847 struct files_struct *fsp, const char *name)
2849 VFS_FIND(fremovexattr);
2850 return handle->fns->fremovexattr_fn(handle, fsp, name);
2853 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle,
2854 const struct smb_filename *smb_fname,
2861 return handle->fns->setxattr_fn(handle, smb_fname,
2862 name, value, size, flags);
2865 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2866 struct files_struct *fsp, const char *name,
2867 const void *value, size_t size, int flags)
2869 VFS_FIND(fsetxattr);
2870 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2873 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2874 struct files_struct *fsp)
2876 VFS_FIND(aio_force);
2877 return handle->fns->aio_force_fn(handle, fsp);
2880 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2881 struct files_struct *fsp,
2882 TALLOC_CTX *mem_ctx,
2885 VFS_FIND(durable_cookie);
2886 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2889 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2890 struct files_struct *fsp,
2891 const DATA_BLOB old_cookie,
2892 TALLOC_CTX *mem_ctx,
2893 DATA_BLOB *new_cookie)
2895 VFS_FIND(durable_disconnect);
2896 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2897 mem_ctx, new_cookie);
2900 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2901 struct smb_request *smb1req,
2902 struct smbXsrv_open *op,
2903 const DATA_BLOB old_cookie,
2904 TALLOC_CTX *mem_ctx,
2905 struct files_struct **fsp,
2906 DATA_BLOB *new_cookie)
2908 VFS_FIND(durable_reconnect);
2909 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2910 old_cookie, mem_ctx, fsp,
2914 NTSTATUS smb_vfs_call_readdir_attr(struct vfs_handle_struct *handle,
2915 const struct smb_filename *fname,
2916 TALLOC_CTX *mem_ctx,
2917 struct readdir_attr_data **attr_data)
2919 VFS_FIND(readdir_attr);
2920 return handle->fns->readdir_attr_fn(handle, fname, mem_ctx, attr_data);