2 Unix SMB/Netbios implementation.
4 VFS initialisation and support functions
5 Copyright (C) Tim Potter 1999
6 Copyright (C) Alexander Bokovoy 2002
7 Copyright (C) James Peach 2006
8 Copyright (C) Volker Lendecke 2009
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 This work was sponsored by Optifacio Software Services, Inc.
27 #include "system/filesys.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "../lib/util/memcache.h"
31 #include "transfer_file.h"
33 #include "lib/util/tevent_unix.h"
34 #include "lib/util/tevent_ntstatus.h"
35 #include "lib/util/sys_rw.h"
38 #define DBGC_CLASS DBGC_VFS
43 struct vfs_fsp_data
*next
;
44 struct vfs_handle_struct
*owner
;
45 void (*destroy
)(void *p_data
);
47 /* NOTE: This structure contains four pointers so that we can guarantee
48 * that the end of the structure is always both 4-byte and 8-byte aligned.
52 struct vfs_init_function_entry
{
54 struct vfs_init_function_entry
*prev
, *next
;
55 const struct vfs_fn_pointers
*fns
;
58 /****************************************************************************
59 maintain the list of available backends
60 ****************************************************************************/
62 static struct vfs_init_function_entry
*vfs_find_backend_entry(const char *name
)
64 struct vfs_init_function_entry
*entry
= backends
;
66 DEBUG(10, ("vfs_find_backend_entry called for %s\n", name
));
69 if (strcmp(entry
->name
, name
)==0) return entry
;
76 NTSTATUS
smb_register_vfs(int version
, const char *name
,
77 const struct vfs_fn_pointers
*fns
)
79 struct vfs_init_function_entry
*entry
= backends
;
81 if ((version
!= SMB_VFS_INTERFACE_VERSION
)) {
82 DEBUG(0, ("Failed to register vfs module.\n"
83 "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
84 "current SMB_VFS_INTERFACE_VERSION is %d.\n"
85 "Please recompile against the current Samba Version!\n",
86 version
, SMB_VFS_INTERFACE_VERSION
));
87 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
90 if (!name
|| !name
[0]) {
91 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
92 return NT_STATUS_INVALID_PARAMETER
;
95 if (vfs_find_backend_entry(name
)) {
96 DEBUG(0,("VFS module %s already loaded!\n", name
));
97 return NT_STATUS_OBJECT_NAME_COLLISION
;
100 entry
= SMB_XMALLOC_P(struct vfs_init_function_entry
);
101 entry
->name
= smb_xstrdup(name
);
104 DLIST_ADD(backends
, entry
);
105 DEBUG(5, ("Successfully added vfs backend '%s'\n", name
));
109 /****************************************************************************
110 initialise default vfs hooks
111 ****************************************************************************/
113 static void vfs_init_default(connection_struct
*conn
)
115 DEBUG(3, ("Initialising default vfs hooks\n"));
116 vfs_init_custom(conn
, DEFAULT_VFS_MODULE_NAME
);
119 /****************************************************************************
120 initialise custom vfs hooks
121 ****************************************************************************/
123 bool vfs_init_custom(connection_struct
*conn
, const char *vfs_object
)
125 char *module_path
= NULL
;
126 char *module_name
= NULL
;
127 char *module_param
= NULL
, *p
;
128 vfs_handle_struct
*handle
;
129 const struct vfs_init_function_entry
*entry
;
131 if (!conn
||!vfs_object
||!vfs_object
[0]) {
132 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
133 "empty vfs_object!\n"));
138 static_init_vfs(NULL
);
141 DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object
));
143 module_path
= smb_xstrdup(vfs_object
);
145 p
= strchr_m(module_path
, ':');
150 trim_char(module_param
, ' ', ' ');
153 trim_char(module_path
, ' ', ' ');
155 module_name
= smb_xstrdup(module_path
);
157 if ((module_name
[0] == '/') &&
158 (strcmp(module_path
, DEFAULT_VFS_MODULE_NAME
) != 0)) {
161 * Extract the module name from the path. Just use the base
162 * name of the last path component.
165 SAFE_FREE(module_name
);
166 module_name
= smb_xstrdup(strrchr_m(module_path
, '/')+1);
168 p
= strchr_m(module_name
, '.');
175 /* First, try to load the module with the new module system */
176 entry
= vfs_find_backend_entry(module_name
);
180 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
183 status
= smb_load_module("vfs", module_path
);
184 if (!NT_STATUS_IS_OK(status
)) {
185 DEBUG(0, ("error probing vfs module '%s': %s\n",
186 module_path
, nt_errstr(status
)));
190 entry
= vfs_find_backend_entry(module_name
);
192 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object
));
197 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object
));
199 handle
= talloc_zero(conn
, vfs_handle_struct
);
201 DEBUG(0,("TALLOC_ZERO() failed!\n"));
205 handle
->fns
= entry
->fns
;
207 handle
->param
= talloc_strdup(conn
, module_param
);
209 DLIST_ADD(conn
->vfs_handles
, handle
);
211 SAFE_FREE(module_path
);
212 SAFE_FREE(module_name
);
216 SAFE_FREE(module_path
);
217 SAFE_FREE(module_name
);
221 /*****************************************************************
222 Allow VFS modules to extend files_struct with VFS-specific state.
223 This will be ok for small numbers of extensions, but might need to
224 be refactored if it becomes more widely used.
225 ******************************************************************/
227 #define EXT_DATA_AREA(e) ((uint8_t *)(e) + sizeof(struct vfs_fsp_data))
229 void *vfs_add_fsp_extension_notype(vfs_handle_struct
*handle
,
230 files_struct
*fsp
, size_t ext_size
,
231 void (*destroy_fn
)(void *p_data
))
233 struct vfs_fsp_data
*ext
;
236 /* Prevent VFS modules adding multiple extensions. */
237 if ((ext_data
= vfs_fetch_fsp_extension(handle
, fsp
))) {
241 ext
= talloc_zero_size(
242 handle
->conn
, sizeof(struct vfs_fsp_data
) + ext_size
);
248 ext
->next
= fsp
->vfs_extension
;
249 ext
->destroy
= destroy_fn
;
250 fsp
->vfs_extension
= ext
;
251 return EXT_DATA_AREA(ext
);
254 void vfs_remove_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
256 struct vfs_fsp_data
*curr
;
257 struct vfs_fsp_data
*prev
;
259 for (curr
= fsp
->vfs_extension
, prev
= NULL
;
261 prev
= curr
, curr
= curr
->next
) {
262 if (curr
->owner
== handle
) {
264 prev
->next
= curr
->next
;
266 fsp
->vfs_extension
= curr
->next
;
269 curr
->destroy(EXT_DATA_AREA(curr
));
277 void vfs_remove_all_fsp_extensions(files_struct
*fsp
)
279 struct vfs_fsp_data
*curr
;
280 struct vfs_fsp_data
*next
;
282 for (curr
= fsp
->vfs_extension
; curr
; curr
= next
) {
285 fsp
->vfs_extension
= next
;
288 curr
->destroy(EXT_DATA_AREA(curr
));
294 void *vfs_memctx_fsp_extension(vfs_handle_struct
*handle
,
295 const struct files_struct
*fsp
)
297 struct vfs_fsp_data
*head
;
299 for (head
= fsp
->vfs_extension
; head
; head
= head
->next
) {
300 if (head
->owner
== handle
) {
308 void *vfs_fetch_fsp_extension(vfs_handle_struct
*handle
,
309 const struct files_struct
*fsp
)
311 struct vfs_fsp_data
*head
;
313 head
= (struct vfs_fsp_data
*)vfs_memctx_fsp_extension(handle
, fsp
);
315 return EXT_DATA_AREA(head
);
324 * Ensure this module catches all VFS functions.
327 void smb_vfs_assert_all_fns(const struct vfs_fn_pointers
* fns
,
330 bool missing_fn
= false;
332 const uintptr_t *end
= (const uintptr_t *)(fns
+ 1);
334 for (idx
= 0; ((const uintptr_t *)fns
+ idx
) < end
; idx
++) {
335 if (*((const uintptr_t *)fns
+ idx
) == 0) {
336 DBG_ERR("VFS function at index %d not implemented "
337 "in module %s\n", idx
, module
);
343 smb_panic("Required VFS function not implemented in module.\n");
347 void smb_vfs_assert_all_fns(const struct vfs_fn_pointers
* fns
,
353 /*****************************************************************
355 ******************************************************************/
357 bool smbd_vfs_init(connection_struct
*conn
)
359 const char **vfs_objects
;
363 /* Normal share - initialise with disk access functions */
364 vfs_init_default(conn
);
366 /* No need to load vfs modules for printer connections */
371 if (lp_widelinks(SNUM(conn
))) {
373 * As the widelinks logic is now moving into a
374 * vfs_widelinks module, we need to custom load
375 * it after the default module is initialized.
376 * That way no changes to smb.conf files are
379 bool ok
= vfs_init_custom(conn
, "widelinks");
381 DBG_ERR("widelinks enabled and vfs_init_custom "
382 "failed for vfs_widelinks module\n");
387 vfs_objects
= lp_vfs_objects(SNUM(conn
));
389 /* Override VFS functions if 'vfs object' was not specified*/
390 if (!vfs_objects
|| !vfs_objects
[0])
393 for (i
=0; vfs_objects
[i
] ;) {
397 for (j
=i
-1; j
>= 0; j
--) {
398 if (!vfs_init_custom(conn
, vfs_objects
[j
])) {
399 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects
[j
]));
406 /*******************************************************************
407 Check if a file exists in the vfs.
408 ********************************************************************/
410 NTSTATUS
vfs_file_exist(connection_struct
*conn
, struct smb_filename
*smb_fname
)
412 /* Only return OK if stat was successful and S_ISREG */
413 if ((SMB_VFS_STAT(conn
, smb_fname
) != -1) &&
414 S_ISREG(smb_fname
->st
.st_ex_mode
)) {
418 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
421 bool vfs_valid_pread_range(off_t offset
, size_t length
)
423 return sys_valid_io_range(offset
, length
);
426 bool vfs_valid_pwrite_range(off_t offset
, size_t length
)
429 * See MAXFILESIZE in [MS-FSA] 2.1.5.3 Server Requests a Write
431 static const uint64_t maxfilesize
= 0xfffffff0000;
432 uint64_t last_byte_ofs
;
435 ok
= sys_valid_io_range(offset
, length
);
444 last_byte_ofs
= offset
+ length
;
445 if (last_byte_ofs
> maxfilesize
) {
452 ssize_t
vfs_pwrite_data(struct smb_request
*req
,
462 ok
= vfs_valid_pwrite_range(offset
, N
);
468 if (req
&& req
->unread_bytes
) {
469 int sockfd
= req
->xconn
->transport
.sock
;
470 SMB_ASSERT(req
->unread_bytes
== N
);
471 /* VFS_RECVFILE must drain the socket
472 * before returning. */
473 req
->unread_bytes
= 0;
475 * Leave the socket non-blocking and
476 * use SMB_VFS_RECVFILE. If it returns
477 * EAGAIN || EWOULDBLOCK temporarily set
478 * the socket blocking and retry
482 ret
= SMB_VFS_RECVFILE(sockfd
,
486 if (ret
== 0 || (ret
== -1 &&
488 errno
== EWOULDBLOCK
))) {
490 /* Ensure the socket is blocking. */
491 old_flags
= fcntl(sockfd
, F_GETFL
, 0);
492 if (set_blocking(sockfd
, true) == -1) {
495 ret
= SMB_VFS_RECVFILE(sockfd
,
499 if (fcntl(sockfd
, F_SETFL
, old_flags
) == -1) {
506 return (ssize_t
)total
;
508 /* Any other error case. */
514 return (ssize_t
)total
;
518 ret
= SMB_VFS_PWRITE(fsp
, buffer
+ total
, N
- total
,
528 return (ssize_t
)total
;
530 /****************************************************************************
531 An allocate file space call using the vfs interface.
532 Allocates space for a file from a filedescriptor.
533 Returns 0 on success, -1 on failure.
534 ****************************************************************************/
536 int vfs_allocate_file_space(files_struct
*fsp
, uint64_t len
)
539 connection_struct
*conn
= fsp
->conn
;
540 uint64_t space_avail
;
541 uint64_t bsize
,dfree
,dsize
;
546 * Actually try and commit the space on disk....
549 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
550 fsp_str_dbg(fsp
), (double)len
));
552 ok
= vfs_valid_pwrite_range((off_t
)len
, 0);
554 DEBUG(0,("vfs_allocate_file_space: %s negative/invalid len "
555 "requested.\n", fsp_str_dbg(fsp
)));
560 status
= vfs_stat_fsp(fsp
);
561 if (!NT_STATUS_IS_OK(status
)) {
565 if (len
== (uint64_t)fsp
->fsp_name
->st
.st_ex_size
)
568 if (len
< (uint64_t)fsp
->fsp_name
->st
.st_ex_size
) {
569 /* Shrink - use ftruncate. */
571 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
572 "size %.0f\n", fsp_str_dbg(fsp
),
573 (double)fsp
->fsp_name
->st
.st_ex_size
));
575 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_ALLOC_SHRINK
);
577 ret
= SMB_VFS_FTRUNCATE(fsp
, (off_t
)len
);
579 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_ALLOC_SHRINK
);
584 /* Grow - we need to test if we have enough space. */
586 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_ALLOC_GROW
);
588 if (lp_strict_allocate(SNUM(fsp
->conn
))) {
589 /* See if we have a syscall that will allocate beyond
590 end-of-file without changing EOF. */
591 ret
= SMB_VFS_FALLOCATE(fsp
, VFS_FALLOCATE_FL_KEEP_SIZE
,
597 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_ALLOC_GROW
);
600 /* We changed the allocation size on disk, but not
601 EOF - exactly as required. We're done ! */
605 if (ret
== -1 && errno
== ENOSPC
) {
609 len
-= fsp
->fsp_name
->st
.st_ex_size
;
610 len
/= 1024; /* Len is now number of 1k blocks needed. */
612 get_dfree_info(conn
, fsp
->fsp_name
, &bsize
, &dfree
, &dsize
);
613 if (space_avail
== (uint64_t)-1) {
617 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
618 "needed blocks = %.0f, space avail = %.0f\n",
619 fsp_str_dbg(fsp
), (double)fsp
->fsp_name
->st
.st_ex_size
, (double)len
,
620 (double)space_avail
));
622 if (len
> space_avail
) {
630 /****************************************************************************
631 A vfs set_filelen call.
632 set the length of a file from a filedescriptor.
633 Returns 0 on success, -1 on failure.
634 ****************************************************************************/
636 int vfs_set_filelen(files_struct
*fsp
, off_t len
)
641 ok
= vfs_valid_pwrite_range(len
, 0);
647 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_SET_FILE_LEN
);
649 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
650 fsp_str_dbg(fsp
), (double)len
));
651 if ((ret
= SMB_VFS_FTRUNCATE(fsp
, len
)) != -1) {
652 notify_fname(fsp
->conn
, NOTIFY_ACTION_MODIFIED
,
653 FILE_NOTIFY_CHANGE_SIZE
654 | FILE_NOTIFY_CHANGE_ATTRIBUTES
,
655 fsp
->fsp_name
->base_name
);
658 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_SET_FILE_LEN
);
663 /****************************************************************************
664 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
665 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
666 as this is also called from the default SMB_VFS_FTRUNCATE code.
667 Always extends the file size.
668 Returns 0 on success, -1 on failure.
669 ****************************************************************************/
671 #define SPARSE_BUF_WRITE_SIZE (32*1024)
673 int vfs_slow_fallocate(files_struct
*fsp
, off_t offset
, off_t len
)
679 ok
= vfs_valid_pwrite_range(offset
, len
);
686 sparse_buf
= SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE
);
693 while (total
< len
) {
694 size_t curr_write_size
= MIN(SPARSE_BUF_WRITE_SIZE
, (len
- total
));
696 pwrite_ret
= SMB_VFS_PWRITE(fsp
, sparse_buf
, curr_write_size
, offset
+ total
);
697 if (pwrite_ret
== -1) {
698 int saved_errno
= errno
;
699 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
700 "%s failed with error %s\n",
701 fsp_str_dbg(fsp
), strerror(saved_errno
)));
711 /****************************************************************************
712 A vfs fill sparse call.
713 Writes zeros from the end of file to len, if len is greater than EOF.
714 Used only by strict_sync.
715 Returns 0 on success, -1 on failure.
716 ****************************************************************************/
718 int vfs_fill_sparse(files_struct
*fsp
, off_t len
)
726 ok
= vfs_valid_pwrite_range(len
, 0);
732 status
= vfs_stat_fsp(fsp
);
733 if (!NT_STATUS_IS_OK(status
)) {
737 if (len
<= fsp
->fsp_name
->st
.st_ex_size
) {
742 if (S_ISFIFO(fsp
->fsp_name
->st
.st_ex_mode
)) {
747 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
748 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp
),
749 (double)fsp
->fsp_name
->st
.st_ex_size
, (double)len
,
750 (double)(len
- fsp
->fsp_name
->st
.st_ex_size
)));
752 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_FILL_SPARSE
);
754 offset
= fsp
->fsp_name
->st
.st_ex_size
;
755 num_to_write
= len
- fsp
->fsp_name
->st
.st_ex_size
;
757 /* Only do this on non-stream file handles. */
758 if (fsp
->base_fsp
== NULL
) {
759 /* for allocation try fallocate first. This can fail on some
760 * platforms e.g. when the filesystem doesn't support it and no
761 * emulation is being done by the libc (like on AIX with JFS1). In that
762 * case we do our own emulation. fallocate implementations can
763 * return ENOTSUP or EINVAL in cases like that. */
764 ret
= SMB_VFS_FALLOCATE(fsp
, 0, offset
, num_to_write
);
765 if (ret
== -1 && errno
== ENOSPC
) {
771 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
772 "error %d. Falling back to slow manual allocation\n", ret
));
775 ret
= vfs_slow_fallocate(fsp
, offset
, num_to_write
);
779 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_FILL_SPARSE
);
783 /*******************************************************************************
784 Set a fd into blocking/nonblocking mode through VFS
785 *******************************************************************************/
787 int vfs_set_blocking(files_struct
*fsp
, bool set
)
791 #define FLAG_TO_SET O_NONBLOCK
794 #define FLAG_TO_SET O_NDELAY
796 #define FLAG_TO_SET FNDELAY
800 if (fsp
->fsp_flags
.is_pathref
) {
804 val
= SMB_VFS_FCNTL(fsp
, F_GETFL
, 0);
815 return SMB_VFS_FCNTL(fsp
, F_SETFL
, val
);
819 /****************************************************************************
820 Transfer some data (n bytes) between two file_struct's.
821 ****************************************************************************/
823 static ssize_t
vfs_pread_fn(void *file
, void *buf
, size_t len
, off_t offset
)
825 struct files_struct
*fsp
= (struct files_struct
*)file
;
827 return SMB_VFS_PREAD(fsp
, buf
, len
, offset
);
830 static ssize_t
vfs_pwrite_fn(void *file
, const void *buf
, size_t len
, off_t offset
)
832 struct files_struct
*fsp
= (struct files_struct
*)file
;
834 return SMB_VFS_PWRITE(fsp
, buf
, len
, offset
);
837 off_t
vfs_transfer_file(files_struct
*in
, files_struct
*out
, off_t n
)
839 return transfer_file_internal((void *)in
, (void *)out
, n
,
840 vfs_pread_fn
, vfs_pwrite_fn
);
843 /*******************************************************************
844 A vfs_readdir wrapper which just returns the file name.
845 ********************************************************************/
847 const char *vfs_readdirname(connection_struct
*conn
,
848 struct files_struct
*dirfsp
,
850 SMB_STRUCT_STAT
*sbuf
,
853 struct dirent
*ptr
= NULL
;
861 ptr
= SMB_VFS_READDIR(conn
, dirfsp
, (DIR *)p
, sbuf
);
867 status
= SMB_VFS_TRANSLATE_NAME(conn
, dname
, vfs_translate_to_windows
,
868 talloc_tos(), &translated
);
869 if (NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
873 *talloced
= translated
;
874 if (!NT_STATUS_IS_OK(status
)) {
880 /*******************************************************************
881 A wrapper for vfs_chdir().
882 ********************************************************************/
884 int vfs_ChDir(connection_struct
*conn
, const struct smb_filename
*smb_fname
)
887 struct smb_filename
*cwd
= NULL
;
890 LastDir
= SMB_STRDUP("");
893 if (ISDOT(smb_fname
->base_name
)) {
895 * passing a '.' is a noop,
896 * and we only expect this after
897 * everything is initialized.
899 * So the first vfs_ChDir() on a given
900 * connection_struct must not be '.'.
902 * Note: conn_new() sets
903 * conn->cwd_fsp->fh->fd = -1
904 * and vfs_ChDir() leaves with
905 * conn->cwd_fsp->fh->fd = AT_FDCWD
908 if (fsp_get_pathref_fd(conn
->cwd_fsp
) != AT_FDCWD
) {
910 * This should never happen and
911 * we might change this to
912 * SMB_ASSERT() in future.
914 DBG_ERR("Called with '.' as first operation!\n");
922 if (smb_fname
->base_name
[0] == '/' &&
923 strcsequal(LastDir
,smb_fname
->base_name
))
926 * conn->cwd_fsp->fsp_name and the kernel
927 * are already correct, but conn->cwd_fsp->fh->fd
928 * might still be -1 as initialized in conn_new().
930 * This can happen when a client made a 2nd
931 * tree connect to a share with the same underlying
932 * path (may or may not the same share).
934 fsp_set_fd(conn
->cwd_fsp
, AT_FDCWD
);
938 DEBUG(4,("vfs_ChDir to %s\n", smb_fname
->base_name
));
940 ret
= SMB_VFS_CHDIR(conn
, smb_fname
);
946 * Always replace conn->cwd_fsp. We
947 * don't know if it's been modified by
948 * VFS modules in the stack.
950 fsp_set_fd(conn
->cwd_fsp
, AT_FDCWD
);
953 cwd
= vfs_GetWd(conn
, conn
);
956 * vfs_GetWd() failed.
957 * We must be able to read cwd.
958 * Return to original directory
961 int saved_errno
= errno
;
963 if (conn
->cwd_fsp
->fsp_name
== NULL
) {
965 * Failed on the very first chdir()+getwd()
966 * for this connection. We can't
969 smb_panic("conn->cwd getwd failed\n");
974 /* Return to the previous $cwd. */
975 ret
= SMB_VFS_CHDIR(conn
, conn
->cwd_fsp
->fsp_name
);
977 smb_panic("conn->cwd getwd failed\n");
982 /* And fail the chdir(). */
986 /* vfs_GetWd() succeeded. */
987 /* Replace global cache. */
989 LastDir
= SMB_STRDUP(smb_fname
->base_name
);
992 * (Indirect) Callers of vfs_ChDir() may still hold references to the
993 * old conn->cwd_fsp->fsp_name. Move it to talloc_tos(), that way
994 * callers can use it for the lifetime of the SMB request.
996 talloc_move(talloc_tos(), &conn
->cwd_fsp
->fsp_name
);
998 conn
->cwd_fsp
->fsp_name
= talloc_move(conn
->cwd_fsp
, &cwd
);
1000 DBG_INFO("vfs_ChDir got %s\n", fsp_str_dbg(conn
->cwd_fsp
));
1005 /*******************************************************************
1006 Return the absolute current directory path - given a UNIX pathname.
1007 Note that this path is returned in DOS format, not UNIX
1008 format. Note this can be called with conn == NULL.
1009 ********************************************************************/
1011 struct smb_filename
*vfs_GetWd(TALLOC_CTX
*ctx
, connection_struct
*conn
)
1013 struct smb_filename
*current_dir_fname
= NULL
;
1015 struct smb_filename
*smb_fname_dot
= NULL
;
1016 struct smb_filename
*smb_fname_full
= NULL
;
1017 struct smb_filename
*result
= NULL
;
1019 if (!lp_getwd_cache()) {
1023 smb_fname_dot
= synthetic_smb_fname(ctx
,
1029 if (smb_fname_dot
== NULL
) {
1034 if (SMB_VFS_STAT(conn
, smb_fname_dot
) == -1) {
1036 * Known to fail for root: the directory may be NFS-mounted
1037 * and exported with root_squash (so has no root access).
1039 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
1040 "(NFS problem ?)\n", strerror(errno
) ));
1044 key
= vfs_file_id_from_sbuf(conn
, &smb_fname_dot
->st
);
1046 smb_fname_full
= (struct smb_filename
*)memcache_lookup_talloc(
1049 data_blob_const(&key
, sizeof(key
)));
1051 if (smb_fname_full
== NULL
) {
1055 if ((SMB_VFS_STAT(conn
, smb_fname_full
) == 0) &&
1056 (smb_fname_dot
->st
.st_ex_dev
== smb_fname_full
->st
.st_ex_dev
) &&
1057 (smb_fname_dot
->st
.st_ex_ino
== smb_fname_full
->st
.st_ex_ino
) &&
1058 (S_ISDIR(smb_fname_dot
->st
.st_ex_mode
))) {
1061 * Note: smb_fname_full is owned by smbd_memcache()
1062 * so we must make a copy to return.
1064 result
= cp_smb_filename(ctx
, smb_fname_full
);
1065 if (result
== NULL
) {
1074 * We don't have the information to hand so rely on traditional
1075 * methods. The very slow getcwd, which spawns a process on some
1076 * systems, or the not quite so bad getwd.
1079 current_dir_fname
= SMB_VFS_GETWD(conn
, ctx
);
1080 if (current_dir_fname
== NULL
) {
1081 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
1086 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot
->st
)) {
1087 key
= vfs_file_id_from_sbuf(conn
, &smb_fname_dot
->st
);
1090 * smbd_memcache() will own current_dir_fname after the
1091 * memcache_add_talloc call, so we must make
1092 * a copy on ctx to return.
1094 result
= cp_smb_filename(ctx
, current_dir_fname
);
1095 if (result
== NULL
) {
1100 * Ensure the memory going into the cache
1101 * doesn't have a destructor so it can be
1104 talloc_set_destructor(current_dir_fname
, NULL
);
1106 memcache_add_talloc(smbd_memcache(),
1108 data_blob_const(&key
, sizeof(key
)),
1109 ¤t_dir_fname
);
1110 /* current_dir_fname is now == NULL here. */
1112 /* current_dir_fname is already allocated on ctx. */
1113 result
= current_dir_fname
;
1117 TALLOC_FREE(smb_fname_dot
);
1119 * Don't free current_dir_fname here. It's either been moved
1120 * to the memcache or is being returned in result.
1125 /*******************************************************************
1126 Reduce a file name, removing .. elements and checking that
1127 it is below dir in the hierarchy. This uses realpath.
1128 This function must run as root, and will return names
1129 and valid stat structs that can be checked on open.
1130 ********************************************************************/
1132 NTSTATUS
check_reduced_name_with_privilege(connection_struct
*conn
,
1133 const struct smb_filename
*smb_fname
,
1134 struct smb_request
*smbreq
)
1137 TALLOC_CTX
*ctx
= talloc_tos();
1138 const char *conn_rootdir
;
1140 char *resolved_name
= NULL
;
1141 struct smb_filename
*resolved_fname
= NULL
;
1142 struct smb_filename
*saved_dir_fname
= NULL
;
1143 struct smb_filename
*smb_fname_cwd
= NULL
;
1145 struct smb_filename
*parent_name
= NULL
;
1146 struct smb_filename
*file_name
= NULL
;
1148 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
1149 smb_fname
->base_name
,
1150 conn
->connectpath
));
1152 status
= SMB_VFS_PARENT_PATHNAME(conn
,
1157 if (!NT_STATUS_IS_OK(status
)) {
1161 if (SMB_VFS_STAT(conn
, parent_name
) != 0) {
1162 status
= map_nt_error_from_unix(errno
);
1165 /* Remember where we were. */
1166 saved_dir_fname
= vfs_GetWd(ctx
, conn
);
1167 if (!saved_dir_fname
) {
1168 status
= map_nt_error_from_unix(errno
);
1172 if (vfs_ChDir(conn
, parent_name
) == -1) {
1173 status
= map_nt_error_from_unix(errno
);
1177 smb_fname_cwd
= synthetic_smb_fname(talloc_tos(),
1183 if (smb_fname_cwd
== NULL
) {
1184 status
= NT_STATUS_NO_MEMORY
;
1188 /* Get the absolute path of the parent directory. */
1189 resolved_fname
= SMB_VFS_REALPATH(conn
, ctx
, smb_fname_cwd
);
1190 if (resolved_fname
== NULL
) {
1191 status
= map_nt_error_from_unix(errno
);
1194 resolved_name
= resolved_fname
->base_name
;
1196 if (*resolved_name
!= '/') {
1197 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1198 "doesn't return absolute paths !\n"));
1199 status
= NT_STATUS_OBJECT_NAME_INVALID
;
1203 DBG_DEBUG("realpath [%s] -> [%s]\n",
1204 smb_fname_str_dbg(parent_name
),
1207 /* Now check the stat value is the same. */
1208 if (SMB_VFS_LSTAT(conn
, smb_fname_cwd
) != 0) {
1209 status
= map_nt_error_from_unix(errno
);
1213 /* Ensure we're pointing at the same place. */
1214 if (!check_same_stat(&smb_fname_cwd
->st
, &parent_name
->st
)) {
1215 DBG_ERR("device/inode/uid/gid on directory %s changed. "
1216 "Denying access !\n",
1217 smb_fname_str_dbg(parent_name
));
1218 status
= NT_STATUS_ACCESS_DENIED
;
1222 /* Ensure we're below the connect path. */
1224 conn_rootdir
= SMB_VFS_CONNECTPATH(conn
, smb_fname
);
1225 if (conn_rootdir
== NULL
) {
1226 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1228 status
= NT_STATUS_ACCESS_DENIED
;
1232 rootdir_len
= strlen(conn_rootdir
);
1235 * In the case of rootdir_len == 1, we know that conn_rootdir is
1236 * "/", and we also know that resolved_name starts with a slash.
1237 * So, in this corner case, resolved_name is automatically a
1238 * sub-directory of the conn_rootdir. Thus we can skip the string
1239 * comparison and the next character checks (which are even
1240 * wrong in this case).
1242 if (rootdir_len
!= 1) {
1245 matched
= (strncmp(conn_rootdir
, resolved_name
,
1248 if (!matched
|| (resolved_name
[rootdir_len
] != '/' &&
1249 resolved_name
[rootdir_len
] != '\0')) {
1250 DBG_WARNING("%s is a symlink outside the "
1252 smb_fname_str_dbg(parent_name
));
1253 DEBUGADD(1, ("conn_rootdir =%s\n", conn_rootdir
));
1254 DEBUGADD(1, ("resolved_name=%s\n", resolved_name
));
1255 status
= NT_STATUS_ACCESS_DENIED
;
1260 /* Now ensure that the last component either doesn't
1261 exist, or is *NOT* a symlink. */
1263 ret
= SMB_VFS_LSTAT(conn
, file_name
);
1265 /* Errno must be ENOENT for this be ok. */
1266 if (errno
!= ENOENT
) {
1267 status
= map_nt_error_from_unix(errno
);
1268 DBG_WARNING("LSTAT on %s failed with %s\n",
1269 smb_fname_str_dbg(file_name
),
1275 if (VALID_STAT(file_name
->st
) &&
1276 S_ISLNK(file_name
->st
.st_ex_mode
))
1278 DBG_WARNING("Last component %s is a symlink. Denying"
1280 smb_fname_str_dbg(file_name
));
1281 status
= NT_STATUS_ACCESS_DENIED
;
1285 status
= NT_STATUS_OK
;
1289 if (saved_dir_fname
!= NULL
) {
1290 vfs_ChDir(conn
, saved_dir_fname
);
1291 TALLOC_FREE(saved_dir_fname
);
1293 TALLOC_FREE(resolved_fname
);
1294 TALLOC_FREE(parent_name
);
1298 /*******************************************************************
1299 Reduce a file name, removing .. elements and checking that
1300 it is below dir in the hierarchy. This uses realpath.
1302 If cwd_name == NULL then fname is a client given path relative
1303 to the root path of the share.
1305 If cwd_name != NULL then fname is a client given path relative
1306 to cwd_name. cwd_name is relative to the root path of the share.
1307 ********************************************************************/
1309 NTSTATUS
check_reduced_name(connection_struct
*conn
,
1310 const struct smb_filename
*cwd_fname
,
1311 const struct smb_filename
*smb_fname
)
1313 TALLOC_CTX
*ctx
= talloc_tos();
1314 const char *cwd_name
= cwd_fname
? cwd_fname
->base_name
: NULL
;
1315 const char *fname
= smb_fname
->base_name
;
1316 struct smb_filename
*resolved_fname
;
1317 char *resolved_name
= NULL
;
1318 char *new_fname
= NULL
;
1319 bool allow_symlinks
= true;
1320 const char *conn_rootdir
;
1323 DBG_DEBUG("check_reduced_name [%s] [%s]\n", fname
, conn
->connectpath
);
1325 resolved_fname
= SMB_VFS_REALPATH(conn
, ctx
, smb_fname
);
1327 if (resolved_fname
== NULL
) {
1329 struct smb_filename
*dir_fname
= NULL
;
1330 struct smb_filename
*last_component
= NULL
;
1332 if (errno
== ENOTDIR
) {
1333 DBG_NOTICE("Component not a directory in getting "
1334 "realpath for %s\n",
1336 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1338 if (errno
!= ENOENT
) {
1339 status
= map_nt_error_from_unix(errno
);
1340 DBG_NOTICE("couldn't get realpath for %s: %s\n",
1346 /* errno == ENOENT */
1349 * Last component didn't exist. Remove it and try and
1350 * canonicalise the directory name.
1353 status
= SMB_VFS_PARENT_PATHNAME(conn
,
1358 if (!NT_STATUS_IS_OK(status
)) {
1362 resolved_fname
= SMB_VFS_REALPATH(conn
, ctx
, dir_fname
);
1363 if (resolved_fname
== NULL
) {
1364 status
= map_nt_error_from_unix(errno
);
1366 if (errno
== ENOENT
|| errno
== ENOTDIR
) {
1367 status
= NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1370 DBG_NOTICE("couldn't get realpath for "
1372 smb_fname_str_dbg(dir_fname
),
1376 resolved_name
= talloc_asprintf(ctx
,
1378 resolved_fname
->base_name
,
1379 last_component
->base_name
);
1380 if (resolved_name
== NULL
) {
1381 return NT_STATUS_NO_MEMORY
;
1384 resolved_name
= resolved_fname
->base_name
;
1387 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname
,
1390 if (*resolved_name
!= '/') {
1391 DEBUG(0,("check_reduced_name: realpath doesn't return "
1392 "absolute paths !\n"));
1393 TALLOC_FREE(resolved_fname
);
1394 return NT_STATUS_OBJECT_NAME_INVALID
;
1397 /* Common widelinks and symlinks checks. */
1398 conn_rootdir
= SMB_VFS_CONNECTPATH(conn
, smb_fname
);
1399 if (conn_rootdir
== NULL
) {
1400 DBG_NOTICE("Could not get conn_rootdir\n");
1401 TALLOC_FREE(resolved_fname
);
1402 return NT_STATUS_ACCESS_DENIED
;
1405 rootdir_len
= strlen(conn_rootdir
);
1408 * In the case of rootdir_len == 1, we know that
1409 * conn_rootdir is "/", and we also know that
1410 * resolved_name starts with a slash. So, in this
1411 * corner case, resolved_name is automatically a
1412 * sub-directory of the conn_rootdir. Thus we can skip
1413 * the string comparison and the next character checks
1414 * (which are even wrong in this case).
1416 if (rootdir_len
!= 1) {
1419 matched
= (strncmp(conn_rootdir
, resolved_name
,
1421 if (!matched
|| (resolved_name
[rootdir_len
] != '/' &&
1422 resolved_name
[rootdir_len
] != '\0')) {
1423 DBG_NOTICE("Bad access attempt: %s is a symlink "
1426 "conn_rootdir =%s\n"
1427 "resolved_name=%s\n",
1431 TALLOC_FREE(resolved_fname
);
1432 return NT_STATUS_ACCESS_DENIED
;
1436 /* Extra checks if all symlinks are disallowed. */
1437 allow_symlinks
= lp_follow_symlinks(SNUM(conn
));
1438 if (!allow_symlinks
) {
1439 /* fname can't have changed in resolved_path. */
1440 const char *p
= &resolved_name
[rootdir_len
];
1443 * UNIX filesystem semantics, names consisting
1444 * only of "." or ".." CANNOT be symlinks.
1446 if (ISDOT(fname
) || ISDOTDOT(fname
)) {
1451 DBG_NOTICE("logic error (%c) "
1452 "in resolved_name: %s\n",
1455 TALLOC_FREE(resolved_fname
);
1456 return NT_STATUS_ACCESS_DENIED
;
1462 * If cwd_name is present and not ".",
1463 * then fname is relative to that, not
1464 * the root of the share. Make sure the
1465 * path we check is the one the client
1466 * sent (cwd_name+fname).
1468 if (cwd_name
!= NULL
&& !ISDOT(cwd_name
)) {
1469 new_fname
= talloc_asprintf(ctx
,
1473 if (new_fname
== NULL
) {
1474 TALLOC_FREE(resolved_fname
);
1475 return NT_STATUS_NO_MEMORY
;
1480 if (strcmp(fname
, p
)!=0) {
1481 DBG_NOTICE("Bad access "
1482 "attempt: %s is a symlink to %s\n",
1485 TALLOC_FREE(resolved_fname
);
1486 TALLOC_FREE(new_fname
);
1487 return NT_STATUS_ACCESS_DENIED
;
1493 DBG_INFO("%s reduced to %s\n", fname
, resolved_name
);
1494 TALLOC_FREE(resolved_fname
);
1495 TALLOC_FREE(new_fname
);
1496 return NT_STATUS_OK
;
1500 * Ensure LSTAT is called for POSIX paths.
1502 int vfs_stat(struct connection_struct
*conn
,
1503 struct smb_filename
*smb_fname
)
1505 if (smb_fname
->flags
& SMB_FILENAME_POSIX_PATH
) {
1506 return SMB_VFS_LSTAT(conn
, smb_fname
);
1508 return SMB_VFS_STAT(conn
, smb_fname
);
1512 * XXX: This is temporary and there should be no callers of this once
1513 * smb_filename is plumbed through all path based operations.
1515 * Called when we know stream name parsing has already been done.
1517 int vfs_stat_smb_basename(struct connection_struct
*conn
,
1518 const struct smb_filename
*smb_fname_in
,
1519 SMB_STRUCT_STAT
*psbuf
)
1521 struct smb_filename smb_fname
= {
1522 .base_name
= discard_const_p(char, smb_fname_in
->base_name
),
1523 .flags
= smb_fname_in
->flags
,
1524 .twrp
= smb_fname_in
->twrp
,
1528 if (smb_fname
.flags
& SMB_FILENAME_POSIX_PATH
) {
1529 ret
= SMB_VFS_LSTAT(conn
, &smb_fname
);
1531 ret
= SMB_VFS_STAT(conn
, &smb_fname
);
1535 *psbuf
= smb_fname
.st
;
1541 * Ensure LSTAT is called for POSIX paths.
1544 NTSTATUS
vfs_stat_fsp(files_struct
*fsp
)
1547 struct stat_ex saved_stat
= fsp
->fsp_name
->st
;
1549 if (fsp_get_pathref_fd(fsp
) == -1) {
1550 if (fsp
->posix_flags
& FSP_POSIX_FLAGS_OPEN
) {
1551 ret
= SMB_VFS_LSTAT(fsp
->conn
, fsp
->fsp_name
);
1553 ret
= SMB_VFS_STAT(fsp
->conn
, fsp
->fsp_name
);
1556 ret
= SMB_VFS_FSTAT(fsp
, &fsp
->fsp_name
->st
);
1559 return map_nt_error_from_unix(errno
);
1561 update_stat_ex_from_saved_stat(&fsp
->fsp_name
->st
, &saved_stat
);
1562 return NT_STATUS_OK
;
1565 void init_smb_file_time(struct smb_file_time
*ft
)
1567 *ft
= (struct smb_file_time
) {
1568 .atime
= make_omit_timespec(),
1569 .ctime
= make_omit_timespec(),
1570 .mtime
= make_omit_timespec(),
1571 .create_time
= make_omit_timespec()
1576 * Initialize num_streams and streams, then call VFS op streaminfo
1579 NTSTATUS
vfs_fstreaminfo(struct files_struct
*fsp
,
1580 TALLOC_CTX
*mem_ctx
,
1581 unsigned int *num_streams
,
1582 struct stream_struct
**streams
)
1589 * Callers may pass fsp == NULL when passing smb_fname->fsp of a
1590 * symlink. This is ok, handle it here, by just return no
1591 * streams on a symlink.
1593 return NT_STATUS_OK
;
1596 if (fsp_get_pathref_fd(fsp
) == -1) {
1598 * No streams on non-real files/directories.
1600 return NT_STATUS_OK
;
1603 return SMB_VFS_FSTREAMINFO(fsp
,
1609 int vfs_fake_fd(void)
1615 * Return a valid fd, but ensure any attempt to use
1616 * it returns an error (EPIPE).
1618 ret
= pipe(pipe_fds
);
1628 * This is just a helper to make
1629 * users of vfs_fake_fd() more symmetric
1631 int vfs_fake_fd_close(int fd
)
1637 generate a file_id from a stat structure
1639 struct file_id
vfs_file_id_from_sbuf(connection_struct
*conn
, const SMB_STRUCT_STAT
*sbuf
)
1641 return SMB_VFS_FILE_ID_CREATE(conn
, sbuf
);
1644 NTSTATUS
vfs_at_fspcwd(TALLOC_CTX
*mem_ctx
,
1645 struct connection_struct
*conn
,
1646 struct files_struct
**_fsp
)
1648 struct files_struct
*fsp
= NULL
;
1650 fsp
= talloc_zero(mem_ctx
, struct files_struct
);
1652 return NT_STATUS_NO_MEMORY
;
1655 fsp
->fsp_name
= synthetic_smb_fname(fsp
, ".", NULL
, NULL
, 0, 0);
1656 if (fsp
->fsp_name
== NULL
) {
1658 return NT_STATUS_NO_MEMORY
;
1661 fsp
->fh
= fd_handle_create(fsp
);
1662 if (fsp
->fh
== NULL
) {
1664 return NT_STATUS_NO_MEMORY
;
1667 fsp_set_fd(fsp
, AT_FDCWD
);
1668 fsp
->fnum
= FNUM_FIELD_INVALID
;
1672 return NT_STATUS_OK
;
1675 int smb_vfs_call_connect(struct vfs_handle_struct
*handle
,
1676 const char *service
, const char *user
)
1679 return handle
->fns
->connect_fn(handle
, service
, user
);
1682 void smb_vfs_call_disconnect(struct vfs_handle_struct
*handle
)
1684 VFS_FIND(disconnect
);
1685 handle
->fns
->disconnect_fn(handle
);
1688 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct
*handle
,
1689 const struct smb_filename
*smb_fname
,
1694 VFS_FIND(disk_free
);
1695 return handle
->fns
->disk_free_fn(handle
, smb_fname
,
1696 bsize
, dfree
, dsize
);
1699 int smb_vfs_call_get_quota(struct vfs_handle_struct
*handle
,
1700 const struct smb_filename
*smb_fname
,
1701 enum SMB_QUOTA_TYPE qtype
,
1705 VFS_FIND(get_quota
);
1706 return handle
->fns
->get_quota_fn(handle
, smb_fname
, qtype
, id
, qt
);
1709 int smb_vfs_call_set_quota(struct vfs_handle_struct
*handle
,
1710 enum SMB_QUOTA_TYPE qtype
, unid_t id
,
1713 VFS_FIND(set_quota
);
1714 return handle
->fns
->set_quota_fn(handle
, qtype
, id
, qt
);
1717 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct
*handle
,
1718 struct files_struct
*fsp
,
1719 struct shadow_copy_data
*shadow_copy_data
,
1722 VFS_FIND(get_shadow_copy_data
);
1723 return handle
->fns
->get_shadow_copy_data_fn(handle
, fsp
,
1727 int smb_vfs_call_statvfs(struct vfs_handle_struct
*handle
,
1728 const struct smb_filename
*smb_fname
,
1729 struct vfs_statvfs_struct
*statbuf
)
1732 return handle
->fns
->statvfs_fn(handle
, smb_fname
, statbuf
);
1735 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct
*handle
,
1736 enum timestamp_set_resolution
*p_ts_res
)
1738 VFS_FIND(fs_capabilities
);
1739 return handle
->fns
->fs_capabilities_fn(handle
, p_ts_res
);
1742 NTSTATUS
smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct
*handle
,
1743 struct dfs_GetDFSReferral
*r
)
1745 VFS_FIND(get_dfs_referrals
);
1746 return handle
->fns
->get_dfs_referrals_fn(handle
, r
);
1749 NTSTATUS
smb_vfs_call_create_dfs_pathat(struct vfs_handle_struct
*handle
,
1750 struct files_struct
*dirfsp
,
1751 const struct smb_filename
*smb_fname
,
1752 const struct referral
*reflist
,
1753 size_t referral_count
)
1755 VFS_FIND(create_dfs_pathat
);
1756 return handle
->fns
->create_dfs_pathat_fn(handle
,
1763 NTSTATUS
smb_vfs_call_read_dfs_pathat(struct vfs_handle_struct
*handle
,
1764 TALLOC_CTX
*mem_ctx
,
1765 struct files_struct
*dirfsp
,
1766 struct smb_filename
*smb_fname
,
1767 struct referral
**ppreflist
,
1768 size_t *preferral_count
)
1770 VFS_FIND(read_dfs_pathat
);
1771 return handle
->fns
->read_dfs_pathat_fn(handle
,
1779 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct
*handle
,
1780 struct files_struct
*fsp
,
1782 uint32_t attributes
)
1784 VFS_FIND(fdopendir
);
1785 return handle
->fns
->fdopendir_fn(handle
, fsp
, mask
, attributes
);
1788 struct dirent
*smb_vfs_call_readdir(struct vfs_handle_struct
*handle
,
1789 struct files_struct
*dirfsp
,
1791 SMB_STRUCT_STAT
*sbuf
)
1794 return handle
->fns
->readdir_fn(handle
, dirfsp
, dirp
, sbuf
);
1797 void smb_vfs_call_seekdir(struct vfs_handle_struct
*handle
,
1798 DIR *dirp
, long offset
)
1801 handle
->fns
->seekdir_fn(handle
, dirp
, offset
);
1804 long smb_vfs_call_telldir(struct vfs_handle_struct
*handle
,
1808 return handle
->fns
->telldir_fn(handle
, dirp
);
1811 void smb_vfs_call_rewind_dir(struct vfs_handle_struct
*handle
,
1814 VFS_FIND(rewind_dir
);
1815 handle
->fns
->rewind_dir_fn(handle
, dirp
);
1818 int smb_vfs_call_mkdirat(struct vfs_handle_struct
*handle
,
1819 struct files_struct
*dirfsp
,
1820 const struct smb_filename
*smb_fname
,
1824 return handle
->fns
->mkdirat_fn(handle
,
1830 int smb_vfs_call_closedir(struct vfs_handle_struct
*handle
,
1834 return handle
->fns
->closedir_fn(handle
, dir
);
1837 int smb_vfs_call_openat(struct vfs_handle_struct
*handle
,
1838 const struct files_struct
*dirfsp
,
1839 const struct smb_filename
*smb_fname
,
1840 struct files_struct
*fsp
,
1845 return handle
->fns
->openat_fn(handle
,
1853 NTSTATUS
smb_vfs_call_create_file(struct vfs_handle_struct
*handle
,
1854 struct smb_request
*req
,
1855 struct smb_filename
*smb_fname
,
1856 uint32_t access_mask
,
1857 uint32_t share_access
,
1858 uint32_t create_disposition
,
1859 uint32_t create_options
,
1860 uint32_t file_attributes
,
1861 uint32_t oplock_request
,
1862 const struct smb2_lease
*lease
,
1863 uint64_t allocation_size
,
1864 uint32_t private_flags
,
1865 struct security_descriptor
*sd
,
1866 struct ea_list
*ea_list
,
1867 files_struct
**result
,
1869 const struct smb2_create_blobs
*in_context_blobs
,
1870 struct smb2_create_blobs
*out_context_blobs
)
1872 VFS_FIND(create_file
);
1873 return handle
->fns
->create_file_fn(
1874 handle
, req
, smb_fname
,
1875 access_mask
, share_access
, create_disposition
, create_options
,
1876 file_attributes
, oplock_request
, lease
, allocation_size
,
1877 private_flags
, sd
, ea_list
,
1878 result
, pinfo
, in_context_blobs
, out_context_blobs
);
1881 int smb_vfs_call_close(struct vfs_handle_struct
*handle
,
1882 struct files_struct
*fsp
)
1885 return handle
->fns
->close_fn(handle
, fsp
);
1888 ssize_t
smb_vfs_call_pread(struct vfs_handle_struct
*handle
,
1889 struct files_struct
*fsp
, void *data
, size_t n
,
1893 return handle
->fns
->pread_fn(handle
, fsp
, data
, n
, offset
);
1896 struct smb_vfs_call_pread_state
{
1897 ssize_t (*recv_fn
)(struct tevent_req
*req
, struct vfs_aio_state
*vfs_aio_state
);
1899 struct vfs_aio_state vfs_aio_state
;
1902 static void smb_vfs_call_pread_done(struct tevent_req
*subreq
);
1904 struct tevent_req
*smb_vfs_call_pread_send(struct vfs_handle_struct
*handle
,
1905 TALLOC_CTX
*mem_ctx
,
1906 struct tevent_context
*ev
,
1907 struct files_struct
*fsp
,
1909 size_t n
, off_t offset
)
1911 struct tevent_req
*req
, *subreq
;
1912 struct smb_vfs_call_pread_state
*state
;
1914 req
= tevent_req_create(mem_ctx
, &state
,
1915 struct smb_vfs_call_pread_state
);
1919 VFS_FIND(pread_send
);
1920 state
->recv_fn
= handle
->fns
->pread_recv_fn
;
1922 subreq
= handle
->fns
->pread_send_fn(handle
, state
, ev
, fsp
, data
, n
,
1924 if (tevent_req_nomem(subreq
, req
)) {
1925 return tevent_req_post(req
, ev
);
1927 tevent_req_set_callback(subreq
, smb_vfs_call_pread_done
, req
);
1931 static void smb_vfs_call_pread_done(struct tevent_req
*subreq
)
1933 struct tevent_req
*req
= tevent_req_callback_data(
1934 subreq
, struct tevent_req
);
1935 struct smb_vfs_call_pread_state
*state
= tevent_req_data(
1936 req
, struct smb_vfs_call_pread_state
);
1938 state
->retval
= state
->recv_fn(subreq
, &state
->vfs_aio_state
);
1939 TALLOC_FREE(subreq
);
1940 if (state
->retval
== -1) {
1941 tevent_req_error(req
, state
->vfs_aio_state
.error
);
1944 tevent_req_done(req
);
1947 ssize_t
SMB_VFS_PREAD_RECV(struct tevent_req
*req
,
1948 struct vfs_aio_state
*vfs_aio_state
)
1950 struct smb_vfs_call_pread_state
*state
= tevent_req_data(
1951 req
, struct smb_vfs_call_pread_state
);
1954 if (tevent_req_is_unix_error(req
, &vfs_aio_state
->error
)) {
1955 tevent_req_received(req
);
1958 *vfs_aio_state
= state
->vfs_aio_state
;
1959 retval
= state
->retval
;
1960 tevent_req_received(req
);
1964 ssize_t
smb_vfs_call_pwrite(struct vfs_handle_struct
*handle
,
1965 struct files_struct
*fsp
, const void *data
,
1966 size_t n
, off_t offset
)
1969 return handle
->fns
->pwrite_fn(handle
, fsp
, data
, n
, offset
);
1972 struct smb_vfs_call_pwrite_state
{
1973 ssize_t (*recv_fn
)(struct tevent_req
*req
, struct vfs_aio_state
*vfs_aio_state
);
1975 struct vfs_aio_state vfs_aio_state
;
1978 static void smb_vfs_call_pwrite_done(struct tevent_req
*subreq
);
1980 struct tevent_req
*smb_vfs_call_pwrite_send(struct vfs_handle_struct
*handle
,
1981 TALLOC_CTX
*mem_ctx
,
1982 struct tevent_context
*ev
,
1983 struct files_struct
*fsp
,
1985 size_t n
, off_t offset
)
1987 struct tevent_req
*req
, *subreq
;
1988 struct smb_vfs_call_pwrite_state
*state
;
1990 req
= tevent_req_create(mem_ctx
, &state
,
1991 struct smb_vfs_call_pwrite_state
);
1995 VFS_FIND(pwrite_send
);
1996 state
->recv_fn
= handle
->fns
->pwrite_recv_fn
;
1998 subreq
= handle
->fns
->pwrite_send_fn(handle
, state
, ev
, fsp
, data
, n
,
2000 if (tevent_req_nomem(subreq
, req
)) {
2001 return tevent_req_post(req
, ev
);
2003 tevent_req_set_callback(subreq
, smb_vfs_call_pwrite_done
, req
);
2007 static void smb_vfs_call_pwrite_done(struct tevent_req
*subreq
)
2009 struct tevent_req
*req
= tevent_req_callback_data(
2010 subreq
, struct tevent_req
);
2011 struct smb_vfs_call_pwrite_state
*state
= tevent_req_data(
2012 req
, struct smb_vfs_call_pwrite_state
);
2014 state
->retval
= state
->recv_fn(subreq
, &state
->vfs_aio_state
);
2015 TALLOC_FREE(subreq
);
2016 if (state
->retval
== -1) {
2017 tevent_req_error(req
, state
->vfs_aio_state
.error
);
2020 tevent_req_done(req
);
2023 ssize_t
SMB_VFS_PWRITE_RECV(struct tevent_req
*req
,
2024 struct vfs_aio_state
*vfs_aio_state
)
2026 struct smb_vfs_call_pwrite_state
*state
= tevent_req_data(
2027 req
, struct smb_vfs_call_pwrite_state
);
2030 if (tevent_req_is_unix_error(req
, &vfs_aio_state
->error
)) {
2031 tevent_req_received(req
);
2034 *vfs_aio_state
= state
->vfs_aio_state
;
2035 retval
= state
->retval
;
2036 tevent_req_received(req
);
2040 off_t
smb_vfs_call_lseek(struct vfs_handle_struct
*handle
,
2041 struct files_struct
*fsp
, off_t offset
,
2045 return handle
->fns
->lseek_fn(handle
, fsp
, offset
, whence
);
2048 ssize_t
smb_vfs_call_sendfile(struct vfs_handle_struct
*handle
, int tofd
,
2049 files_struct
*fromfsp
, const DATA_BLOB
*header
,
2050 off_t offset
, size_t count
)
2053 return handle
->fns
->sendfile_fn(handle
, tofd
, fromfsp
, header
, offset
,
2057 ssize_t
smb_vfs_call_recvfile(struct vfs_handle_struct
*handle
, int fromfd
,
2058 files_struct
*tofsp
, off_t offset
,
2062 return handle
->fns
->recvfile_fn(handle
, fromfd
, tofsp
, offset
, count
);
2065 int smb_vfs_call_renameat(struct vfs_handle_struct
*handle
,
2066 files_struct
*srcfsp
,
2067 const struct smb_filename
*smb_fname_src
,
2068 files_struct
*dstfsp
,
2069 const struct smb_filename
*smb_fname_dst
)
2072 return handle
->fns
->renameat_fn(handle
,
2079 struct smb_vfs_call_fsync_state
{
2080 int (*recv_fn
)(struct tevent_req
*req
, struct vfs_aio_state
*vfs_aio_state
);
2082 struct vfs_aio_state vfs_aio_state
;
2085 static void smb_vfs_call_fsync_done(struct tevent_req
*subreq
);
2087 struct tevent_req
*smb_vfs_call_fsync_send(struct vfs_handle_struct
*handle
,
2088 TALLOC_CTX
*mem_ctx
,
2089 struct tevent_context
*ev
,
2090 struct files_struct
*fsp
)
2092 struct tevent_req
*req
, *subreq
;
2093 struct smb_vfs_call_fsync_state
*state
;
2095 req
= tevent_req_create(mem_ctx
, &state
,
2096 struct smb_vfs_call_fsync_state
);
2100 VFS_FIND(fsync_send
);
2101 state
->recv_fn
= handle
->fns
->fsync_recv_fn
;
2103 subreq
= handle
->fns
->fsync_send_fn(handle
, state
, ev
, fsp
);
2104 if (tevent_req_nomem(subreq
, req
)) {
2105 return tevent_req_post(req
, ev
);
2107 tevent_req_set_callback(subreq
, smb_vfs_call_fsync_done
, req
);
2111 static void smb_vfs_call_fsync_done(struct tevent_req
*subreq
)
2113 struct tevent_req
*req
= tevent_req_callback_data(
2114 subreq
, struct tevent_req
);
2115 struct smb_vfs_call_fsync_state
*state
= tevent_req_data(
2116 req
, struct smb_vfs_call_fsync_state
);
2118 state
->retval
= state
->recv_fn(subreq
, &state
->vfs_aio_state
);
2119 TALLOC_FREE(subreq
);
2120 if (state
->retval
== -1) {
2121 tevent_req_error(req
, state
->vfs_aio_state
.error
);
2124 tevent_req_done(req
);
2127 int SMB_VFS_FSYNC_RECV(struct tevent_req
*req
, struct vfs_aio_state
*vfs_aio_state
)
2129 struct smb_vfs_call_fsync_state
*state
= tevent_req_data(
2130 req
, struct smb_vfs_call_fsync_state
);
2133 if (tevent_req_is_unix_error(req
, &vfs_aio_state
->error
)) {
2134 tevent_req_received(req
);
2137 *vfs_aio_state
= state
->vfs_aio_state
;
2138 retval
= state
->retval
;
2139 tevent_req_received(req
);
2144 * Synchronous version of fsync, built from backend
2145 * async VFS primitives. Uses a temporary sub-event
2146 * context (NOT NESTED).
2149 int smb_vfs_fsync_sync(files_struct
*fsp
)
2151 TALLOC_CTX
*frame
= talloc_stackframe();
2152 struct tevent_req
*req
= NULL
;
2153 struct vfs_aio_state aio_state
= { 0 };
2156 struct tevent_context
*ev
= samba_tevent_context_init(frame
);
2162 req
= SMB_VFS_FSYNC_SEND(talloc_tos(), ev
, fsp
);
2167 ok
= tevent_req_poll(req
, ev
);
2172 ret
= SMB_VFS_FSYNC_RECV(req
, &aio_state
);
2177 if (aio_state
.error
!= 0) {
2178 errno
= aio_state
.error
;
2183 int smb_vfs_call_stat(struct vfs_handle_struct
*handle
,
2184 struct smb_filename
*smb_fname
)
2187 return handle
->fns
->stat_fn(handle
, smb_fname
);
2190 int smb_vfs_call_fstat(struct vfs_handle_struct
*handle
,
2191 struct files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
2194 return handle
->fns
->fstat_fn(handle
, fsp
, sbuf
);
2197 int smb_vfs_call_lstat(struct vfs_handle_struct
*handle
,
2198 struct smb_filename
*smb_filename
)
2201 return handle
->fns
->lstat_fn(handle
, smb_filename
);
2204 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct
*handle
,
2205 struct files_struct
*fsp
,
2206 const SMB_STRUCT_STAT
*sbuf
)
2208 VFS_FIND(get_alloc_size
);
2209 return handle
->fns
->get_alloc_size_fn(handle
, fsp
, sbuf
);
2212 int smb_vfs_call_unlinkat(struct vfs_handle_struct
*handle
,
2213 struct files_struct
*dirfsp
,
2214 const struct smb_filename
*smb_fname
,
2218 return handle
->fns
->unlinkat_fn(handle
,
2224 int smb_vfs_call_fchmod(struct vfs_handle_struct
*handle
,
2225 struct files_struct
*fsp
, mode_t mode
)
2228 return handle
->fns
->fchmod_fn(handle
, fsp
, mode
);
2231 int smb_vfs_call_fchown(struct vfs_handle_struct
*handle
,
2232 struct files_struct
*fsp
, uid_t uid
, gid_t gid
)
2235 return handle
->fns
->fchown_fn(handle
, fsp
, uid
, gid
);
2238 int smb_vfs_call_lchown(struct vfs_handle_struct
*handle
,
2239 const struct smb_filename
*smb_fname
,
2244 return handle
->fns
->lchown_fn(handle
, smb_fname
, uid
, gid
);
2247 int smb_vfs_call_chdir(struct vfs_handle_struct
*handle
,
2248 const struct smb_filename
*smb_fname
)
2251 return handle
->fns
->chdir_fn(handle
, smb_fname
);
2254 struct smb_filename
*smb_vfs_call_getwd(struct vfs_handle_struct
*handle
,
2258 return handle
->fns
->getwd_fn(handle
, ctx
);
2261 int smb_vfs_call_fntimes(struct vfs_handle_struct
*handle
,
2262 struct files_struct
*fsp
,
2263 struct smb_file_time
*ft
)
2266 return handle
->fns
->fntimes_fn(handle
, fsp
, ft
);
2269 int smb_vfs_call_ftruncate(struct vfs_handle_struct
*handle
,
2270 struct files_struct
*fsp
, off_t offset
)
2272 VFS_FIND(ftruncate
);
2273 return handle
->fns
->ftruncate_fn(handle
, fsp
, offset
);
2276 int smb_vfs_call_fallocate(struct vfs_handle_struct
*handle
,
2277 struct files_struct
*fsp
,
2282 VFS_FIND(fallocate
);
2283 return handle
->fns
->fallocate_fn(handle
, fsp
, mode
, offset
, len
);
2286 int smb_vfs_call_filesystem_sharemode(struct vfs_handle_struct
*handle
,
2287 struct files_struct
*fsp
,
2288 uint32_t share_mode
,
2289 uint32_t access_mask
)
2291 VFS_FIND(filesystem_sharemode
);
2292 return handle
->fns
->filesystem_sharemode_fn(handle
,
2298 int smb_vfs_call_fcntl(struct vfs_handle_struct
*handle
,
2299 struct files_struct
*fsp
, int cmd
, ...)
2306 va_start(cmd_arg
, cmd
);
2307 result
= handle
->fns
->fcntl_fn(handle
, fsp
, cmd
, cmd_arg
);
2313 int smb_vfs_call_linux_setlease(struct vfs_handle_struct
*handle
,
2314 struct files_struct
*fsp
, int leasetype
)
2316 VFS_FIND(linux_setlease
);
2317 return handle
->fns
->linux_setlease_fn(handle
, fsp
, leasetype
);
2320 int smb_vfs_call_symlinkat(struct vfs_handle_struct
*handle
,
2321 const struct smb_filename
*link_target
,
2322 struct files_struct
*dirfsp
,
2323 const struct smb_filename
*new_smb_fname
)
2325 VFS_FIND(symlinkat
);
2326 return handle
->fns
->symlinkat_fn(handle
,
2332 int smb_vfs_call_readlinkat(struct vfs_handle_struct
*handle
,
2333 const struct files_struct
*dirfsp
,
2334 const struct smb_filename
*smb_fname
,
2338 VFS_FIND(readlinkat
);
2339 return handle
->fns
->readlinkat_fn(handle
,
2346 int smb_vfs_call_linkat(struct vfs_handle_struct
*handle
,
2347 struct files_struct
*srcfsp
,
2348 const struct smb_filename
*old_smb_fname
,
2349 struct files_struct
*dstfsp
,
2350 const struct smb_filename
*new_smb_fname
,
2354 return handle
->fns
->linkat_fn(handle
,
2362 int smb_vfs_call_mknodat(struct vfs_handle_struct
*handle
,
2363 struct files_struct
*dirfsp
,
2364 const struct smb_filename
*smb_fname
,
2369 return handle
->fns
->mknodat_fn(handle
,
2376 struct smb_filename
*smb_vfs_call_realpath(struct vfs_handle_struct
*handle
,
2378 const struct smb_filename
*smb_fname
)
2381 return handle
->fns
->realpath_fn(handle
, ctx
, smb_fname
);
2384 int smb_vfs_call_fchflags(struct vfs_handle_struct
*handle
,
2385 struct files_struct
*fsp
,
2389 return handle
->fns
->fchflags_fn(handle
, fsp
, flags
);
2392 struct file_id
smb_vfs_call_file_id_create(struct vfs_handle_struct
*handle
,
2393 const SMB_STRUCT_STAT
*sbuf
)
2395 VFS_FIND(file_id_create
);
2396 return handle
->fns
->file_id_create_fn(handle
, sbuf
);
2399 uint64_t smb_vfs_call_fs_file_id(struct vfs_handle_struct
*handle
,
2400 const SMB_STRUCT_STAT
*sbuf
)
2402 VFS_FIND(fs_file_id
);
2403 return handle
->fns
->fs_file_id_fn(handle
, sbuf
);
2406 NTSTATUS
smb_vfs_call_fstreaminfo(struct vfs_handle_struct
*handle
,
2407 struct files_struct
*fsp
,
2408 TALLOC_CTX
*mem_ctx
,
2409 unsigned int *num_streams
,
2410 struct stream_struct
**streams
)
2412 VFS_FIND(fstreaminfo
);
2413 return handle
->fns
->fstreaminfo_fn(handle
, fsp
, mem_ctx
,
2414 num_streams
, streams
);
2417 int smb_vfs_call_get_real_filename(struct vfs_handle_struct
*handle
,
2418 const struct smb_filename
*path
,
2420 TALLOC_CTX
*mem_ctx
,
2423 VFS_FIND(get_real_filename
);
2424 return handle
->fns
->get_real_filename_fn(handle
, path
, name
, mem_ctx
,
2428 const char *smb_vfs_call_connectpath(struct vfs_handle_struct
*handle
,
2429 const struct smb_filename
*smb_fname
)
2431 VFS_FIND(connectpath
);
2432 return handle
->fns
->connectpath_fn(handle
, smb_fname
);
2435 bool smb_vfs_call_strict_lock_check(struct vfs_handle_struct
*handle
,
2436 struct files_struct
*fsp
,
2437 struct lock_struct
*plock
)
2439 VFS_FIND(strict_lock_check
);
2440 return handle
->fns
->strict_lock_check_fn(handle
, fsp
, plock
);
2443 NTSTATUS
smb_vfs_call_translate_name(struct vfs_handle_struct
*handle
,
2445 enum vfs_translate_direction direction
,
2446 TALLOC_CTX
*mem_ctx
,
2449 VFS_FIND(translate_name
);
2450 return handle
->fns
->translate_name_fn(handle
, name
, direction
, mem_ctx
,
2454 NTSTATUS
smb_vfs_call_parent_pathname(struct vfs_handle_struct
*handle
,
2455 TALLOC_CTX
*mem_ctx
,
2456 const struct smb_filename
*smb_fname_in
,
2457 struct smb_filename
**parent_dir_out
,
2458 struct smb_filename
**atname_out
)
2460 VFS_FIND(parent_pathname
);
2461 return handle
->fns
->parent_pathname_fn(handle
,
2468 NTSTATUS
smb_vfs_call_fsctl(struct vfs_handle_struct
*handle
,
2469 struct files_struct
*fsp
,
2473 const uint8_t *in_data
,
2476 uint32_t max_out_len
,
2480 return handle
->fns
->fsctl_fn(handle
, fsp
, ctx
, function
, req_flags
,
2481 in_data
, in_len
, out_data
, max_out_len
,
2485 NTSTATUS
smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct
*handle
,
2486 struct files_struct
*fsp
,
2489 VFS_FIND(fget_dos_attributes
);
2490 return handle
->fns
->fget_dos_attributes_fn(handle
, fsp
, dosmode
);
2493 NTSTATUS
smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct
*handle
,
2494 struct files_struct
*fsp
,
2497 VFS_FIND(fset_dos_attributes
);
2498 return handle
->fns
->fset_dos_attributes_fn(handle
, fsp
, dosmode
);
2501 struct tevent_req
*smb_vfs_call_offload_read_send(TALLOC_CTX
*mem_ctx
,
2502 struct tevent_context
*ev
,
2503 struct vfs_handle_struct
*handle
,
2504 struct files_struct
*fsp
,
2510 VFS_FIND(offload_read_send
);
2511 return handle
->fns
->offload_read_send_fn(mem_ctx
, ev
, handle
,
2513 ttl
, offset
, to_copy
);
2516 NTSTATUS
smb_vfs_call_offload_read_recv(struct tevent_req
*req
,
2517 struct vfs_handle_struct
*handle
,
2518 TALLOC_CTX
*mem_ctx
,
2521 DATA_BLOB
*token_blob
)
2523 VFS_FIND(offload_read_recv
);
2524 return handle
->fns
->offload_read_recv_fn(req
, handle
, mem_ctx
, flags
, xferlen
, token_blob
);
2527 struct tevent_req
*smb_vfs_call_offload_write_send(struct vfs_handle_struct
*handle
,
2528 TALLOC_CTX
*mem_ctx
,
2529 struct tevent_context
*ev
,
2532 off_t transfer_offset
,
2533 struct files_struct
*dest_fsp
,
2537 VFS_FIND(offload_write_send
);
2538 return handle
->fns
->offload_write_send_fn(handle
, mem_ctx
, ev
, fsctl
,
2539 token
, transfer_offset
,
2540 dest_fsp
, dest_off
, num
);
2543 NTSTATUS
smb_vfs_call_offload_write_recv(struct vfs_handle_struct
*handle
,
2544 struct tevent_req
*req
,
2547 VFS_FIND(offload_write_recv
);
2548 return handle
->fns
->offload_write_recv_fn(handle
, req
, copied
);
2551 struct smb_vfs_call_get_dos_attributes_state
{
2552 files_struct
*dir_fsp
;
2553 NTSTATUS (*recv_fn
)(struct tevent_req
*req
,
2554 struct vfs_aio_state
*aio_state
,
2556 struct vfs_aio_state aio_state
;
2557 uint32_t dos_attributes
;
2560 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req
*subreq
);
2562 struct tevent_req
*smb_vfs_call_get_dos_attributes_send(
2563 TALLOC_CTX
*mem_ctx
,
2564 struct tevent_context
*ev
,
2565 struct vfs_handle_struct
*handle
,
2566 files_struct
*dir_fsp
,
2567 struct smb_filename
*smb_fname
)
2569 struct tevent_req
*req
= NULL
;
2570 struct smb_vfs_call_get_dos_attributes_state
*state
= NULL
;
2571 struct tevent_req
*subreq
= NULL
;
2573 req
= tevent_req_create(mem_ctx
, &state
,
2574 struct smb_vfs_call_get_dos_attributes_state
);
2579 VFS_FIND(get_dos_attributes_send
);
2581 *state
= (struct smb_vfs_call_get_dos_attributes_state
) {
2583 .recv_fn
= handle
->fns
->get_dos_attributes_recv_fn
,
2586 subreq
= handle
->fns
->get_dos_attributes_send_fn(mem_ctx
,
2591 if (tevent_req_nomem(subreq
, req
)) {
2592 return tevent_req_post(req
, ev
);
2594 tevent_req_defer_callback(req
, ev
);
2596 tevent_req_set_callback(subreq
,
2597 smb_vfs_call_get_dos_attributes_done
,
2603 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req
*subreq
)
2605 struct tevent_req
*req
=
2606 tevent_req_callback_data(subreq
,
2608 struct smb_vfs_call_get_dos_attributes_state
*state
=
2609 tevent_req_data(req
,
2610 struct smb_vfs_call_get_dos_attributes_state
);
2615 * Make sure we run as the user again
2617 ok
= change_to_user_and_service_by_fsp(state
->dir_fsp
);
2620 status
= state
->recv_fn(subreq
,
2622 &state
->dos_attributes
);
2623 TALLOC_FREE(subreq
);
2624 if (tevent_req_nterror(req
, status
)) {
2628 tevent_req_done(req
);
2631 NTSTATUS
smb_vfs_call_get_dos_attributes_recv(
2632 struct tevent_req
*req
,
2633 struct vfs_aio_state
*aio_state
,
2634 uint32_t *dos_attributes
)
2636 struct smb_vfs_call_get_dos_attributes_state
*state
=
2637 tevent_req_data(req
,
2638 struct smb_vfs_call_get_dos_attributes_state
);
2641 if (tevent_req_is_nterror(req
, &status
)) {
2642 tevent_req_received(req
);
2646 *aio_state
= state
->aio_state
;
2647 *dos_attributes
= state
->dos_attributes
;
2648 tevent_req_received(req
);
2649 return NT_STATUS_OK
;
2652 NTSTATUS
smb_vfs_call_fget_compression(vfs_handle_struct
*handle
,
2653 TALLOC_CTX
*mem_ctx
,
2654 struct files_struct
*fsp
,
2655 uint16_t *_compression_fmt
)
2657 VFS_FIND(fget_compression
);
2658 return handle
->fns
->fget_compression_fn(handle
, mem_ctx
, fsp
,
2662 NTSTATUS
smb_vfs_call_set_compression(vfs_handle_struct
*handle
,
2663 TALLOC_CTX
*mem_ctx
,
2664 struct files_struct
*fsp
,
2665 uint16_t compression_fmt
)
2667 VFS_FIND(set_compression
);
2668 return handle
->fns
->set_compression_fn(handle
, mem_ctx
, fsp
,
2672 NTSTATUS
smb_vfs_call_snap_check_path(vfs_handle_struct
*handle
,
2673 TALLOC_CTX
*mem_ctx
,
2674 const char *service_path
,
2677 VFS_FIND(snap_check_path
);
2678 return handle
->fns
->snap_check_path_fn(handle
, mem_ctx
, service_path
,
2682 NTSTATUS
smb_vfs_call_snap_create(struct vfs_handle_struct
*handle
,
2683 TALLOC_CTX
*mem_ctx
,
2684 const char *base_volume
,
2690 VFS_FIND(snap_create
);
2691 return handle
->fns
->snap_create_fn(handle
, mem_ctx
, base_volume
, tstamp
,
2692 rw
, base_path
, snap_path
);
2695 NTSTATUS
smb_vfs_call_snap_delete(struct vfs_handle_struct
*handle
,
2696 TALLOC_CTX
*mem_ctx
,
2700 VFS_FIND(snap_delete
);
2701 return handle
->fns
->snap_delete_fn(handle
, mem_ctx
, base_path
,
2705 NTSTATUS
smb_vfs_call_fget_nt_acl(struct vfs_handle_struct
*handle
,
2706 struct files_struct
*fsp
,
2707 uint32_t security_info
,
2708 TALLOC_CTX
*mem_ctx
,
2709 struct security_descriptor
**ppdesc
)
2711 VFS_FIND(fget_nt_acl
);
2712 return handle
->fns
->fget_nt_acl_fn(handle
, fsp
, security_info
,
2716 NTSTATUS
smb_vfs_call_fset_nt_acl(struct vfs_handle_struct
*handle
,
2717 struct files_struct
*fsp
,
2718 uint32_t security_info_sent
,
2719 const struct security_descriptor
*psd
)
2721 VFS_FIND(fset_nt_acl
);
2722 return handle
->fns
->fset_nt_acl_fn(handle
, fsp
, security_info_sent
,
2726 NTSTATUS
smb_vfs_call_audit_file(struct vfs_handle_struct
*handle
,
2727 struct smb_filename
*file
,
2728 struct security_acl
*sacl
,
2729 uint32_t access_requested
,
2730 uint32_t access_denied
)
2732 VFS_FIND(audit_file
);
2733 return handle
->fns
->audit_file_fn(handle
,
2740 SMB_ACL_T
smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct
*handle
,
2741 struct files_struct
*fsp
,
2742 SMB_ACL_TYPE_T type
,
2743 TALLOC_CTX
*mem_ctx
)
2745 VFS_FIND(sys_acl_get_fd
);
2746 return handle
->fns
->sys_acl_get_fd_fn(handle
, fsp
, type
, mem_ctx
);
2749 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct
*handle
,
2750 struct files_struct
*fsp
,
2751 TALLOC_CTX
*mem_ctx
,
2752 char **blob_description
,
2755 VFS_FIND(sys_acl_blob_get_fd
);
2756 return handle
->fns
->sys_acl_blob_get_fd_fn(handle
, fsp
, mem_ctx
, blob_description
, blob
);
2759 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct
*handle
,
2760 struct files_struct
*fsp
,
2761 SMB_ACL_TYPE_T type
,
2764 VFS_FIND(sys_acl_set_fd
);
2765 return handle
->fns
->sys_acl_set_fd_fn(handle
, fsp
, type
, theacl
);
2768 int smb_vfs_call_sys_acl_delete_def_fd(struct vfs_handle_struct
*handle
,
2769 struct files_struct
*fsp
)
2771 VFS_FIND(sys_acl_delete_def_fd
);
2772 return handle
->fns
->sys_acl_delete_def_fd_fn(handle
, fsp
);
2775 struct smb_vfs_call_getxattrat_state
{
2776 files_struct
*dir_fsp
;
2777 ssize_t (*recv_fn
)(struct tevent_req
*req
,
2778 struct vfs_aio_state
*aio_state
,
2779 TALLOC_CTX
*mem_ctx
,
2780 uint8_t **xattr_value
);
2782 uint8_t *xattr_value
;
2783 struct vfs_aio_state aio_state
;
2786 static void smb_vfs_call_getxattrat_done(struct tevent_req
*subreq
);
2788 struct tevent_req
*smb_vfs_call_getxattrat_send(
2789 TALLOC_CTX
*mem_ctx
,
2790 struct tevent_context
*ev
,
2791 struct vfs_handle_struct
*handle
,
2792 files_struct
*dir_fsp
,
2793 const struct smb_filename
*smb_fname
,
2794 const char *xattr_name
,
2797 struct tevent_req
*req
= NULL
;
2798 struct smb_vfs_call_getxattrat_state
*state
= NULL
;
2799 struct tevent_req
*subreq
= NULL
;
2801 req
= tevent_req_create(mem_ctx
, &state
,
2802 struct smb_vfs_call_getxattrat_state
);
2807 VFS_FIND(getxattrat_send
);
2809 *state
= (struct smb_vfs_call_getxattrat_state
) {
2811 .recv_fn
= handle
->fns
->getxattrat_recv_fn
,
2814 subreq
= handle
->fns
->getxattrat_send_fn(mem_ctx
,
2821 if (tevent_req_nomem(subreq
, req
)) {
2822 return tevent_req_post(req
, ev
);
2824 tevent_req_defer_callback(req
, ev
);
2826 tevent_req_set_callback(subreq
, smb_vfs_call_getxattrat_done
, req
);
2830 static void smb_vfs_call_getxattrat_done(struct tevent_req
*subreq
)
2832 struct tevent_req
*req
= tevent_req_callback_data(
2833 subreq
, struct tevent_req
);
2834 struct smb_vfs_call_getxattrat_state
*state
= tevent_req_data(
2835 req
, struct smb_vfs_call_getxattrat_state
);
2839 * Make sure we run as the user again
2841 ok
= change_to_user_and_service_by_fsp(state
->dir_fsp
);
2844 state
->retval
= state
->recv_fn(subreq
,
2847 &state
->xattr_value
);
2848 TALLOC_FREE(subreq
);
2849 if (state
->retval
== -1) {
2850 tevent_req_error(req
, state
->aio_state
.error
);
2854 tevent_req_done(req
);
2857 ssize_t
smb_vfs_call_getxattrat_recv(struct tevent_req
*req
,
2858 struct vfs_aio_state
*aio_state
,
2859 TALLOC_CTX
*mem_ctx
,
2860 uint8_t **xattr_value
)
2862 struct smb_vfs_call_getxattrat_state
*state
= tevent_req_data(
2863 req
, struct smb_vfs_call_getxattrat_state
);
2866 if (tevent_req_is_unix_error(req
, &aio_state
->error
)) {
2867 tevent_req_received(req
);
2871 *aio_state
= state
->aio_state
;
2872 xattr_size
= state
->retval
;
2873 if (xattr_value
!= NULL
) {
2874 *xattr_value
= talloc_move(mem_ctx
, &state
->xattr_value
);
2877 tevent_req_received(req
);
2881 ssize_t
smb_vfs_call_fgetxattr(struct vfs_handle_struct
*handle
,
2882 struct files_struct
*fsp
, const char *name
,
2883 void *value
, size_t size
)
2885 VFS_FIND(fgetxattr
);
2886 return handle
->fns
->fgetxattr_fn(handle
, fsp
, name
, value
, size
);
2889 ssize_t
smb_vfs_call_flistxattr(struct vfs_handle_struct
*handle
,
2890 struct files_struct
*fsp
, char *list
,
2893 VFS_FIND(flistxattr
);
2894 return handle
->fns
->flistxattr_fn(handle
, fsp
, list
, size
);
2897 int smb_vfs_call_fremovexattr(struct vfs_handle_struct
*handle
,
2898 struct files_struct
*fsp
, const char *name
)
2900 VFS_FIND(fremovexattr
);
2901 return handle
->fns
->fremovexattr_fn(handle
, fsp
, name
);
2904 int smb_vfs_call_fsetxattr(struct vfs_handle_struct
*handle
,
2905 struct files_struct
*fsp
, const char *name
,
2906 const void *value
, size_t size
, int flags
)
2908 VFS_FIND(fsetxattr
);
2909 return handle
->fns
->fsetxattr_fn(handle
, fsp
, name
, value
, size
, flags
);
2912 bool smb_vfs_call_aio_force(struct vfs_handle_struct
*handle
,
2913 struct files_struct
*fsp
)
2915 VFS_FIND(aio_force
);
2916 return handle
->fns
->aio_force_fn(handle
, fsp
);
2919 NTSTATUS
smb_vfs_call_durable_cookie(struct vfs_handle_struct
*handle
,
2920 struct files_struct
*fsp
,
2921 TALLOC_CTX
*mem_ctx
,
2924 VFS_FIND(durable_cookie
);
2925 return handle
->fns
->durable_cookie_fn(handle
, fsp
, mem_ctx
, cookie
);
2928 NTSTATUS
smb_vfs_call_durable_disconnect(struct vfs_handle_struct
*handle
,
2929 struct files_struct
*fsp
,
2930 const DATA_BLOB old_cookie
,
2931 TALLOC_CTX
*mem_ctx
,
2932 DATA_BLOB
*new_cookie
)
2934 VFS_FIND(durable_disconnect
);
2935 return handle
->fns
->durable_disconnect_fn(handle
, fsp
, old_cookie
,
2936 mem_ctx
, new_cookie
);
2939 NTSTATUS
smb_vfs_call_durable_reconnect(struct vfs_handle_struct
*handle
,
2940 struct smb_request
*smb1req
,
2941 struct smbXsrv_open
*op
,
2942 const DATA_BLOB old_cookie
,
2943 TALLOC_CTX
*mem_ctx
,
2944 struct files_struct
**fsp
,
2945 DATA_BLOB
*new_cookie
)
2947 VFS_FIND(durable_reconnect
);
2948 return handle
->fns
->durable_reconnect_fn(handle
, smb1req
, op
,
2949 old_cookie
, mem_ctx
, fsp
,
2953 NTSTATUS
smb_vfs_call_freaddir_attr(struct vfs_handle_struct
*handle
,
2954 struct files_struct
*fsp
,
2955 TALLOC_CTX
*mem_ctx
,
2956 struct readdir_attr_data
**attr_data
)
2958 VFS_FIND(freaddir_attr
);
2959 return handle
->fns
->freaddir_attr_fn(handle
,