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 if (lp_widelinks(SNUM(conn))) {
370 * As the widelinks logic is now moving into a
371 * vfs_widelinks module, we need to custom load
372 * it after the default module is initialized.
373 * That way no changes to smb.conf files are
376 bool ok = vfs_init_custom(conn, "widelinks");
378 DBG_ERR("widelinks enabled and vfs_init_custom "
379 "failed for vfs_widelinks module\n");
384 vfs_objects = lp_vfs_objects(SNUM(conn));
386 /* Override VFS functions if 'vfs object' was not specified*/
387 if (!vfs_objects || !vfs_objects[0])
390 for (i=0; vfs_objects[i] ;) {
394 for (j=i-1; j >= 0; j--) {
395 if (!vfs_init_custom(conn, vfs_objects[j])) {
396 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
403 /*******************************************************************
404 Check if a file exists in the vfs.
405 ********************************************************************/
407 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
409 /* Only return OK if stat was successful and S_ISREG */
410 if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
411 S_ISREG(smb_fname->st.st_ex_mode)) {
415 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
418 ssize_t vfs_pwrite_data(struct smb_request *req,
427 if (req && req->unread_bytes) {
428 int sockfd = req->xconn->transport.sock;
429 SMB_ASSERT(req->unread_bytes == N);
430 /* VFS_RECVFILE must drain the socket
431 * before returning. */
432 req->unread_bytes = 0;
434 * Leave the socket non-blocking and
435 * use SMB_VFS_RECVFILE. If it returns
436 * EAGAIN || EWOULDBLOCK temporarily set
437 * the socket blocking and retry
441 ret = SMB_VFS_RECVFILE(sockfd,
445 if (ret == 0 || (ret == -1 &&
447 errno == EWOULDBLOCK))) {
449 /* Ensure the socket is blocking. */
450 old_flags = fcntl(sockfd, F_GETFL, 0);
451 if (set_blocking(sockfd, true) == -1) {
454 ret = SMB_VFS_RECVFILE(sockfd,
458 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
465 return (ssize_t)total;
467 /* Any other error case. */
473 return (ssize_t)total;
477 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
487 return (ssize_t)total;
489 /****************************************************************************
490 An allocate file space call using the vfs interface.
491 Allocates space for a file from a filedescriptor.
492 Returns 0 on success, -1 on failure.
493 ****************************************************************************/
495 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
498 connection_struct *conn = fsp->conn;
499 uint64_t space_avail;
500 uint64_t bsize,dfree,dsize;
504 * Actually try and commit the space on disk....
507 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
508 fsp_str_dbg(fsp), (double)len));
510 if (((off_t)len) < 0) {
511 DEBUG(0,("vfs_allocate_file_space: %s negative len "
512 "requested.\n", fsp_str_dbg(fsp)));
517 status = vfs_stat_fsp(fsp);
518 if (!NT_STATUS_IS_OK(status)) {
522 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
525 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
526 /* Shrink - use ftruncate. */
528 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
529 "size %.0f\n", fsp_str_dbg(fsp),
530 (double)fsp->fsp_name->st.st_ex_size));
532 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
534 ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len);
536 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
541 /* Grow - we need to test if we have enough space. */
543 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
545 if (lp_strict_allocate(SNUM(fsp->conn))) {
546 /* See if we have a syscall that will allocate beyond
547 end-of-file without changing EOF. */
548 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_FL_KEEP_SIZE,
554 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
557 /* We changed the allocation size on disk, but not
558 EOF - exactly as required. We're done ! */
562 if (ret == -1 && errno == ENOSPC) {
566 len -= fsp->fsp_name->st.st_ex_size;
567 len /= 1024; /* Len is now number of 1k blocks needed. */
569 get_dfree_info(conn, fsp->fsp_name, &bsize, &dfree, &dsize);
570 if (space_avail == (uint64_t)-1) {
574 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
575 "needed blocks = %.0f, space avail = %.0f\n",
576 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
577 (double)space_avail));
579 if (len > space_avail) {
587 /****************************************************************************
588 A vfs set_filelen call.
589 set the length of a file from a filedescriptor.
590 Returns 0 on success, -1 on failure.
591 ****************************************************************************/
593 int vfs_set_filelen(files_struct *fsp, off_t len)
597 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
599 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
600 fsp_str_dbg(fsp), (double)len));
601 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
602 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
603 FILE_NOTIFY_CHANGE_SIZE
604 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
605 fsp->fsp_name->base_name);
608 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
613 /****************************************************************************
614 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
615 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
616 as this is also called from the default SMB_VFS_FTRUNCATE code.
617 Always extends the file size.
618 Returns 0 on success, -1 on failure.
619 ****************************************************************************/
621 #define SPARSE_BUF_WRITE_SIZE (32*1024)
623 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
629 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
636 while (total < len) {
637 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
639 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
640 if (pwrite_ret == -1) {
641 int saved_errno = errno;
642 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
643 "%s failed with error %s\n",
644 fsp_str_dbg(fsp), strerror(saved_errno)));
654 /****************************************************************************
655 A vfs fill sparse call.
656 Writes zeros from the end of file to len, if len is greater than EOF.
657 Used only by strict_sync.
658 Returns 0 on success, -1 on failure.
659 ****************************************************************************/
661 int vfs_fill_sparse(files_struct *fsp, off_t len)
668 status = vfs_stat_fsp(fsp);
669 if (!NT_STATUS_IS_OK(status)) {
673 if (len <= fsp->fsp_name->st.st_ex_size) {
678 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
683 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
684 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
685 (double)fsp->fsp_name->st.st_ex_size, (double)len,
686 (double)(len - fsp->fsp_name->st.st_ex_size)));
688 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
690 offset = fsp->fsp_name->st.st_ex_size;
691 num_to_write = len - fsp->fsp_name->st.st_ex_size;
693 /* Only do this on non-stream file handles. */
694 if (fsp->base_fsp == NULL) {
695 /* for allocation try fallocate first. This can fail on some
696 * platforms e.g. when the filesystem doesn't support it and no
697 * emulation is being done by the libc (like on AIX with JFS1). In that
698 * case we do our own emulation. fallocate implementations can
699 * return ENOTSUP or EINVAL in cases like that. */
700 ret = SMB_VFS_FALLOCATE(fsp, 0, offset, num_to_write);
701 if (ret == -1 && errno == ENOSPC) {
707 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
708 "error %d. Falling back to slow manual allocation\n", ret));
711 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
715 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
719 /*******************************************************************************
720 Set a fd into blocking/nonblocking mode through VFS
721 *******************************************************************************/
723 int vfs_set_blocking(files_struct *fsp, bool set)
727 #define FLAG_TO_SET O_NONBLOCK
730 #define FLAG_TO_SET O_NDELAY
732 #define FLAG_TO_SET FNDELAY
735 val = SMB_VFS_FCNTL(fsp, F_GETFL, 0);
746 return SMB_VFS_FCNTL(fsp, F_SETFL, val);
750 /****************************************************************************
751 Transfer some data (n bytes) between two file_struct's.
752 ****************************************************************************/
754 static ssize_t vfs_pread_fn(void *file, void *buf, size_t len, off_t offset)
756 struct files_struct *fsp = (struct files_struct *)file;
758 return SMB_VFS_PREAD(fsp, buf, len, offset);
761 static ssize_t vfs_pwrite_fn(void *file, const void *buf, size_t len, off_t offset)
763 struct files_struct *fsp = (struct files_struct *)file;
765 return SMB_VFS_PWRITE(fsp, buf, len, offset);
768 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
770 return transfer_file_internal((void *)in, (void *)out, n,
771 vfs_pread_fn, vfs_pwrite_fn);
774 /*******************************************************************
775 A vfs_readdir wrapper which just returns the file name.
776 ********************************************************************/
778 const char *vfs_readdirname(connection_struct *conn, void *p,
779 SMB_STRUCT_STAT *sbuf, char **talloced)
781 struct dirent *ptr= NULL;
789 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
801 #ifdef HAVE_BROKEN_READDIR_NAME
802 /* using /usr/ucb/cc is BAD */
806 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
807 talloc_tos(), &translated);
808 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
812 *talloced = translated;
813 if (!NT_STATUS_IS_OK(status)) {
819 /*******************************************************************
820 A wrapper for vfs_chdir().
821 ********************************************************************/
823 int vfs_ChDir(connection_struct *conn, const struct smb_filename *smb_fname)
826 struct smb_filename *cwd = NULL;
829 LastDir = SMB_STRDUP("");
832 if (ISDOT(smb_fname->base_name)) {
836 if (*smb_fname->base_name == '/' &&
837 strcsequal(LastDir,smb_fname->base_name)) {
841 DEBUG(4,("vfs_ChDir to %s\n", smb_fname->base_name));
843 ret = SMB_VFS_CHDIR(conn, smb_fname);
849 * Always replace conn->cwd_fsp. We
850 * don't know if it's been modified by
851 * VFS modules in the stack.
855 cwd = vfs_GetWd(conn, conn);
858 * vfs_GetWd() failed.
859 * We must be able to read cwd.
860 * Return to original directory
863 int saved_errno = errno;
865 if (conn->cwd_fsp->fsp_name == NULL) {
867 * Failed on the very first chdir()+getwd()
868 * for this connection. We can't
871 smb_panic("conn->cwd getwd failed\n");
876 /* Return to the previous $cwd. */
877 ret = SMB_VFS_CHDIR(conn, conn->cwd_fsp->fsp_name);
879 smb_panic("conn->cwd getwd failed\n");
884 /* And fail the chdir(). */
888 /* vfs_GetWd() succeeded. */
889 /* Replace global cache. */
891 LastDir = SMB_STRDUP(smb_fname->base_name);
894 * (Indirect) Callers of vfs_ChDir() may still hold references to the
895 * old conn->cwd_fsp->fsp_name. Move it to talloc_tos(), that way
896 * callers can use it for the lifetime of the SMB request.
898 talloc_move(talloc_tos(), &conn->cwd_fsp->fsp_name);
900 conn->cwd_fsp->fsp_name = talloc_move(conn->cwd_fsp, &cwd);
901 conn->cwd_fsp->fh->fd = AT_FDCWD;
903 DBG_INFO("vfs_ChDir got %s\n", fsp_str_dbg(conn->cwd_fsp));
908 /*******************************************************************
909 Return the absolute current directory path - given a UNIX pathname.
910 Note that this path is returned in DOS format, not UNIX
911 format. Note this can be called with conn == NULL.
912 ********************************************************************/
914 struct smb_filename *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
916 struct smb_filename *current_dir_fname = NULL;
918 struct smb_filename *smb_fname_dot = NULL;
919 struct smb_filename *smb_fname_full = NULL;
920 struct smb_filename *result = NULL;
922 if (!lp_getwd_cache()) {
926 smb_fname_dot = synthetic_smb_fname(ctx,
931 if (smb_fname_dot == NULL) {
936 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
938 * Known to fail for root: the directory may be NFS-mounted
939 * and exported with root_squash (so has no root access).
941 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
942 "(NFS problem ?)\n", strerror(errno) ));
946 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
948 smb_fname_full = (struct smb_filename *)memcache_lookup_talloc(
951 data_blob_const(&key, sizeof(key)));
953 if (smb_fname_full == NULL) {
957 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
958 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
959 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
960 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
963 * Note: smb_fname_full is owned by smbd_memcache()
964 * so we must make a copy to return.
966 result = cp_smb_filename(ctx, smb_fname_full);
967 if (result == NULL) {
976 * We don't have the information to hand so rely on traditional
977 * methods. The very slow getcwd, which spawns a process on some
978 * systems, or the not quite so bad getwd.
981 current_dir_fname = SMB_VFS_GETWD(conn, ctx);
982 if (current_dir_fname == NULL) {
983 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
988 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
989 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
992 * smbd_memcache() will own current_dir_fname after the
993 * memcache_add_talloc call, so we must make
994 * a copy on ctx to return.
996 result = cp_smb_filename(ctx, current_dir_fname);
997 if (result == NULL) {
1002 * Ensure the memory going into the cache
1003 * doesn't have a destructor so it can be
1006 talloc_set_destructor(current_dir_fname, NULL);
1008 memcache_add_talloc(smbd_memcache(),
1010 data_blob_const(&key, sizeof(key)),
1011 ¤t_dir_fname);
1012 /* current_dir_fname is now == NULL here. */
1014 /* current_dir_fname is already allocated on ctx. */
1015 result = current_dir_fname;
1019 TALLOC_FREE(smb_fname_dot);
1021 * Don't free current_dir_fname here. It's either been moved
1022 * to the memcache or is being returned in result.
1027 /*******************************************************************
1028 Reduce a file name, removing .. elements and checking that
1029 it is below dir in the hierarchy. This uses realpath.
1030 This function must run as root, and will return names
1031 and valid stat structs that can be checked on open.
1032 ********************************************************************/
1034 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
1035 const struct smb_filename *smb_fname,
1036 struct smb_request *smbreq)
1039 TALLOC_CTX *ctx = talloc_tos();
1040 const char *conn_rootdir;
1042 char *resolved_name = NULL;
1043 struct smb_filename *resolved_fname = NULL;
1044 struct smb_filename *saved_dir_fname = NULL;
1045 struct smb_filename *smb_fname_cwd = NULL;
1047 struct smb_filename *parent_name = NULL;
1048 struct smb_filename *file_name = NULL;
1051 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
1052 smb_fname->base_name,
1053 conn->connectpath));
1056 ok = parent_smb_fname(ctx,
1061 status = NT_STATUS_NO_MEMORY;
1065 if (SMB_VFS_STAT(conn, parent_name) != 0) {
1066 status = map_nt_error_from_unix(errno);
1069 /* Remember where we were. */
1070 saved_dir_fname = vfs_GetWd(ctx, conn);
1071 if (!saved_dir_fname) {
1072 status = map_nt_error_from_unix(errno);
1076 if (vfs_ChDir(conn, parent_name) == -1) {
1077 status = map_nt_error_from_unix(errno);
1081 smb_fname_cwd = synthetic_smb_fname(talloc_tos(),
1086 if (smb_fname_cwd == NULL) {
1087 status = NT_STATUS_NO_MEMORY;
1091 /* Get the absolute path of the parent directory. */
1092 resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname_cwd);
1093 if (resolved_fname == NULL) {
1094 status = map_nt_error_from_unix(errno);
1097 resolved_name = resolved_fname->base_name;
1099 if (*resolved_name != '/') {
1100 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1101 "doesn't return absolute paths !\n"));
1102 status = NT_STATUS_OBJECT_NAME_INVALID;
1106 DBG_DEBUG("realpath [%s] -> [%s]\n",
1107 smb_fname_str_dbg(parent_name),
1110 /* Now check the stat value is the same. */
1111 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1112 status = map_nt_error_from_unix(errno);
1116 /* Ensure we're pointing at the same place. */
1117 if (!check_same_stat(&smb_fname_cwd->st, &parent_name->st)) {
1118 DBG_ERR("device/inode/uid/gid on directory %s changed. "
1119 "Denying access !\n",
1120 smb_fname_str_dbg(parent_name));
1121 status = NT_STATUS_ACCESS_DENIED;
1125 /* Ensure we're below the connect path. */
1127 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
1128 if (conn_rootdir == NULL) {
1129 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1131 status = NT_STATUS_ACCESS_DENIED;
1135 rootdir_len = strlen(conn_rootdir);
1138 * In the case of rootdir_len == 1, we know that conn_rootdir is
1139 * "/", and we also know that resolved_name starts with a slash.
1140 * So, in this corner case, resolved_name is automatically a
1141 * sub-directory of the conn_rootdir. Thus we can skip the string
1142 * comparison and the next character checks (which are even
1143 * wrong in this case).
1145 if (rootdir_len != 1) {
1148 matched = (strncmp(conn_rootdir, resolved_name,
1151 if (!matched || (resolved_name[rootdir_len] != '/' &&
1152 resolved_name[rootdir_len] != '\0')) {
1153 DBG_WARNING("%s is a symlink outside the "
1155 smb_fname_str_dbg(parent_name));
1156 DEBUGADD(1, ("conn_rootdir =%s\n", conn_rootdir));
1157 DEBUGADD(1, ("resolved_name=%s\n", resolved_name));
1158 status = NT_STATUS_ACCESS_DENIED;
1163 /* Now ensure that the last component either doesn't
1164 exist, or is *NOT* a symlink. */
1166 ret = SMB_VFS_LSTAT(conn, file_name);
1168 /* Errno must be ENOENT for this be ok. */
1169 if (errno != ENOENT) {
1170 status = map_nt_error_from_unix(errno);
1171 DBG_WARNING("LSTAT on %s failed with %s\n",
1172 smb_fname_str_dbg(file_name),
1178 if (VALID_STAT(file_name->st) &&
1179 S_ISLNK(file_name->st.st_ex_mode))
1181 DBG_WARNING("Last component %s is a symlink. Denying"
1183 smb_fname_str_dbg(file_name));
1184 status = NT_STATUS_ACCESS_DENIED;
1188 status = NT_STATUS_OK;
1192 if (saved_dir_fname != NULL) {
1193 vfs_ChDir(conn, saved_dir_fname);
1194 TALLOC_FREE(saved_dir_fname);
1196 TALLOC_FREE(resolved_fname);
1197 TALLOC_FREE(parent_name);
1201 /*******************************************************************
1202 Reduce a file name, removing .. elements and checking that
1203 it is below dir in the hierarchy. This uses realpath.
1205 If cwd_name == NULL then fname is a client given path relative
1206 to the root path of the share.
1208 If cwd_name != NULL then fname is a client given path relative
1209 to cwd_name. cwd_name is relative to the root path of the share.
1210 ********************************************************************/
1212 NTSTATUS check_reduced_name(connection_struct *conn,
1213 const struct smb_filename *cwd_fname,
1214 const struct smb_filename *smb_fname)
1216 TALLOC_CTX *ctx = talloc_tos();
1217 const char *cwd_name = cwd_fname ? cwd_fname->base_name : NULL;
1218 const char *fname = smb_fname->base_name;
1219 struct smb_filename *resolved_fname;
1220 char *resolved_name = NULL;
1221 char *new_fname = NULL;
1222 bool allow_symlinks = true;
1223 const char *conn_rootdir;
1227 DBG_DEBUG("check_reduced_name [%s] [%s]\n", fname, conn->connectpath);
1229 resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname);
1231 if (resolved_fname == NULL) {
1234 DEBUG(3,("check_reduced_name: Component not a "
1235 "directory in getting realpath for "
1237 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1240 struct smb_filename *dir_fname = NULL;
1241 struct smb_filename *last_component = NULL;
1243 /* Last component didn't exist.
1244 Remove it and try and canonicalise
1245 the directory name. */
1247 ok = parent_smb_fname(ctx,
1252 return NT_STATUS_NO_MEMORY;
1255 resolved_fname = SMB_VFS_REALPATH(conn,
1258 if (resolved_fname == NULL) {
1259 NTSTATUS status = map_nt_error_from_unix(errno);
1261 if (errno == ENOENT || errno == ENOTDIR) {
1262 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1265 DEBUG(3,("check_reduce_name: "
1266 "couldn't get realpath for "
1268 smb_fname_str_dbg(dir_fname),
1269 nt_errstr(status)));
1272 resolved_name = talloc_asprintf(ctx,
1274 resolved_fname->base_name,
1275 last_component->base_name);
1276 if (resolved_name == NULL) {
1277 return NT_STATUS_NO_MEMORY;
1282 DEBUG(3,("check_reduced_name: couldn't get "
1283 "realpath for %s\n", fname));
1284 return map_nt_error_from_unix(errno);
1287 resolved_name = resolved_fname->base_name;
1290 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1293 if (*resolved_name != '/') {
1294 DEBUG(0,("check_reduced_name: realpath doesn't return "
1295 "absolute paths !\n"));
1296 TALLOC_FREE(resolved_fname);
1297 return NT_STATUS_OBJECT_NAME_INVALID;
1300 /* Common widelinks and symlinks checks. */
1301 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
1302 if (conn_rootdir == NULL) {
1303 DBG_NOTICE("Could not get conn_rootdir\n");
1304 TALLOC_FREE(resolved_fname);
1305 return NT_STATUS_ACCESS_DENIED;
1308 rootdir_len = strlen(conn_rootdir);
1311 * In the case of rootdir_len == 1, we know that
1312 * conn_rootdir is "/", and we also know that
1313 * resolved_name starts with a slash. So, in this
1314 * corner case, resolved_name is automatically a
1315 * sub-directory of the conn_rootdir. Thus we can skip
1316 * the string comparison and the next character checks
1317 * (which are even wrong in this case).
1319 if (rootdir_len != 1) {
1322 matched = (strncmp(conn_rootdir, resolved_name,
1324 if (!matched || (resolved_name[rootdir_len] != '/' &&
1325 resolved_name[rootdir_len] != '\0')) {
1326 DBG_NOTICE("Bad access attempt: %s is a symlink "
1329 "conn_rootdir =%s\n"
1330 "resolved_name=%s\n",
1334 TALLOC_FREE(resolved_fname);
1335 return NT_STATUS_ACCESS_DENIED;
1339 /* Extra checks if all symlinks are disallowed. */
1340 allow_symlinks = lp_follow_symlinks(SNUM(conn));
1341 if (!allow_symlinks) {
1342 /* fname can't have changed in resolved_path. */
1343 const char *p = &resolved_name[rootdir_len];
1346 * UNIX filesystem semantics, names consisting
1347 * only of "." or ".." CANNOT be symlinks.
1349 if (ISDOT(fname) || ISDOTDOT(fname)) {
1354 DBG_NOTICE("logic error (%c) "
1355 "in resolved_name: %s\n",
1358 TALLOC_FREE(resolved_fname);
1359 return NT_STATUS_ACCESS_DENIED;
1365 * If cwd_name is present and not ".",
1366 * then fname is relative to that, not
1367 * the root of the share. Make sure the
1368 * path we check is the one the client
1369 * sent (cwd_name+fname).
1371 if (cwd_name != NULL && !ISDOT(cwd_name)) {
1372 new_fname = talloc_asprintf(ctx,
1376 if (new_fname == NULL) {
1377 TALLOC_FREE(resolved_fname);
1378 return NT_STATUS_NO_MEMORY;
1383 if (strcmp(fname, p)!=0) {
1384 DBG_NOTICE("Bad access "
1385 "attempt: %s is a symlink to %s\n",
1388 TALLOC_FREE(resolved_fname);
1389 TALLOC_FREE(new_fname);
1390 return NT_STATUS_ACCESS_DENIED;
1396 DBG_INFO("%s reduced to %s\n", fname, resolved_name);
1397 TALLOC_FREE(resolved_fname);
1398 TALLOC_FREE(new_fname);
1399 return NT_STATUS_OK;
1403 * XXX: This is temporary and there should be no callers of this once
1404 * smb_filename is plumbed through all path based operations.
1406 * Called when we know stream name parsing has already been done.
1408 int vfs_stat_smb_basename(struct connection_struct *conn,
1409 const struct smb_filename *smb_fname_in,
1410 SMB_STRUCT_STAT *psbuf)
1412 struct smb_filename smb_fname = {
1413 .base_name = discard_const_p(char, smb_fname_in->base_name),
1414 .flags = smb_fname_in->flags
1418 if (smb_fname.flags & SMB_FILENAME_POSIX_PATH) {
1419 ret = SMB_VFS_LSTAT(conn, &smb_fname);
1421 ret = SMB_VFS_STAT(conn, &smb_fname);
1425 *psbuf = smb_fname.st;
1431 * Ensure LSTAT is called for POSIX paths.
1434 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1437 struct stat_ex saved_stat = fsp->fsp_name->st;
1439 if(fsp->fh->fd == -1) {
1440 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1441 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1443 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1446 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
1449 return map_nt_error_from_unix(errno);
1451 update_stat_ex_from_saved_stat(&fsp->fsp_name->st, &saved_stat);
1452 return NT_STATUS_OK;
1455 void init_smb_file_time(struct smb_file_time *ft)
1457 *ft = (struct smb_file_time) {
1458 .atime = make_omit_timespec(),
1459 .ctime = make_omit_timespec(),
1460 .mtime = make_omit_timespec(),
1461 .create_time = make_omit_timespec()
1466 * Initialize num_streams and streams, then call VFS op streaminfo
1468 NTSTATUS vfs_streaminfo(connection_struct *conn,
1469 struct files_struct *fsp,
1470 const struct smb_filename *smb_fname,
1471 TALLOC_CTX *mem_ctx,
1472 unsigned int *num_streams,
1473 struct stream_struct **streams)
1477 return SMB_VFS_STREAMINFO(conn,
1486 generate a file_id from a stat structure
1488 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1490 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1493 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1494 const char *service, const char *user)
1497 return handle->fns->connect_fn(handle, service, user);
1500 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1502 VFS_FIND(disconnect);
1503 handle->fns->disconnect_fn(handle);
1506 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1507 const struct smb_filename *smb_fname,
1512 VFS_FIND(disk_free);
1513 return handle->fns->disk_free_fn(handle, smb_fname,
1514 bsize, dfree, dsize);
1517 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1518 const struct smb_filename *smb_fname,
1519 enum SMB_QUOTA_TYPE qtype,
1523 VFS_FIND(get_quota);
1524 return handle->fns->get_quota_fn(handle, smb_fname, qtype, id, qt);
1527 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1528 enum SMB_QUOTA_TYPE qtype, unid_t id,
1531 VFS_FIND(set_quota);
1532 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1535 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1536 struct files_struct *fsp,
1537 struct shadow_copy_data *shadow_copy_data,
1540 VFS_FIND(get_shadow_copy_data);
1541 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1545 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle,
1546 const struct smb_filename *smb_fname,
1547 struct vfs_statvfs_struct *statbuf)
1550 return handle->fns->statvfs_fn(handle, smb_fname, statbuf);
1553 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1554 enum timestamp_set_resolution *p_ts_res)
1556 VFS_FIND(fs_capabilities);
1557 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1560 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1561 struct dfs_GetDFSReferral *r)
1563 VFS_FIND(get_dfs_referrals);
1564 return handle->fns->get_dfs_referrals_fn(handle, r);
1567 NTSTATUS smb_vfs_call_create_dfs_pathat(struct vfs_handle_struct *handle,
1568 struct files_struct *dirfsp,
1569 const struct smb_filename *smb_fname,
1570 const struct referral *reflist,
1571 size_t referral_count)
1573 VFS_FIND(create_dfs_pathat);
1574 return handle->fns->create_dfs_pathat_fn(handle,
1581 NTSTATUS smb_vfs_call_read_dfs_pathat(struct vfs_handle_struct *handle,
1582 TALLOC_CTX *mem_ctx,
1583 struct files_struct *dirfsp,
1584 const struct smb_filename *smb_fname,
1585 struct referral **ppreflist,
1586 size_t *preferral_count)
1588 VFS_FIND(read_dfs_pathat);
1589 return handle->fns->read_dfs_pathat_fn(handle,
1597 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1598 struct files_struct *fsp,
1600 uint32_t attributes)
1602 VFS_FIND(fdopendir);
1603 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1606 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1608 SMB_STRUCT_STAT *sbuf)
1611 return handle->fns->readdir_fn(handle, dirp, sbuf);
1614 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1615 DIR *dirp, long offset)
1618 handle->fns->seekdir_fn(handle, dirp, offset);
1621 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1625 return handle->fns->telldir_fn(handle, dirp);
1628 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1631 VFS_FIND(rewind_dir);
1632 handle->fns->rewind_dir_fn(handle, dirp);
1635 int smb_vfs_call_mkdirat(struct vfs_handle_struct *handle,
1636 struct files_struct *dirfsp,
1637 const struct smb_filename *smb_fname,
1641 return handle->fns->mkdirat_fn(handle,
1647 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1651 return handle->fns->closedir_fn(handle, dir);
1654 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1655 struct smb_filename *smb_fname, struct files_struct *fsp,
1656 int flags, mode_t mode)
1659 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1662 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1663 struct smb_request *req,
1664 uint16_t root_dir_fid,
1665 struct smb_filename *smb_fname,
1666 uint32_t access_mask,
1667 uint32_t share_access,
1668 uint32_t create_disposition,
1669 uint32_t create_options,
1670 uint32_t file_attributes,
1671 uint32_t oplock_request,
1672 const struct smb2_lease *lease,
1673 uint64_t allocation_size,
1674 uint32_t private_flags,
1675 struct security_descriptor *sd,
1676 struct ea_list *ea_list,
1677 files_struct **result,
1679 const struct smb2_create_blobs *in_context_blobs,
1680 struct smb2_create_blobs *out_context_blobs)
1682 VFS_FIND(create_file);
1683 return handle->fns->create_file_fn(
1684 handle, req, root_dir_fid, smb_fname, access_mask,
1685 share_access, create_disposition, create_options,
1686 file_attributes, oplock_request, lease, allocation_size,
1687 private_flags, sd, ea_list,
1688 result, pinfo, in_context_blobs, out_context_blobs);
1691 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1692 struct files_struct *fsp)
1695 return handle->fns->close_fn(handle, fsp);
1698 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1699 struct files_struct *fsp, void *data, size_t n,
1703 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1706 struct smb_vfs_call_pread_state {
1707 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1709 struct vfs_aio_state vfs_aio_state;
1712 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1714 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1715 TALLOC_CTX *mem_ctx,
1716 struct tevent_context *ev,
1717 struct files_struct *fsp,
1719 size_t n, off_t offset)
1721 struct tevent_req *req, *subreq;
1722 struct smb_vfs_call_pread_state *state;
1724 req = tevent_req_create(mem_ctx, &state,
1725 struct smb_vfs_call_pread_state);
1729 VFS_FIND(pread_send);
1730 state->recv_fn = handle->fns->pread_recv_fn;
1732 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1734 if (tevent_req_nomem(subreq, req)) {
1735 return tevent_req_post(req, ev);
1737 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1741 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1743 struct tevent_req *req = tevent_req_callback_data(
1744 subreq, struct tevent_req);
1745 struct smb_vfs_call_pread_state *state = tevent_req_data(
1746 req, struct smb_vfs_call_pread_state);
1748 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1749 TALLOC_FREE(subreq);
1750 if (state->retval == -1) {
1751 tevent_req_error(req, state->vfs_aio_state.error);
1754 tevent_req_done(req);
1757 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req,
1758 struct vfs_aio_state *vfs_aio_state)
1760 struct smb_vfs_call_pread_state *state = tevent_req_data(
1761 req, struct smb_vfs_call_pread_state);
1764 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1765 tevent_req_received(req);
1768 *vfs_aio_state = state->vfs_aio_state;
1769 retval = state->retval;
1770 tevent_req_received(req);
1774 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1775 struct files_struct *fsp, const void *data,
1776 size_t n, off_t offset)
1779 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1782 struct smb_vfs_call_pwrite_state {
1783 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1785 struct vfs_aio_state vfs_aio_state;
1788 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1790 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1791 TALLOC_CTX *mem_ctx,
1792 struct tevent_context *ev,
1793 struct files_struct *fsp,
1795 size_t n, off_t offset)
1797 struct tevent_req *req, *subreq;
1798 struct smb_vfs_call_pwrite_state *state;
1800 req = tevent_req_create(mem_ctx, &state,
1801 struct smb_vfs_call_pwrite_state);
1805 VFS_FIND(pwrite_send);
1806 state->recv_fn = handle->fns->pwrite_recv_fn;
1808 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1810 if (tevent_req_nomem(subreq, req)) {
1811 return tevent_req_post(req, ev);
1813 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1817 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1819 struct tevent_req *req = tevent_req_callback_data(
1820 subreq, struct tevent_req);
1821 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1822 req, struct smb_vfs_call_pwrite_state);
1824 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1825 TALLOC_FREE(subreq);
1826 if (state->retval == -1) {
1827 tevent_req_error(req, state->vfs_aio_state.error);
1830 tevent_req_done(req);
1833 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req,
1834 struct vfs_aio_state *vfs_aio_state)
1836 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1837 req, struct smb_vfs_call_pwrite_state);
1840 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1841 tevent_req_received(req);
1844 *vfs_aio_state = state->vfs_aio_state;
1845 retval = state->retval;
1846 tevent_req_received(req);
1850 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1851 struct files_struct *fsp, off_t offset,
1855 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1858 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1859 files_struct *fromfsp, const DATA_BLOB *header,
1860 off_t offset, size_t count)
1863 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1867 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1868 files_struct *tofsp, off_t offset,
1872 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1875 int smb_vfs_call_renameat(struct vfs_handle_struct *handle,
1876 files_struct *srcfsp,
1877 const struct smb_filename *smb_fname_src,
1878 files_struct *dstfsp,
1879 const struct smb_filename *smb_fname_dst)
1882 return handle->fns->renameat_fn(handle,
1889 struct smb_vfs_call_fsync_state {
1890 int (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1892 struct vfs_aio_state vfs_aio_state;
1895 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1897 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1898 TALLOC_CTX *mem_ctx,
1899 struct tevent_context *ev,
1900 struct files_struct *fsp)
1902 struct tevent_req *req, *subreq;
1903 struct smb_vfs_call_fsync_state *state;
1905 req = tevent_req_create(mem_ctx, &state,
1906 struct smb_vfs_call_fsync_state);
1910 VFS_FIND(fsync_send);
1911 state->recv_fn = handle->fns->fsync_recv_fn;
1913 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1914 if (tevent_req_nomem(subreq, req)) {
1915 return tevent_req_post(req, ev);
1917 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1921 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1923 struct tevent_req *req = tevent_req_callback_data(
1924 subreq, struct tevent_req);
1925 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1926 req, struct smb_vfs_call_fsync_state);
1928 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1929 TALLOC_FREE(subreq);
1930 if (state->retval == -1) {
1931 tevent_req_error(req, state->vfs_aio_state.error);
1934 tevent_req_done(req);
1937 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state)
1939 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1940 req, struct smb_vfs_call_fsync_state);
1943 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1944 tevent_req_received(req);
1947 *vfs_aio_state = state->vfs_aio_state;
1948 retval = state->retval;
1949 tevent_req_received(req);
1954 * Synchronous version of fsync, built from backend
1955 * async VFS primitives. Uses a temporary sub-event
1956 * context (NOT NESTED).
1959 int smb_vfs_fsync_sync(files_struct *fsp)
1961 TALLOC_CTX *frame = talloc_stackframe();
1962 struct tevent_req *req = NULL;
1963 struct vfs_aio_state aio_state = { 0 };
1966 struct tevent_context *ev = samba_tevent_context_init(frame);
1972 req = SMB_VFS_FSYNC_SEND(talloc_tos(), ev, fsp);
1977 ok = tevent_req_poll(req, ev);
1982 ret = SMB_VFS_FSYNC_RECV(req, &aio_state);
1987 if (aio_state.error != 0) {
1988 errno = aio_state.error;
1993 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1994 struct smb_filename *smb_fname)
1997 return handle->fns->stat_fn(handle, smb_fname);
2000 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
2001 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
2004 return handle->fns->fstat_fn(handle, fsp, sbuf);
2007 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
2008 struct smb_filename *smb_filename)
2011 return handle->fns->lstat_fn(handle, smb_filename);
2014 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
2015 struct files_struct *fsp,
2016 const SMB_STRUCT_STAT *sbuf)
2018 VFS_FIND(get_alloc_size);
2019 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
2022 int smb_vfs_call_unlinkat(struct vfs_handle_struct *handle,
2023 struct files_struct *dirfsp,
2024 const struct smb_filename *smb_fname,
2028 return handle->fns->unlinkat_fn(handle,
2034 int smb_vfs_call_chmod(struct vfs_handle_struct *handle,
2035 const struct smb_filename *smb_fname,
2039 return handle->fns->chmod_fn(handle, smb_fname, mode);
2042 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
2043 struct files_struct *fsp, mode_t mode)
2046 return handle->fns->fchmod_fn(handle, fsp, mode);
2049 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
2050 struct files_struct *fsp, uid_t uid, gid_t gid)
2053 return handle->fns->fchown_fn(handle, fsp, uid, gid);
2056 int smb_vfs_call_lchown(struct vfs_handle_struct *handle,
2057 const struct smb_filename *smb_fname,
2062 return handle->fns->lchown_fn(handle, smb_fname, uid, gid);
2065 int smb_vfs_call_chdir(struct vfs_handle_struct *handle,
2066 const struct smb_filename *smb_fname)
2069 return handle->fns->chdir_fn(handle, smb_fname);
2072 struct smb_filename *smb_vfs_call_getwd(struct vfs_handle_struct *handle,
2076 return handle->fns->getwd_fn(handle, ctx);
2079 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
2080 const struct smb_filename *smb_fname,
2081 struct smb_file_time *ft)
2084 return handle->fns->ntimes_fn(handle, smb_fname, ft);
2087 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2088 struct files_struct *fsp, off_t offset)
2090 VFS_FIND(ftruncate);
2091 return handle->fns->ftruncate_fn(handle, fsp, offset);
2094 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2095 struct files_struct *fsp,
2100 VFS_FIND(fallocate);
2101 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2104 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2105 struct files_struct *fsp, uint32_t share_mode,
2106 uint32_t access_mask)
2108 VFS_FIND(kernel_flock);
2109 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2113 int smb_vfs_call_fcntl(struct vfs_handle_struct *handle,
2114 struct files_struct *fsp, int cmd, ...)
2121 va_start(cmd_arg, cmd);
2122 result = handle->fns->fcntl_fn(handle, fsp, cmd, cmd_arg);
2128 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2129 struct files_struct *fsp, int leasetype)
2131 VFS_FIND(linux_setlease);
2132 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2135 int smb_vfs_call_symlinkat(struct vfs_handle_struct *handle,
2136 const char *link_target,
2137 struct files_struct *dirfsp,
2138 const struct smb_filename *new_smb_fname)
2140 VFS_FIND(symlinkat);
2141 return handle->fns->symlinkat_fn(handle,
2147 int smb_vfs_call_readlinkat(struct vfs_handle_struct *handle,
2148 files_struct *dirfsp,
2149 const struct smb_filename *smb_fname,
2153 VFS_FIND(readlinkat);
2154 return handle->fns->readlinkat_fn(handle,
2161 int smb_vfs_call_linkat(struct vfs_handle_struct *handle,
2162 struct files_struct *srcfsp,
2163 const struct smb_filename *old_smb_fname,
2164 struct files_struct *dstfsp,
2165 const struct smb_filename *new_smb_fname,
2169 return handle->fns->linkat_fn(handle,
2177 int smb_vfs_call_mknodat(struct vfs_handle_struct *handle,
2178 struct files_struct *dirfsp,
2179 const struct smb_filename *smb_fname,
2184 return handle->fns->mknodat_fn(handle,
2191 struct smb_filename *smb_vfs_call_realpath(struct vfs_handle_struct *handle,
2193 const struct smb_filename *smb_fname)
2196 return handle->fns->realpath_fn(handle, ctx, smb_fname);
2199 int smb_vfs_call_chflags(struct vfs_handle_struct *handle,
2200 const struct smb_filename *smb_fname,
2204 return handle->fns->chflags_fn(handle, smb_fname, flags);
2207 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2208 const SMB_STRUCT_STAT *sbuf)
2210 VFS_FIND(file_id_create);
2211 return handle->fns->file_id_create_fn(handle, sbuf);
2214 uint64_t smb_vfs_call_fs_file_id(struct vfs_handle_struct *handle,
2215 const SMB_STRUCT_STAT *sbuf)
2217 VFS_FIND(fs_file_id);
2218 return handle->fns->fs_file_id_fn(handle, sbuf);
2221 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2222 struct files_struct *fsp,
2223 const struct smb_filename *smb_fname,
2224 TALLOC_CTX *mem_ctx,
2225 unsigned int *num_streams,
2226 struct stream_struct **streams)
2228 VFS_FIND(streaminfo);
2229 return handle->fns->streaminfo_fn(handle, fsp, smb_fname, mem_ctx,
2230 num_streams, streams);
2233 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2234 const char *path, const char *name,
2235 TALLOC_CTX *mem_ctx, char **found_name)
2237 VFS_FIND(get_real_filename);
2238 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2242 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2243 const struct smb_filename *smb_fname)
2245 VFS_FIND(connectpath);
2246 return handle->fns->connectpath_fn(handle, smb_fname);
2249 bool smb_vfs_call_strict_lock_check(struct vfs_handle_struct *handle,
2250 struct files_struct *fsp,
2251 struct lock_struct *plock)
2253 VFS_FIND(strict_lock_check);
2254 return handle->fns->strict_lock_check_fn(handle, fsp, plock);
2257 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2259 enum vfs_translate_direction direction,
2260 TALLOC_CTX *mem_ctx,
2263 VFS_FIND(translate_name);
2264 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2268 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2269 struct files_struct *fsp,
2273 const uint8_t *in_data,
2276 uint32_t max_out_len,
2280 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2281 in_data, in_len, out_data, max_out_len,
2285 NTSTATUS smb_vfs_call_get_dos_attributes(struct vfs_handle_struct *handle,
2286 struct smb_filename *smb_fname,
2289 VFS_FIND(get_dos_attributes);
2290 return handle->fns->get_dos_attributes_fn(handle, smb_fname, dosmode);
2293 NTSTATUS smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct *handle,
2294 struct files_struct *fsp,
2297 VFS_FIND(fget_dos_attributes);
2298 return handle->fns->fget_dos_attributes_fn(handle, fsp, dosmode);
2301 NTSTATUS smb_vfs_call_set_dos_attributes(struct vfs_handle_struct *handle,
2302 const struct smb_filename *smb_fname,
2305 VFS_FIND(set_dos_attributes);
2306 return handle->fns->set_dos_attributes_fn(handle, smb_fname, dosmode);
2309 NTSTATUS smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct *handle,
2310 struct files_struct *fsp,
2313 VFS_FIND(set_dos_attributes);
2314 return handle->fns->fset_dos_attributes_fn(handle, fsp, dosmode);
2317 struct tevent_req *smb_vfs_call_offload_read_send(TALLOC_CTX *mem_ctx,
2318 struct tevent_context *ev,
2319 struct vfs_handle_struct *handle,
2320 struct files_struct *fsp,
2326 VFS_FIND(offload_read_send);
2327 return handle->fns->offload_read_send_fn(mem_ctx, ev, handle,
2329 ttl, offset, to_copy);
2332 NTSTATUS smb_vfs_call_offload_read_recv(struct tevent_req *req,
2333 struct vfs_handle_struct *handle,
2334 TALLOC_CTX *mem_ctx,
2335 DATA_BLOB *token_blob)
2337 VFS_FIND(offload_read_recv);
2338 return handle->fns->offload_read_recv_fn(req, handle, mem_ctx, token_blob);
2341 struct tevent_req *smb_vfs_call_offload_write_send(struct vfs_handle_struct *handle,
2342 TALLOC_CTX *mem_ctx,
2343 struct tevent_context *ev,
2346 off_t transfer_offset,
2347 struct files_struct *dest_fsp,
2351 VFS_FIND(offload_write_send);
2352 return handle->fns->offload_write_send_fn(handle, mem_ctx, ev, fsctl,
2353 token, transfer_offset,
2354 dest_fsp, dest_off, num);
2357 NTSTATUS smb_vfs_call_offload_write_recv(struct vfs_handle_struct *handle,
2358 struct tevent_req *req,
2361 VFS_FIND(offload_write_recv);
2362 return handle->fns->offload_write_recv_fn(handle, req, copied);
2365 struct smb_vfs_call_get_dos_attributes_state {
2366 files_struct *dir_fsp;
2367 NTSTATUS (*recv_fn)(struct tevent_req *req,
2368 struct vfs_aio_state *aio_state,
2370 struct vfs_aio_state aio_state;
2371 uint32_t dos_attributes;
2374 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq);
2376 struct tevent_req *smb_vfs_call_get_dos_attributes_send(
2377 TALLOC_CTX *mem_ctx,
2378 struct tevent_context *ev,
2379 struct vfs_handle_struct *handle,
2380 files_struct *dir_fsp,
2381 struct smb_filename *smb_fname)
2383 struct tevent_req *req = NULL;
2384 struct smb_vfs_call_get_dos_attributes_state *state = NULL;
2385 struct tevent_req *subreq = NULL;
2387 req = tevent_req_create(mem_ctx, &state,
2388 struct smb_vfs_call_get_dos_attributes_state);
2393 VFS_FIND(get_dos_attributes_send);
2395 *state = (struct smb_vfs_call_get_dos_attributes_state) {
2397 .recv_fn = handle->fns->get_dos_attributes_recv_fn,
2400 subreq = handle->fns->get_dos_attributes_send_fn(mem_ctx,
2405 if (tevent_req_nomem(subreq, req)) {
2406 return tevent_req_post(req, ev);
2408 tevent_req_defer_callback(req, ev);
2410 tevent_req_set_callback(subreq,
2411 smb_vfs_call_get_dos_attributes_done,
2417 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req *subreq)
2419 struct tevent_req *req =
2420 tevent_req_callback_data(subreq,
2422 struct smb_vfs_call_get_dos_attributes_state *state =
2423 tevent_req_data(req,
2424 struct smb_vfs_call_get_dos_attributes_state);
2429 * Make sure we run as the user again
2431 ok = change_to_user_and_service_by_fsp(state->dir_fsp);
2434 status = state->recv_fn(subreq,
2436 &state->dos_attributes);
2437 TALLOC_FREE(subreq);
2438 if (tevent_req_nterror(req, status)) {
2442 tevent_req_done(req);
2445 NTSTATUS smb_vfs_call_get_dos_attributes_recv(
2446 struct tevent_req *req,
2447 struct vfs_aio_state *aio_state,
2448 uint32_t *dos_attributes)
2450 struct smb_vfs_call_get_dos_attributes_state *state =
2451 tevent_req_data(req,
2452 struct smb_vfs_call_get_dos_attributes_state);
2455 if (tevent_req_is_nterror(req, &status)) {
2456 tevent_req_received(req);
2460 *aio_state = state->aio_state;
2461 *dos_attributes = state->dos_attributes;
2462 tevent_req_received(req);
2463 return NT_STATUS_OK;
2466 NTSTATUS smb_vfs_call_get_compression(vfs_handle_struct *handle,
2467 TALLOC_CTX *mem_ctx,
2468 struct files_struct *fsp,
2469 struct smb_filename *smb_fname,
2470 uint16_t *_compression_fmt)
2472 VFS_FIND(get_compression);
2473 return handle->fns->get_compression_fn(handle, mem_ctx, fsp, smb_fname,
2477 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2478 TALLOC_CTX *mem_ctx,
2479 struct files_struct *fsp,
2480 uint16_t compression_fmt)
2482 VFS_FIND(set_compression);
2483 return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2487 NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
2488 TALLOC_CTX *mem_ctx,
2489 const char *service_path,
2492 VFS_FIND(snap_check_path);
2493 return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path,
2497 NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle,
2498 TALLOC_CTX *mem_ctx,
2499 const char *base_volume,
2505 VFS_FIND(snap_create);
2506 return handle->fns->snap_create_fn(handle, mem_ctx, base_volume, tstamp,
2507 rw, base_path, snap_path);
2510 NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle,
2511 TALLOC_CTX *mem_ctx,
2515 VFS_FIND(snap_delete);
2516 return handle->fns->snap_delete_fn(handle, mem_ctx, base_path,
2520 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2521 struct files_struct *fsp,
2522 uint32_t security_info,
2523 TALLOC_CTX *mem_ctx,
2524 struct security_descriptor **ppdesc)
2526 VFS_FIND(fget_nt_acl);
2527 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2531 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2532 const struct smb_filename *smb_fname,
2533 uint32_t security_info,
2534 TALLOC_CTX *mem_ctx,
2535 struct security_descriptor **ppdesc)
2537 VFS_FIND(get_nt_acl);
2538 return handle->fns->get_nt_acl_fn(handle,
2545 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2546 struct files_struct *fsp,
2547 uint32_t security_info_sent,
2548 const struct security_descriptor *psd)
2550 VFS_FIND(fset_nt_acl);
2551 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2555 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2556 struct smb_filename *file,
2557 struct security_acl *sacl,
2558 uint32_t access_requested,
2559 uint32_t access_denied)
2561 VFS_FIND(audit_file);
2562 return handle->fns->audit_file_fn(handle,
2569 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2570 const struct smb_filename *smb_fname,
2571 SMB_ACL_TYPE_T type,
2572 TALLOC_CTX *mem_ctx)
2574 VFS_FIND(sys_acl_get_file);
2575 return handle->fns->sys_acl_get_file_fn(handle, smb_fname, type, mem_ctx);
2578 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2579 struct files_struct *fsp,
2580 TALLOC_CTX *mem_ctx)
2582 VFS_FIND(sys_acl_get_fd);
2583 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2586 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2587 const struct smb_filename *smb_fname,
2588 TALLOC_CTX *mem_ctx,
2589 char **blob_description,
2592 VFS_FIND(sys_acl_blob_get_file);
2593 return handle->fns->sys_acl_blob_get_file_fn(handle, smb_fname,
2594 mem_ctx, blob_description, blob);
2597 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2598 struct files_struct *fsp,
2599 TALLOC_CTX *mem_ctx,
2600 char **blob_description,
2603 VFS_FIND(sys_acl_blob_get_fd);
2604 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2607 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2608 const struct smb_filename *smb_fname,
2609 SMB_ACL_TYPE_T acltype,
2612 VFS_FIND(sys_acl_set_file);
2613 return handle->fns->sys_acl_set_file_fn(handle, smb_fname,
2617 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2618 struct files_struct *fsp, SMB_ACL_T theacl)
2620 VFS_FIND(sys_acl_set_fd);
2621 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2624 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2625 const struct smb_filename *smb_fname)
2627 VFS_FIND(sys_acl_delete_def_file);
2628 return handle->fns->sys_acl_delete_def_file_fn(handle, smb_fname);
2631 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2632 const struct smb_filename *smb_fname,
2638 return handle->fns->getxattr_fn(handle, smb_fname, name, value, size);
2642 struct smb_vfs_call_getxattrat_state {
2643 files_struct *dir_fsp;
2644 ssize_t (*recv_fn)(struct tevent_req *req,
2645 struct vfs_aio_state *aio_state,
2646 TALLOC_CTX *mem_ctx,
2647 uint8_t **xattr_value);
2649 uint8_t *xattr_value;
2650 struct vfs_aio_state aio_state;
2653 static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq);
2655 struct tevent_req *smb_vfs_call_getxattrat_send(
2656 TALLOC_CTX *mem_ctx,
2657 struct tevent_context *ev,
2658 struct vfs_handle_struct *handle,
2659 files_struct *dir_fsp,
2660 const struct smb_filename *smb_fname,
2661 const char *xattr_name,
2664 struct tevent_req *req = NULL;
2665 struct smb_vfs_call_getxattrat_state *state = NULL;
2666 struct tevent_req *subreq = NULL;
2668 req = tevent_req_create(mem_ctx, &state,
2669 struct smb_vfs_call_getxattrat_state);
2674 VFS_FIND(getxattrat_send);
2676 *state = (struct smb_vfs_call_getxattrat_state) {
2678 .recv_fn = handle->fns->getxattrat_recv_fn,
2681 subreq = handle->fns->getxattrat_send_fn(mem_ctx,
2688 if (tevent_req_nomem(subreq, req)) {
2689 return tevent_req_post(req, ev);
2691 tevent_req_defer_callback(req, ev);
2693 tevent_req_set_callback(subreq, smb_vfs_call_getxattrat_done, req);
2697 static void smb_vfs_call_getxattrat_done(struct tevent_req *subreq)
2699 struct tevent_req *req = tevent_req_callback_data(
2700 subreq, struct tevent_req);
2701 struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2702 req, struct smb_vfs_call_getxattrat_state);
2706 * Make sure we run as the user again
2708 ok = change_to_user_and_service_by_fsp(state->dir_fsp);
2711 state->retval = state->recv_fn(subreq,
2714 &state->xattr_value);
2715 TALLOC_FREE(subreq);
2716 if (state->retval == -1) {
2717 tevent_req_error(req, state->aio_state.error);
2721 tevent_req_done(req);
2724 ssize_t smb_vfs_call_getxattrat_recv(struct tevent_req *req,
2725 struct vfs_aio_state *aio_state,
2726 TALLOC_CTX *mem_ctx,
2727 uint8_t **xattr_value)
2729 struct smb_vfs_call_getxattrat_state *state = tevent_req_data(
2730 req, struct smb_vfs_call_getxattrat_state);
2733 if (tevent_req_is_unix_error(req, &aio_state->error)) {
2734 tevent_req_received(req);
2738 *aio_state = state->aio_state;
2739 xattr_size = state->retval;
2740 if (xattr_value != NULL) {
2741 *xattr_value = talloc_move(mem_ctx, &state->xattr_value);
2744 tevent_req_received(req);
2748 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2749 struct files_struct *fsp, const char *name,
2750 void *value, size_t size)
2752 VFS_FIND(fgetxattr);
2753 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2756 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2757 const struct smb_filename *smb_fname,
2761 VFS_FIND(listxattr);
2762 return handle->fns->listxattr_fn(handle, smb_fname, list, size);
2765 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2766 struct files_struct *fsp, char *list,
2769 VFS_FIND(flistxattr);
2770 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2773 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2774 const struct smb_filename *smb_fname,
2777 VFS_FIND(removexattr);
2778 return handle->fns->removexattr_fn(handle, smb_fname, name);
2781 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2782 struct files_struct *fsp, const char *name)
2784 VFS_FIND(fremovexattr);
2785 return handle->fns->fremovexattr_fn(handle, fsp, name);
2788 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle,
2789 const struct smb_filename *smb_fname,
2796 return handle->fns->setxattr_fn(handle, smb_fname,
2797 name, value, size, flags);
2800 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2801 struct files_struct *fsp, const char *name,
2802 const void *value, size_t size, int flags)
2804 VFS_FIND(fsetxattr);
2805 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2808 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2809 struct files_struct *fsp)
2811 VFS_FIND(aio_force);
2812 return handle->fns->aio_force_fn(handle, fsp);
2815 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2816 struct files_struct *fsp,
2817 TALLOC_CTX *mem_ctx,
2820 VFS_FIND(durable_cookie);
2821 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2824 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2825 struct files_struct *fsp,
2826 const DATA_BLOB old_cookie,
2827 TALLOC_CTX *mem_ctx,
2828 DATA_BLOB *new_cookie)
2830 VFS_FIND(durable_disconnect);
2831 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2832 mem_ctx, new_cookie);
2835 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2836 struct smb_request *smb1req,
2837 struct smbXsrv_open *op,
2838 const DATA_BLOB old_cookie,
2839 TALLOC_CTX *mem_ctx,
2840 struct files_struct **fsp,
2841 DATA_BLOB *new_cookie)
2843 VFS_FIND(durable_reconnect);
2844 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2845 old_cookie, mem_ctx, fsp,
2849 NTSTATUS smb_vfs_call_readdir_attr(struct vfs_handle_struct *handle,
2850 const struct smb_filename *fname,
2851 TALLOC_CTX *mem_ctx,
2852 struct readdir_attr_data **attr_data)
2854 VFS_FIND(readdir_attr);
2855 return handle->fns->readdir_attr_fn(handle, fname, mem_ctx, attr_data);