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"
31 #include "transfer_file.h"
33 #include "lib/util/tevent_unix.h"
36 #define DBGC_CLASS DBGC_VFS
41 struct vfs_fsp_data
*next
;
42 struct vfs_handle_struct
*owner
;
43 void (*destroy
)(void *p_data
);
45 /* NOTE: This structure contains four pointers so that we can guarantee
46 * that the end of the structure is always both 4-byte and 8-byte aligned.
50 struct vfs_init_function_entry
{
52 struct vfs_init_function_entry
*prev
, *next
;
53 const struct vfs_fn_pointers
*fns
;
56 /****************************************************************************
57 maintain the list of available backends
58 ****************************************************************************/
60 static struct vfs_init_function_entry
*vfs_find_backend_entry(const char *name
)
62 struct vfs_init_function_entry
*entry
= backends
;
64 DEBUG(10, ("vfs_find_backend_entry called for %s\n", name
));
67 if (strcmp(entry
->name
, name
)==0) return entry
;
74 NTSTATUS
smb_register_vfs(int version
, const char *name
,
75 const struct vfs_fn_pointers
*fns
)
77 struct vfs_init_function_entry
*entry
= backends
;
79 if ((version
!= SMB_VFS_INTERFACE_VERSION
)) {
80 DEBUG(0, ("Failed to register vfs module.\n"
81 "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
82 "current SMB_VFS_INTERFACE_VERSION is %d.\n"
83 "Please recompile against the current Samba Version!\n",
84 version
, SMB_VFS_INTERFACE_VERSION
));
85 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
88 if (!name
|| !name
[0]) {
89 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
90 return NT_STATUS_INVALID_PARAMETER
;
93 if (vfs_find_backend_entry(name
)) {
94 DEBUG(0,("VFS module %s already loaded!\n", name
));
95 return NT_STATUS_OBJECT_NAME_COLLISION
;
98 entry
= SMB_XMALLOC_P(struct vfs_init_function_entry
);
99 entry
->name
= smb_xstrdup(name
);
102 DLIST_ADD(backends
, entry
);
103 DEBUG(5, ("Successfully added vfs backend '%s'\n", name
));
107 /****************************************************************************
108 initialise default vfs hooks
109 ****************************************************************************/
111 static void vfs_init_default(connection_struct
*conn
)
113 DEBUG(3, ("Initialising default vfs hooks\n"));
114 vfs_init_custom(conn
, DEFAULT_VFS_MODULE_NAME
);
117 /****************************************************************************
118 initialise custom vfs hooks
119 ****************************************************************************/
121 bool vfs_init_custom(connection_struct
*conn
, const char *vfs_object
)
123 char *module_path
= NULL
;
124 char *module_name
= NULL
;
125 char *module_param
= NULL
, *p
;
126 vfs_handle_struct
*handle
;
127 const struct vfs_init_function_entry
*entry
;
129 if (!conn
||!vfs_object
||!vfs_object
[0]) {
130 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
131 "empty vfs_object!\n"));
139 DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object
));
141 module_path
= smb_xstrdup(vfs_object
);
143 p
= strchr_m(module_path
, ':');
148 trim_char(module_param
, ' ', ' ');
151 trim_char(module_path
, ' ', ' ');
153 module_name
= smb_xstrdup(module_path
);
155 if ((module_name
[0] == '/') &&
156 (strcmp(module_path
, DEFAULT_VFS_MODULE_NAME
) != 0)) {
159 * Extract the module name from the path. Just use the base
160 * name of the last path component.
163 SAFE_FREE(module_name
);
164 module_name
= smb_xstrdup(strrchr_m(module_path
, '/')+1);
166 p
= strchr_m(module_name
, '.');
173 /* First, try to load the module with the new module system */
174 entry
= vfs_find_backend_entry(module_name
);
178 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
181 status
= smb_load_module("vfs", module_path
);
182 if (!NT_STATUS_IS_OK(status
)) {
183 DEBUG(0, ("error probing vfs module '%s': %s\n",
184 module_path
, nt_errstr(status
)));
188 entry
= vfs_find_backend_entry(module_name
);
190 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object
));
195 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object
));
197 handle
= talloc_zero(conn
, vfs_handle_struct
);
199 DEBUG(0,("TALLOC_ZERO() failed!\n"));
203 handle
->fns
= entry
->fns
;
205 handle
->param
= talloc_strdup(conn
, module_param
);
207 DLIST_ADD(conn
->vfs_handles
, handle
);
209 SAFE_FREE(module_path
);
210 SAFE_FREE(module_name
);
214 SAFE_FREE(module_path
);
215 SAFE_FREE(module_name
);
219 /*****************************************************************
220 Allow VFS modules to extend files_struct with VFS-specific state.
221 This will be ok for small numbers of extensions, but might need to
222 be refactored if it becomes more widely used.
223 ******************************************************************/
225 #define EXT_DATA_AREA(e) ((uint8 *)(e) + sizeof(struct vfs_fsp_data))
227 void *vfs_add_fsp_extension_notype(vfs_handle_struct
*handle
,
228 files_struct
*fsp
, size_t ext_size
,
229 void (*destroy_fn
)(void *p_data
))
231 struct vfs_fsp_data
*ext
;
234 /* Prevent VFS modules adding multiple extensions. */
235 if ((ext_data
= vfs_fetch_fsp_extension(handle
, fsp
))) {
239 ext
= (struct vfs_fsp_data
*)TALLOC_ZERO(
240 handle
->conn
, sizeof(struct vfs_fsp_data
) + ext_size
);
246 ext
->next
= fsp
->vfs_extension
;
247 ext
->destroy
= destroy_fn
;
248 fsp
->vfs_extension
= ext
;
249 return EXT_DATA_AREA(ext
);
252 void vfs_remove_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
254 struct vfs_fsp_data
*curr
;
255 struct vfs_fsp_data
*prev
;
257 for (curr
= fsp
->vfs_extension
, prev
= NULL
;
259 prev
= curr
, curr
= curr
->next
) {
260 if (curr
->owner
== handle
) {
262 prev
->next
= curr
->next
;
264 fsp
->vfs_extension
= curr
->next
;
267 curr
->destroy(EXT_DATA_AREA(curr
));
275 void vfs_remove_all_fsp_extensions(files_struct
*fsp
)
277 struct vfs_fsp_data
*curr
;
278 struct vfs_fsp_data
*next
;
280 for (curr
= fsp
->vfs_extension
; curr
; curr
= next
) {
283 fsp
->vfs_extension
= next
;
286 curr
->destroy(EXT_DATA_AREA(curr
));
292 void *vfs_memctx_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
294 struct vfs_fsp_data
*head
;
296 for (head
= fsp
->vfs_extension
; head
; head
= head
->next
) {
297 if (head
->owner
== handle
) {
305 void *vfs_fetch_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
307 struct vfs_fsp_data
*head
;
309 head
= (struct vfs_fsp_data
*)vfs_memctx_fsp_extension(handle
, fsp
);
311 return EXT_DATA_AREA(head
);
319 /*****************************************************************
321 ******************************************************************/
323 bool smbd_vfs_init(connection_struct
*conn
)
325 const char **vfs_objects
;
329 /* Normal share - initialise with disk access functions */
330 vfs_init_default(conn
);
331 vfs_objects
= lp_vfs_objects(SNUM(conn
));
333 /* Override VFS functions if 'vfs object' was not specified*/
334 if (!vfs_objects
|| !vfs_objects
[0])
337 for (i
=0; vfs_objects
[i
] ;) {
341 for (j
=i
-1; j
>= 0; j
--) {
342 if (!vfs_init_custom(conn
, vfs_objects
[j
])) {
343 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects
[j
]));
350 /*******************************************************************
351 Check if a file exists in the vfs.
352 ********************************************************************/
354 NTSTATUS
vfs_file_exist(connection_struct
*conn
, struct smb_filename
*smb_fname
)
356 /* Only return OK if stat was successful and S_ISREG */
357 if ((SMB_VFS_STAT(conn
, smb_fname
) != -1) &&
358 S_ISREG(smb_fname
->st
.st_ex_mode
)) {
362 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
365 /****************************************************************************
366 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
367 ****************************************************************************/
369 ssize_t
vfs_read_data(files_struct
*fsp
, char *buf
, size_t byte_count
)
373 while (total
< byte_count
)
375 ssize_t ret
= SMB_VFS_READ(fsp
, buf
+ total
,
378 if (ret
== 0) return total
;
387 return (ssize_t
)total
;
390 ssize_t
vfs_pread_data(files_struct
*fsp
, char *buf
,
391 size_t byte_count
, off_t offset
)
395 while (total
< byte_count
)
397 ssize_t ret
= SMB_VFS_PREAD(fsp
, buf
+ total
,
398 byte_count
- total
, offset
+ total
);
400 if (ret
== 0) return total
;
409 return (ssize_t
)total
;
412 /****************************************************************************
413 Write data to a fd on the vfs.
414 ****************************************************************************/
416 ssize_t
vfs_write_data(struct smb_request
*req
,
424 if (req
&& req
->unread_bytes
) {
425 SMB_ASSERT(req
->unread_bytes
== N
);
426 /* VFS_RECVFILE must drain the socket
427 * before returning. */
428 req
->unread_bytes
= 0;
429 return SMB_VFS_RECVFILE(req
->sconn
->sock
,
436 ret
= SMB_VFS_WRITE(fsp
, buffer
+ total
, N
- total
);
445 return (ssize_t
)total
;
448 ssize_t
vfs_pwrite_data(struct smb_request
*req
,
457 if (req
&& req
->unread_bytes
) {
458 SMB_ASSERT(req
->unread_bytes
== N
);
459 /* VFS_RECVFILE must drain the socket
460 * before returning. */
461 req
->unread_bytes
= 0;
462 return SMB_VFS_RECVFILE(req
->sconn
->sock
,
469 ret
= SMB_VFS_PWRITE(fsp
, buffer
+ total
, N
- total
,
479 return (ssize_t
)total
;
481 /****************************************************************************
482 An allocate file space call using the vfs interface.
483 Allocates space for a file from a filedescriptor.
484 Returns 0 on success, -1 on failure.
485 ****************************************************************************/
487 int vfs_allocate_file_space(files_struct
*fsp
, uint64_t len
)
490 connection_struct
*conn
= fsp
->conn
;
491 uint64_t space_avail
;
492 uint64_t bsize
,dfree
,dsize
;
496 * Actually try and commit the space on disk....
499 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
500 fsp_str_dbg(fsp
), (double)len
));
502 if (((off_t
)len
) < 0) {
503 DEBUG(0,("vfs_allocate_file_space: %s negative len "
504 "requested.\n", fsp_str_dbg(fsp
)));
509 status
= vfs_stat_fsp(fsp
);
510 if (!NT_STATUS_IS_OK(status
)) {
514 if (len
== (uint64_t)fsp
->fsp_name
->st
.st_ex_size
)
517 if (len
< (uint64_t)fsp
->fsp_name
->st
.st_ex_size
) {
518 /* Shrink - use ftruncate. */
520 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
521 "size %.0f\n", fsp_str_dbg(fsp
),
522 (double)fsp
->fsp_name
->st
.st_ex_size
));
524 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_ALLOC_SHRINK
);
526 flush_write_cache(fsp
, SIZECHANGE_FLUSH
);
527 if ((ret
= SMB_VFS_FTRUNCATE(fsp
, (off_t
)len
)) != -1) {
528 set_filelen_write_cache(fsp
, len
);
531 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_ALLOC_SHRINK
);
536 if (!lp_strict_allocate(SNUM(fsp
->conn
)))
539 /* Grow - we need to test if we have enough space. */
541 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_ALLOC_GROW
);
543 /* See if we have a syscall that will allocate beyond end-of-file
544 without changing EOF. */
545 ret
= SMB_VFS_FALLOCATE(fsp
, VFS_FALLOCATE_KEEP_SIZE
, 0, len
);
547 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_ALLOC_GROW
);
550 /* We changed the allocation size on disk, but not
551 EOF - exactly as required. We're done ! */
555 len
-= fsp
->fsp_name
->st
.st_ex_size
;
556 len
/= 1024; /* Len is now number of 1k blocks needed. */
557 space_avail
= get_dfree_info(conn
, fsp
->fsp_name
->base_name
, false,
558 &bsize
, &dfree
, &dsize
);
559 if (space_avail
== (uint64_t)-1) {
563 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
564 "needed blocks = %.0f, space avail = %.0f\n",
565 fsp_str_dbg(fsp
), (double)fsp
->fsp_name
->st
.st_ex_size
, (double)len
,
566 (double)space_avail
));
568 if (len
> space_avail
) {
576 /****************************************************************************
577 A vfs set_filelen call.
578 set the length of a file from a filedescriptor.
579 Returns 0 on success, -1 on failure.
580 ****************************************************************************/
582 int vfs_set_filelen(files_struct
*fsp
, off_t len
)
586 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_SET_FILE_LEN
);
588 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
589 fsp_str_dbg(fsp
), (double)len
));
590 flush_write_cache(fsp
, SIZECHANGE_FLUSH
);
591 if ((ret
= SMB_VFS_FTRUNCATE(fsp
, len
)) != -1) {
592 set_filelen_write_cache(fsp
, len
);
593 notify_fname(fsp
->conn
, NOTIFY_ACTION_MODIFIED
,
594 FILE_NOTIFY_CHANGE_SIZE
595 | FILE_NOTIFY_CHANGE_ATTRIBUTES
,
596 fsp
->fsp_name
->base_name
);
599 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_SET_FILE_LEN
);
604 /****************************************************************************
605 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
606 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
607 as this is also called from the default SMB_VFS_FTRUNCATE code.
608 Always extends the file size.
609 Returns 0 on success, errno on failure.
610 ****************************************************************************/
612 #define SPARSE_BUF_WRITE_SIZE (32*1024)
614 int vfs_slow_fallocate(files_struct
*fsp
, off_t offset
, off_t len
)
620 sparse_buf
= SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE
);
627 while (total
< len
) {
628 size_t curr_write_size
= MIN(SPARSE_BUF_WRITE_SIZE
, (len
- total
));
630 pwrite_ret
= SMB_VFS_PWRITE(fsp
, sparse_buf
, curr_write_size
, offset
+ total
);
631 if (pwrite_ret
== -1) {
632 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
633 "%s failed with error %s\n",
634 fsp_str_dbg(fsp
), strerror(errno
)));
643 /****************************************************************************
644 A vfs fill sparse call.
645 Writes zeros from the end of file to len, if len is greater than EOF.
646 Used only by strict_sync.
647 Returns 0 on success, -1 on failure.
648 ****************************************************************************/
650 int vfs_fill_sparse(files_struct
*fsp
, off_t len
)
657 status
= vfs_stat_fsp(fsp
);
658 if (!NT_STATUS_IS_OK(status
)) {
662 if (len
<= fsp
->fsp_name
->st
.st_ex_size
) {
667 if (S_ISFIFO(fsp
->fsp_name
->st
.st_ex_mode
)) {
672 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
673 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp
),
674 (double)fsp
->fsp_name
->st
.st_ex_size
, (double)len
,
675 (double)(len
- fsp
->fsp_name
->st
.st_ex_size
)));
677 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_FILL_SPARSE
);
679 flush_write_cache(fsp
, SIZECHANGE_FLUSH
);
681 offset
= fsp
->fsp_name
->st
.st_ex_size
;
682 num_to_write
= len
- fsp
->fsp_name
->st
.st_ex_size
;
684 /* Only do this on non-stream file handles. */
685 if (fsp
->base_fsp
== NULL
) {
686 /* for allocation try fallocate first. This can fail on some
687 * platforms e.g. when the filesystem doesn't support it and no
688 * emulation is being done by the libc (like on AIX with JFS1). In that
689 * case we do our own emulation. fallocate implementations can
690 * return ENOTSUP or EINVAL in cases like that. */
691 ret
= SMB_VFS_FALLOCATE(fsp
, VFS_FALLOCATE_EXTEND_SIZE
,
692 offset
, num_to_write
);
701 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
702 "error %d. Falling back to slow manual allocation\n", ret
));
705 ret
= vfs_slow_fallocate(fsp
, offset
, num_to_write
);
714 set_filelen_write_cache(fsp
, len
);
717 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_FILL_SPARSE
);
721 /****************************************************************************
722 Transfer some data (n bytes) between two file_struct's.
723 ****************************************************************************/
725 static ssize_t
vfs_read_fn(void *file
, void *buf
, size_t len
)
727 struct files_struct
*fsp
= (struct files_struct
*)file
;
729 return SMB_VFS_READ(fsp
, buf
, len
);
732 static ssize_t
vfs_write_fn(void *file
, const void *buf
, size_t len
)
734 struct files_struct
*fsp
= (struct files_struct
*)file
;
736 return SMB_VFS_WRITE(fsp
, buf
, len
);
739 off_t
vfs_transfer_file(files_struct
*in
, files_struct
*out
, off_t n
)
741 return transfer_file_internal((void *)in
, (void *)out
, n
,
742 vfs_read_fn
, vfs_write_fn
);
745 /*******************************************************************
746 A vfs_readdir wrapper which just returns the file name.
747 ********************************************************************/
749 const char *vfs_readdirname(connection_struct
*conn
, void *p
,
750 SMB_STRUCT_STAT
*sbuf
, char **talloced
)
752 struct dirent
*ptr
= NULL
;
760 ptr
= SMB_VFS_READDIR(conn
, (DIR *)p
, sbuf
);
772 #ifdef HAVE_BROKEN_READDIR_NAME
773 /* using /usr/ucb/cc is BAD */
777 status
= SMB_VFS_TRANSLATE_NAME(conn
, dname
, vfs_translate_to_windows
,
778 talloc_tos(), &translated
);
779 if (NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
783 *talloced
= translated
;
784 if (!NT_STATUS_IS_OK(status
)) {
790 /*******************************************************************
791 A wrapper for vfs_chdir().
792 ********************************************************************/
794 int vfs_ChDir(connection_struct
*conn
, const char *path
)
799 LastDir
= SMB_STRDUP("");
802 if (strcsequal(path
,"."))
805 if (*path
== '/' && strcsequal(LastDir
,path
))
808 DEBUG(4,("vfs_ChDir to %s\n",path
));
810 res
= SMB_VFS_CHDIR(conn
,path
);
813 LastDir
= SMB_STRDUP(path
);
818 /*******************************************************************
819 Return the absolute current directory path - given a UNIX pathname.
820 Note that this path is returned in DOS format, not UNIX
821 format. Note this can be called with conn == NULL.
822 ********************************************************************/
824 char *vfs_GetWd(TALLOC_CTX
*ctx
, connection_struct
*conn
)
826 char *current_dir
= NULL
;
828 DATA_BLOB cache_value
;
830 struct smb_filename
*smb_fname_dot
= NULL
;
831 struct smb_filename
*smb_fname_full
= NULL
;
834 if (!lp_getwd_cache()) {
838 status
= create_synthetic_smb_fname(ctx
, ".", NULL
, NULL
,
840 if (!NT_STATUS_IS_OK(status
)) {
841 errno
= map_errno_from_nt_status(status
);
845 if (SMB_VFS_STAT(conn
, smb_fname_dot
) == -1) {
847 * Known to fail for root: the directory may be NFS-mounted
848 * and exported with root_squash (so has no root access).
850 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
851 "(NFS problem ?)\n", strerror(errno
) ));
855 key
= vfs_file_id_from_sbuf(conn
, &smb_fname_dot
->st
);
857 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE
,
858 data_blob_const(&key
, sizeof(key
)),
863 SMB_ASSERT((cache_value
.length
> 0)
864 && (cache_value
.data
[cache_value
.length
-1] == '\0'));
866 status
= create_synthetic_smb_fname(ctx
, (char *)cache_value
.data
,
867 NULL
, NULL
, &smb_fname_full
);
868 if (!NT_STATUS_IS_OK(status
)) {
869 errno
= map_errno_from_nt_status(status
);
873 if ((SMB_VFS_STAT(conn
, smb_fname_full
) == 0) &&
874 (smb_fname_dot
->st
.st_ex_dev
== smb_fname_full
->st
.st_ex_dev
) &&
875 (smb_fname_dot
->st
.st_ex_ino
== smb_fname_full
->st
.st_ex_ino
) &&
876 (S_ISDIR(smb_fname_dot
->st
.st_ex_mode
))) {
880 result
= talloc_strdup(ctx
, smb_fname_full
->base_name
);
881 if (result
== NULL
) {
890 * We don't have the information to hand so rely on traditional
891 * methods. The very slow getcwd, which spawns a process on some
892 * systems, or the not quite so bad getwd.
895 current_dir
= SMB_VFS_GETWD(conn
);
896 if (current_dir
== NULL
) {
897 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
902 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot
->st
)) {
903 key
= vfs_file_id_from_sbuf(conn
, &smb_fname_dot
->st
);
905 memcache_add(smbd_memcache(), GETWD_CACHE
,
906 data_blob_const(&key
, sizeof(key
)),
907 data_blob_const(current_dir
,
908 strlen(current_dir
)+1));
911 result
= talloc_strdup(ctx
, current_dir
);
912 if (result
== NULL
) {
917 TALLOC_FREE(smb_fname_dot
);
918 TALLOC_FREE(smb_fname_full
);
919 SAFE_FREE(current_dir
);
923 /*******************************************************************
924 Reduce a file name, removing .. elements and checking that
925 it is below dir in the heirachy. This uses realpath.
926 This function must run as root, and will return names
927 and valid stat structs that can be checked on open.
928 ********************************************************************/
930 NTSTATUS
check_reduced_name_with_privilege(connection_struct
*conn
,
932 struct smb_request
*smbreq
)
935 TALLOC_CTX
*ctx
= talloc_tos();
936 const char *conn_rootdir
;
938 char *dir_name
= NULL
;
939 const char *last_component
= NULL
;
940 char *resolved_name
= NULL
;
941 char *saved_dir
= NULL
;
942 struct smb_filename
*smb_fname_cwd
= NULL
;
943 struct privilege_paths
*priv_paths
= NULL
;
946 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
951 priv_paths
= talloc_zero(smbreq
, struct privilege_paths
);
953 status
= NT_STATUS_NO_MEMORY
;
957 if (!parent_dirname(ctx
, fname
, &dir_name
, &last_component
)) {
958 status
= NT_STATUS_NO_MEMORY
;
962 priv_paths
->parent_name
.base_name
= talloc_strdup(priv_paths
, dir_name
);
963 priv_paths
->file_name
.base_name
= talloc_strdup(priv_paths
, last_component
);
965 if (priv_paths
->parent_name
.base_name
== NULL
||
966 priv_paths
->file_name
.base_name
== NULL
) {
967 status
= NT_STATUS_NO_MEMORY
;
971 if (SMB_VFS_STAT(conn
, &priv_paths
->parent_name
) != 0) {
972 status
= map_nt_error_from_unix(errno
);
975 /* Remember where we were. */
976 saved_dir
= vfs_GetWd(ctx
, conn
);
978 status
= map_nt_error_from_unix(errno
);
982 /* Go to the parent directory to lock in memory. */
983 if (vfs_ChDir(conn
, priv_paths
->parent_name
.base_name
) == -1) {
984 status
= map_nt_error_from_unix(errno
);
988 /* Get the absolute path of the parent directory. */
989 resolved_name
= SMB_VFS_REALPATH(conn
,".");
990 if (!resolved_name
) {
991 status
= map_nt_error_from_unix(errno
);
995 if (*resolved_name
!= '/') {
996 DEBUG(0,("check_reduced_name_with_privilege: realpath "
997 "doesn't return absolute paths !\n"));
998 status
= NT_STATUS_OBJECT_NAME_INVALID
;
1002 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1003 priv_paths
->parent_name
.base_name
,
1006 /* Now check the stat value is the same. */
1007 status
= create_synthetic_smb_fname(talloc_tos(), ".",
1010 if (!NT_STATUS_IS_OK(status
)) {
1014 if (SMB_VFS_LSTAT(conn
, smb_fname_cwd
) != 0) {
1015 status
= map_nt_error_from_unix(errno
);
1019 /* Ensure we're pointing at the same place. */
1020 if (!check_same_stat(&smb_fname_cwd
->st
, &priv_paths
->parent_name
.st
)) {
1021 DEBUG(0,("check_reduced_name_with_privilege: "
1022 "device/inode/uid/gid on directory %s changed. "
1023 "Denying access !\n",
1024 priv_paths
->parent_name
.base_name
));
1025 status
= NT_STATUS_ACCESS_DENIED
;
1029 /* Ensure we're below the connect path. */
1031 conn_rootdir
= SMB_VFS_CONNECTPATH(conn
, fname
);
1032 if (conn_rootdir
== NULL
) {
1033 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1035 status
= NT_STATUS_ACCESS_DENIED
;
1039 rootdir_len
= strlen(conn_rootdir
);
1040 if (strncmp(conn_rootdir
, resolved_name
, rootdir_len
) != 0) {
1041 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1042 "attempt: %s is a symlink outside the "
1045 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir
));
1046 DEBUGADD(2, ("resolved_name=%s\n", resolved_name
));
1047 status
= NT_STATUS_ACCESS_DENIED
;
1051 /* Now ensure that the last component either doesn't
1052 exist, or is *NOT* a symlink. */
1054 ret
= SMB_VFS_LSTAT(conn
, &priv_paths
->file_name
);
1056 /* Errno must be ENOENT for this be ok. */
1057 if (errno
!= ENOENT
) {
1058 status
= map_nt_error_from_unix(errno
);
1059 DEBUG(2, ("check_reduced_name_with_privilege: "
1060 "LSTAT on %s failed with %s\n",
1061 priv_paths
->file_name
.base_name
,
1062 nt_errstr(status
)));
1067 if (VALID_STAT(priv_paths
->file_name
.st
) &&
1068 S_ISLNK(priv_paths
->file_name
.st
.st_ex_mode
)) {
1069 DEBUG(2, ("check_reduced_name_with_privilege: "
1070 "Last component %s is a symlink. Denying"
1072 priv_paths
->file_name
.base_name
));
1073 status
= NT_STATUS_ACCESS_DENIED
;
1077 smbreq
->priv_paths
= priv_paths
;
1078 status
= NT_STATUS_OK
;
1083 vfs_ChDir(conn
, saved_dir
);
1085 SAFE_FREE(resolved_name
);
1086 if (!NT_STATUS_IS_OK(status
)) {
1087 TALLOC_FREE(priv_paths
);
1089 TALLOC_FREE(dir_name
);
1093 /*******************************************************************
1094 Reduce a file name, removing .. elements and checking that
1095 it is below dir in the heirachy. This uses realpath.
1096 ********************************************************************/
1098 NTSTATUS
check_reduced_name(connection_struct
*conn
, const char *fname
)
1100 char *resolved_name
= NULL
;
1101 bool allow_symlinks
= true;
1102 bool allow_widelinks
= false;
1104 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname
, conn
->connectpath
));
1106 resolved_name
= SMB_VFS_REALPATH(conn
,fname
);
1108 if (!resolved_name
) {
1111 DEBUG(3,("check_reduced_name: Component not a "
1112 "directory in getting realpath for "
1114 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1117 TALLOC_CTX
*ctx
= talloc_tos();
1118 char *dir_name
= NULL
;
1119 const char *last_component
= NULL
;
1120 char *new_name
= NULL
;
1123 /* Last component didn't exist.
1124 Remove it and try and canonicalise
1125 the directory name. */
1126 if (!parent_dirname(ctx
, fname
,
1129 return NT_STATUS_NO_MEMORY
;
1132 resolved_name
= SMB_VFS_REALPATH(conn
,dir_name
);
1133 if (!resolved_name
) {
1134 NTSTATUS status
= map_nt_error_from_unix(errno
);
1136 if (errno
== ENOENT
|| errno
== ENOTDIR
) {
1137 status
= NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1140 DEBUG(3,("check_reduce_name: "
1141 "couldn't get realpath for "
1144 nt_errstr(status
)));
1147 ret
= asprintf(&new_name
, "%s/%s",
1148 resolved_name
, last_component
);
1149 SAFE_FREE(resolved_name
);
1151 return NT_STATUS_NO_MEMORY
;
1153 resolved_name
= new_name
;
1157 DEBUG(3,("check_reduced_name: couldn't get "
1158 "realpath for %s\n", fname
));
1159 return map_nt_error_from_unix(errno
);
1163 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname
,
1166 if (*resolved_name
!= '/') {
1167 DEBUG(0,("check_reduced_name: realpath doesn't return "
1168 "absolute paths !\n"));
1169 SAFE_FREE(resolved_name
);
1170 return NT_STATUS_OBJECT_NAME_INVALID
;
1173 allow_widelinks
= lp_widelinks(SNUM(conn
));
1174 allow_symlinks
= lp_symlinks(SNUM(conn
));
1176 /* Common widelinks and symlinks checks. */
1177 if (!allow_widelinks
|| !allow_symlinks
) {
1178 const char *conn_rootdir
;
1181 conn_rootdir
= SMB_VFS_CONNECTPATH(conn
, fname
);
1182 if (conn_rootdir
== NULL
) {
1183 DEBUG(2, ("check_reduced_name: Could not get "
1185 SAFE_FREE(resolved_name
);
1186 return NT_STATUS_ACCESS_DENIED
;
1189 rootdir_len
= strlen(conn_rootdir
);
1190 if (strncmp(conn_rootdir
, resolved_name
,
1191 rootdir_len
) != 0) {
1192 DEBUG(2, ("check_reduced_name: Bad access "
1193 "attempt: %s is a symlink outside the "
1194 "share path\n", fname
));
1195 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir
));
1196 DEBUGADD(2, ("resolved_name=%s\n", resolved_name
));
1197 SAFE_FREE(resolved_name
);
1198 return NT_STATUS_ACCESS_DENIED
;
1201 /* Extra checks if all symlinks are disallowed. */
1202 if (!allow_symlinks
) {
1203 /* fname can't have changed in resolved_path. */
1204 const char *p
= &resolved_name
[rootdir_len
];
1206 /* *p can be '\0' if fname was "." */
1207 if (*p
== '\0' && ISDOT(fname
)) {
1212 DEBUG(2, ("check_reduced_name: logic error (%c) "
1213 "in resolved_name: %s\n",
1216 SAFE_FREE(resolved_name
);
1217 return NT_STATUS_ACCESS_DENIED
;
1221 if (strcmp(fname
, p
)!=0) {
1222 DEBUG(2, ("check_reduced_name: Bad access "
1223 "attempt: %s is a symlink\n",
1225 SAFE_FREE(resolved_name
);
1226 return NT_STATUS_ACCESS_DENIED
;
1233 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname
,
1235 SAFE_FREE(resolved_name
);
1236 return NT_STATUS_OK
;
1240 * XXX: This is temporary and there should be no callers of this once
1241 * smb_filename is plumbed through all path based operations.
1243 int vfs_stat_smb_fname(struct connection_struct
*conn
, const char *fname
,
1244 SMB_STRUCT_STAT
*psbuf
)
1246 struct smb_filename
*smb_fname
= NULL
;
1250 status
= create_synthetic_smb_fname_split(talloc_tos(), fname
, NULL
,
1252 if (!NT_STATUS_IS_OK(status
)) {
1253 errno
= map_errno_from_nt_status(status
);
1257 if (lp_posix_pathnames()) {
1258 ret
= SMB_VFS_LSTAT(conn
, smb_fname
);
1260 ret
= SMB_VFS_STAT(conn
, smb_fname
);
1264 *psbuf
= smb_fname
->st
;
1267 TALLOC_FREE(smb_fname
);
1272 * XXX: This is temporary and there should be no callers of this once
1273 * smb_filename is plumbed through all path based operations.
1275 int vfs_lstat_smb_fname(struct connection_struct
*conn
, const char *fname
,
1276 SMB_STRUCT_STAT
*psbuf
)
1278 struct smb_filename
*smb_fname
= NULL
;
1282 status
= create_synthetic_smb_fname_split(talloc_tos(), fname
, NULL
,
1284 if (!NT_STATUS_IS_OK(status
)) {
1285 errno
= map_errno_from_nt_status(status
);
1289 ret
= SMB_VFS_LSTAT(conn
, smb_fname
);
1291 *psbuf
= smb_fname
->st
;
1294 TALLOC_FREE(smb_fname
);
1299 * Ensure LSTAT is called for POSIX paths.
1302 NTSTATUS
vfs_stat_fsp(files_struct
*fsp
)
1306 if(fsp
->fh
->fd
== -1) {
1307 if (fsp
->posix_open
) {
1308 ret
= SMB_VFS_LSTAT(fsp
->conn
, fsp
->fsp_name
);
1310 ret
= SMB_VFS_STAT(fsp
->conn
, fsp
->fsp_name
);
1313 return map_nt_error_from_unix(errno
);
1316 if(SMB_VFS_FSTAT(fsp
, &fsp
->fsp_name
->st
) != 0) {
1317 return map_nt_error_from_unix(errno
);
1320 return NT_STATUS_OK
;
1324 * Initialize num_streams and streams, then call VFS op streaminfo
1326 NTSTATUS
vfs_streaminfo(connection_struct
*conn
,
1327 struct files_struct
*fsp
,
1329 TALLOC_CTX
*mem_ctx
,
1330 unsigned int *num_streams
,
1331 struct stream_struct
**streams
)
1335 return SMB_VFS_STREAMINFO(conn
, fsp
, fname
, mem_ctx
, num_streams
, streams
);
1339 generate a file_id from a stat structure
1341 struct file_id
vfs_file_id_from_sbuf(connection_struct
*conn
, const SMB_STRUCT_STAT
*sbuf
)
1343 return SMB_VFS_FILE_ID_CREATE(conn
, sbuf
);
1346 int smb_vfs_call_connect(struct vfs_handle_struct
*handle
,
1347 const char *service
, const char *user
)
1350 return handle
->fns
->connect_fn(handle
, service
, user
);
1353 void smb_vfs_call_disconnect(struct vfs_handle_struct
*handle
)
1355 VFS_FIND(disconnect
);
1356 handle
->fns
->disconnect_fn(handle
);
1359 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct
*handle
,
1360 const char *path
, bool small_query
,
1361 uint64_t *bsize
, uint64_t *dfree
,
1364 VFS_FIND(disk_free
);
1365 return handle
->fns
->disk_free_fn(handle
, path
, small_query
, bsize
,
1369 int smb_vfs_call_get_quota(struct vfs_handle_struct
*handle
,
1370 enum SMB_QUOTA_TYPE qtype
, unid_t id
,
1373 VFS_FIND(get_quota
);
1374 return handle
->fns
->get_quota_fn(handle
, qtype
, id
, qt
);
1377 int smb_vfs_call_set_quota(struct vfs_handle_struct
*handle
,
1378 enum SMB_QUOTA_TYPE qtype
, unid_t id
,
1381 VFS_FIND(set_quota
);
1382 return handle
->fns
->set_quota_fn(handle
, qtype
, id
, qt
);
1385 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct
*handle
,
1386 struct files_struct
*fsp
,
1387 struct shadow_copy_data
*shadow_copy_data
,
1390 VFS_FIND(get_shadow_copy_data
);
1391 return handle
->fns
->get_shadow_copy_data_fn(handle
, fsp
,
1395 int smb_vfs_call_statvfs(struct vfs_handle_struct
*handle
, const char *path
,
1396 struct vfs_statvfs_struct
*statbuf
)
1399 return handle
->fns
->statvfs_fn(handle
, path
, statbuf
);
1402 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct
*handle
,
1403 enum timestamp_set_resolution
*p_ts_res
)
1405 VFS_FIND(fs_capabilities
);
1406 return handle
->fns
->fs_capabilities_fn(handle
, p_ts_res
);
1409 NTSTATUS
smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct
*handle
,
1410 struct dfs_GetDFSReferral
*r
)
1412 VFS_FIND(get_dfs_referrals
);
1413 return handle
->fns
->get_dfs_referrals_fn(handle
, r
);
1416 DIR *smb_vfs_call_opendir(struct vfs_handle_struct
*handle
,
1417 const char *fname
, const char *mask
,
1421 return handle
->fns
->opendir_fn(handle
, fname
, mask
, attributes
);
1424 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct
*handle
,
1425 struct files_struct
*fsp
,
1429 VFS_FIND(fdopendir
);
1430 return handle
->fns
->fdopendir_fn(handle
, fsp
, mask
, attributes
);
1433 struct dirent
*smb_vfs_call_readdir(struct vfs_handle_struct
*handle
,
1435 SMB_STRUCT_STAT
*sbuf
)
1438 return handle
->fns
->readdir_fn(handle
, dirp
, sbuf
);
1441 void smb_vfs_call_seekdir(struct vfs_handle_struct
*handle
,
1442 DIR *dirp
, long offset
)
1445 handle
->fns
->seekdir_fn(handle
, dirp
, offset
);
1448 long smb_vfs_call_telldir(struct vfs_handle_struct
*handle
,
1452 return handle
->fns
->telldir_fn(handle
, dirp
);
1455 void smb_vfs_call_rewind_dir(struct vfs_handle_struct
*handle
,
1458 VFS_FIND(rewind_dir
);
1459 handle
->fns
->rewind_dir_fn(handle
, dirp
);
1462 int smb_vfs_call_mkdir(struct vfs_handle_struct
*handle
, const char *path
,
1466 return handle
->fns
->mkdir_fn(handle
, path
, mode
);
1469 int smb_vfs_call_rmdir(struct vfs_handle_struct
*handle
, const char *path
)
1472 return handle
->fns
->rmdir_fn(handle
, path
);
1475 int smb_vfs_call_closedir(struct vfs_handle_struct
*handle
,
1479 return handle
->fns
->closedir_fn(handle
, dir
);
1482 void smb_vfs_call_init_search_op(struct vfs_handle_struct
*handle
,
1485 VFS_FIND(init_search_op
);
1486 handle
->fns
->init_search_op_fn(handle
, dirp
);
1489 int smb_vfs_call_open(struct vfs_handle_struct
*handle
,
1490 struct smb_filename
*smb_fname
, struct files_struct
*fsp
,
1491 int flags
, mode_t mode
)
1494 return handle
->fns
->open_fn(handle
, smb_fname
, fsp
, flags
, mode
);
1497 NTSTATUS
smb_vfs_call_create_file(struct vfs_handle_struct
*handle
,
1498 struct smb_request
*req
,
1499 uint16_t root_dir_fid
,
1500 struct smb_filename
*smb_fname
,
1501 uint32_t access_mask
,
1502 uint32_t share_access
,
1503 uint32_t create_disposition
,
1504 uint32_t create_options
,
1505 uint32_t file_attributes
,
1506 uint32_t oplock_request
,
1507 uint64_t allocation_size
,
1508 uint32_t private_flags
,
1509 struct security_descriptor
*sd
,
1510 struct ea_list
*ea_list
,
1511 files_struct
**result
,
1514 VFS_FIND(create_file
);
1515 return handle
->fns
->create_file_fn(
1516 handle
, req
, root_dir_fid
, smb_fname
, access_mask
,
1517 share_access
, create_disposition
, create_options
,
1518 file_attributes
, oplock_request
, allocation_size
,
1519 private_flags
, sd
, ea_list
,
1523 int smb_vfs_call_close(struct vfs_handle_struct
*handle
,
1524 struct files_struct
*fsp
)
1527 return handle
->fns
->close_fn(handle
, fsp
);
1530 ssize_t
smb_vfs_call_read(struct vfs_handle_struct
*handle
,
1531 struct files_struct
*fsp
, void *data
, size_t n
)
1534 return handle
->fns
->read_fn(handle
, fsp
, data
, n
);
1537 ssize_t
smb_vfs_call_pread(struct vfs_handle_struct
*handle
,
1538 struct files_struct
*fsp
, void *data
, size_t n
,
1542 return handle
->fns
->pread_fn(handle
, fsp
, data
, n
, offset
);
1545 struct smb_vfs_call_pread_state
{
1546 ssize_t (*recv_fn
)(struct tevent_req
*req
, int *err
);
1550 static void smb_vfs_call_pread_done(struct tevent_req
*subreq
);
1552 struct tevent_req
*smb_vfs_call_pread_send(struct vfs_handle_struct
*handle
,
1553 TALLOC_CTX
*mem_ctx
,
1554 struct tevent_context
*ev
,
1555 struct files_struct
*fsp
,
1557 size_t n
, off_t offset
)
1559 struct tevent_req
*req
, *subreq
;
1560 struct smb_vfs_call_pread_state
*state
;
1562 req
= tevent_req_create(mem_ctx
, &state
,
1563 struct smb_vfs_call_pread_state
);
1567 VFS_FIND(pread_send
);
1568 state
->recv_fn
= handle
->fns
->pread_recv_fn
;
1570 subreq
= handle
->fns
->pread_send_fn(handle
, state
, ev
, fsp
, data
, n
,
1572 if (tevent_req_nomem(subreq
, req
)) {
1573 return tevent_req_post(req
, ev
);
1575 tevent_req_set_callback(subreq
, smb_vfs_call_pread_done
, req
);
1579 static void smb_vfs_call_pread_done(struct tevent_req
*subreq
)
1581 struct tevent_req
*req
= tevent_req_callback_data(
1582 subreq
, struct tevent_req
);
1583 struct smb_vfs_call_pread_state
*state
= tevent_req_data(
1584 req
, struct smb_vfs_call_pread_state
);
1587 state
->retval
= state
->recv_fn(subreq
, &err
);
1588 TALLOC_FREE(subreq
);
1589 if (state
->retval
== -1) {
1590 tevent_req_error(req
, err
);
1593 tevent_req_done(req
);
1596 ssize_t
SMB_VFS_PREAD_RECV(struct tevent_req
*req
, int *perrno
)
1598 struct smb_vfs_call_pread_state
*state
= tevent_req_data(
1599 req
, struct smb_vfs_call_pread_state
);
1602 if (tevent_req_is_unix_error(req
, &err
)) {
1606 return state
->retval
;
1609 ssize_t
smb_vfs_call_write(struct vfs_handle_struct
*handle
,
1610 struct files_struct
*fsp
, const void *data
,
1614 return handle
->fns
->write_fn(handle
, fsp
, data
, n
);
1617 ssize_t
smb_vfs_call_pwrite(struct vfs_handle_struct
*handle
,
1618 struct files_struct
*fsp
, const void *data
,
1619 size_t n
, off_t offset
)
1622 return handle
->fns
->pwrite_fn(handle
, fsp
, data
, n
, offset
);
1625 struct smb_vfs_call_pwrite_state
{
1626 ssize_t (*recv_fn
)(struct tevent_req
*req
, int *err
);
1630 static void smb_vfs_call_pwrite_done(struct tevent_req
*subreq
);
1632 struct tevent_req
*smb_vfs_call_pwrite_send(struct vfs_handle_struct
*handle
,
1633 TALLOC_CTX
*mem_ctx
,
1634 struct tevent_context
*ev
,
1635 struct files_struct
*fsp
,
1637 size_t n
, off_t offset
)
1639 struct tevent_req
*req
, *subreq
;
1640 struct smb_vfs_call_pwrite_state
*state
;
1642 req
= tevent_req_create(mem_ctx
, &state
,
1643 struct smb_vfs_call_pwrite_state
);
1647 VFS_FIND(pwrite_send
);
1648 state
->recv_fn
= handle
->fns
->pwrite_recv_fn
;
1650 subreq
= handle
->fns
->pwrite_send_fn(handle
, state
, ev
, fsp
, data
, n
,
1652 if (tevent_req_nomem(subreq
, req
)) {
1653 return tevent_req_post(req
, ev
);
1655 tevent_req_set_callback(subreq
, smb_vfs_call_pwrite_done
, req
);
1659 static void smb_vfs_call_pwrite_done(struct tevent_req
*subreq
)
1661 struct tevent_req
*req
= tevent_req_callback_data(
1662 subreq
, struct tevent_req
);
1663 struct smb_vfs_call_pwrite_state
*state
= tevent_req_data(
1664 req
, struct smb_vfs_call_pwrite_state
);
1667 state
->retval
= state
->recv_fn(subreq
, &err
);
1668 TALLOC_FREE(subreq
);
1669 if (state
->retval
== -1) {
1670 tevent_req_error(req
, err
);
1673 tevent_req_done(req
);
1676 ssize_t
SMB_VFS_PWRITE_RECV(struct tevent_req
*req
, int *perrno
)
1678 struct smb_vfs_call_pwrite_state
*state
= tevent_req_data(
1679 req
, struct smb_vfs_call_pwrite_state
);
1682 if (tevent_req_is_unix_error(req
, &err
)) {
1686 return state
->retval
;
1689 off_t
smb_vfs_call_lseek(struct vfs_handle_struct
*handle
,
1690 struct files_struct
*fsp
, off_t offset
,
1694 return handle
->fns
->lseek_fn(handle
, fsp
, offset
, whence
);
1697 ssize_t
smb_vfs_call_sendfile(struct vfs_handle_struct
*handle
, int tofd
,
1698 files_struct
*fromfsp
, const DATA_BLOB
*header
,
1699 off_t offset
, size_t count
)
1702 return handle
->fns
->sendfile_fn(handle
, tofd
, fromfsp
, header
, offset
,
1706 ssize_t
smb_vfs_call_recvfile(struct vfs_handle_struct
*handle
, int fromfd
,
1707 files_struct
*tofsp
, off_t offset
,
1711 return handle
->fns
->recvfile_fn(handle
, fromfd
, tofsp
, offset
, count
);
1714 int smb_vfs_call_rename(struct vfs_handle_struct
*handle
,
1715 const struct smb_filename
*smb_fname_src
,
1716 const struct smb_filename
*smb_fname_dst
)
1719 return handle
->fns
->rename_fn(handle
, smb_fname_src
, smb_fname_dst
);
1722 int smb_vfs_call_fsync(struct vfs_handle_struct
*handle
,
1723 struct files_struct
*fsp
)
1726 return handle
->fns
->fsync_fn(handle
, fsp
);
1729 struct smb_vfs_call_fsync_state
{
1730 int (*recv_fn
)(struct tevent_req
*req
, int *err
);
1734 static void smb_vfs_call_fsync_done(struct tevent_req
*subreq
);
1736 struct tevent_req
*smb_vfs_call_fsync_send(struct vfs_handle_struct
*handle
,
1737 TALLOC_CTX
*mem_ctx
,
1738 struct tevent_context
*ev
,
1739 struct files_struct
*fsp
)
1741 struct tevent_req
*req
, *subreq
;
1742 struct smb_vfs_call_fsync_state
*state
;
1744 req
= tevent_req_create(mem_ctx
, &state
,
1745 struct smb_vfs_call_fsync_state
);
1749 VFS_FIND(fsync_send
);
1750 state
->recv_fn
= handle
->fns
->fsync_recv_fn
;
1752 subreq
= handle
->fns
->fsync_send_fn(handle
, state
, ev
, fsp
);
1753 if (tevent_req_nomem(subreq
, req
)) {
1754 return tevent_req_post(req
, ev
);
1756 tevent_req_set_callback(subreq
, smb_vfs_call_fsync_done
, req
);
1760 static void smb_vfs_call_fsync_done(struct tevent_req
*subreq
)
1762 struct tevent_req
*req
= tevent_req_callback_data(
1763 subreq
, struct tevent_req
);
1764 struct smb_vfs_call_fsync_state
*state
= tevent_req_data(
1765 req
, struct smb_vfs_call_fsync_state
);
1768 state
->retval
= state
->recv_fn(subreq
, &err
);
1769 TALLOC_FREE(subreq
);
1770 if (state
->retval
== -1) {
1771 tevent_req_error(req
, err
);
1774 tevent_req_done(req
);
1777 int SMB_VFS_FSYNC_RECV(struct tevent_req
*req
, int *perrno
)
1779 struct smb_vfs_call_fsync_state
*state
= tevent_req_data(
1780 req
, struct smb_vfs_call_fsync_state
);
1783 if (tevent_req_is_unix_error(req
, &err
)) {
1787 return state
->retval
;
1791 int smb_vfs_call_stat(struct vfs_handle_struct
*handle
,
1792 struct smb_filename
*smb_fname
)
1795 return handle
->fns
->stat_fn(handle
, smb_fname
);
1798 int smb_vfs_call_fstat(struct vfs_handle_struct
*handle
,
1799 struct files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
1802 return handle
->fns
->fstat_fn(handle
, fsp
, sbuf
);
1805 int smb_vfs_call_lstat(struct vfs_handle_struct
*handle
,
1806 struct smb_filename
*smb_filename
)
1809 return handle
->fns
->lstat_fn(handle
, smb_filename
);
1812 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct
*handle
,
1813 struct files_struct
*fsp
,
1814 const SMB_STRUCT_STAT
*sbuf
)
1816 VFS_FIND(get_alloc_size
);
1817 return handle
->fns
->get_alloc_size_fn(handle
, fsp
, sbuf
);
1820 int smb_vfs_call_unlink(struct vfs_handle_struct
*handle
,
1821 const struct smb_filename
*smb_fname
)
1824 return handle
->fns
->unlink_fn(handle
, smb_fname
);
1827 int smb_vfs_call_chmod(struct vfs_handle_struct
*handle
, const char *path
,
1831 return handle
->fns
->chmod_fn(handle
, path
, mode
);
1834 int smb_vfs_call_fchmod(struct vfs_handle_struct
*handle
,
1835 struct files_struct
*fsp
, mode_t mode
)
1838 return handle
->fns
->fchmod_fn(handle
, fsp
, mode
);
1841 int smb_vfs_call_chown(struct vfs_handle_struct
*handle
, const char *path
,
1842 uid_t uid
, gid_t gid
)
1845 return handle
->fns
->chown_fn(handle
, path
, uid
, gid
);
1848 int smb_vfs_call_fchown(struct vfs_handle_struct
*handle
,
1849 struct files_struct
*fsp
, uid_t uid
, gid_t gid
)
1852 return handle
->fns
->fchown_fn(handle
, fsp
, uid
, gid
);
1855 int smb_vfs_call_lchown(struct vfs_handle_struct
*handle
, const char *path
,
1856 uid_t uid
, gid_t gid
)
1859 return handle
->fns
->lchown_fn(handle
, path
, uid
, gid
);
1862 NTSTATUS
vfs_chown_fsp(files_struct
*fsp
, uid_t uid
, gid_t gid
)
1865 bool as_root
= false;
1867 char *saved_dir
= NULL
;
1868 char *parent_dir
= NULL
;
1871 if (fsp
->fh
->fd
!= -1) {
1873 ret
= SMB_VFS_FCHOWN(fsp
, uid
, gid
);
1875 return NT_STATUS_OK
;
1877 if (ret
== -1 && errno
!= ENOSYS
) {
1878 return map_nt_error_from_unix(errno
);
1882 as_root
= (geteuid() == 0);
1886 * We are being asked to chown as root. Make
1887 * sure we chdir() into the path to pin it,
1888 * and always act using lchown to ensure we
1889 * don't deref any symbolic links.
1891 const char *final_component
= NULL
;
1892 struct smb_filename local_fname
;
1894 saved_dir
= vfs_GetWd(talloc_tos(),fsp
->conn
);
1896 status
= map_nt_error_from_unix(errno
);
1897 DEBUG(0,("vfs_chown_fsp: failed to get "
1898 "current working directory. Error was %s\n",
1903 if (!parent_dirname(talloc_tos(),
1904 fsp
->fsp_name
->base_name
,
1906 &final_component
)) {
1907 return NT_STATUS_NO_MEMORY
;
1910 /* cd into the parent dir to pin it. */
1911 ret
= vfs_ChDir(fsp
->conn
, parent_dir
);
1913 return map_nt_error_from_unix(errno
);
1916 ZERO_STRUCT(local_fname
);
1917 local_fname
.base_name
= discard_const_p(char, final_component
);
1919 /* Must use lstat here. */
1920 ret
= SMB_VFS_LSTAT(fsp
->conn
, &local_fname
);
1922 status
= map_nt_error_from_unix(errno
);
1926 /* Ensure it matches the fsp stat. */
1927 if (!check_same_stat(&local_fname
.st
, &fsp
->fsp_name
->st
)) {
1928 status
= NT_STATUS_ACCESS_DENIED
;
1931 path
= final_component
;
1933 path
= fsp
->fsp_name
->base_name
;
1936 if (fsp
->posix_open
|| as_root
) {
1937 ret
= SMB_VFS_LCHOWN(fsp
->conn
,
1941 ret
= SMB_VFS_CHOWN(fsp
->conn
,
1947 status
= NT_STATUS_OK
;
1949 status
= map_nt_error_from_unix(errno
);
1955 vfs_ChDir(fsp
->conn
,saved_dir
);
1956 TALLOC_FREE(saved_dir
);
1957 TALLOC_FREE(parent_dir
);
1962 int smb_vfs_call_chdir(struct vfs_handle_struct
*handle
, const char *path
)
1965 return handle
->fns
->chdir_fn(handle
, path
);
1968 char *smb_vfs_call_getwd(struct vfs_handle_struct
*handle
)
1971 return handle
->fns
->getwd_fn(handle
);
1974 int smb_vfs_call_ntimes(struct vfs_handle_struct
*handle
,
1975 const struct smb_filename
*smb_fname
,
1976 struct smb_file_time
*ft
)
1979 return handle
->fns
->ntimes_fn(handle
, smb_fname
, ft
);
1982 int smb_vfs_call_ftruncate(struct vfs_handle_struct
*handle
,
1983 struct files_struct
*fsp
, off_t offset
)
1985 VFS_FIND(ftruncate
);
1986 return handle
->fns
->ftruncate_fn(handle
, fsp
, offset
);
1989 int smb_vfs_call_fallocate(struct vfs_handle_struct
*handle
,
1990 struct files_struct
*fsp
,
1991 enum vfs_fallocate_mode mode
,
1995 VFS_FIND(fallocate
);
1996 return handle
->fns
->fallocate_fn(handle
, fsp
, mode
, offset
, len
);
1999 int smb_vfs_call_kernel_flock(struct vfs_handle_struct
*handle
,
2000 struct files_struct
*fsp
, uint32 share_mode
,
2001 uint32_t access_mask
)
2003 VFS_FIND(kernel_flock
);
2004 return handle
->fns
->kernel_flock_fn(handle
, fsp
, share_mode
,
2008 int smb_vfs_call_linux_setlease(struct vfs_handle_struct
*handle
,
2009 struct files_struct
*fsp
, int leasetype
)
2011 VFS_FIND(linux_setlease
);
2012 return handle
->fns
->linux_setlease_fn(handle
, fsp
, leasetype
);
2015 int smb_vfs_call_symlink(struct vfs_handle_struct
*handle
, const char *oldpath
,
2016 const char *newpath
)
2019 return handle
->fns
->symlink_fn(handle
, oldpath
, newpath
);
2022 int smb_vfs_call_readlink(struct vfs_handle_struct
*handle
,
2023 const char *path
, char *buf
, size_t bufsiz
)
2026 return handle
->fns
->readlink_fn(handle
, path
, buf
, bufsiz
);
2029 int smb_vfs_call_link(struct vfs_handle_struct
*handle
, const char *oldpath
,
2030 const char *newpath
)
2033 return handle
->fns
->link_fn(handle
, oldpath
, newpath
);
2036 int smb_vfs_call_mknod(struct vfs_handle_struct
*handle
, const char *path
,
2037 mode_t mode
, SMB_DEV_T dev
)
2040 return handle
->fns
->mknod_fn(handle
, path
, mode
, dev
);
2043 char *smb_vfs_call_realpath(struct vfs_handle_struct
*handle
, const char *path
)
2046 return handle
->fns
->realpath_fn(handle
, path
);
2049 NTSTATUS
smb_vfs_call_notify_watch(struct vfs_handle_struct
*handle
,
2050 struct sys_notify_context
*ctx
,
2053 uint32_t *subdir_filter
,
2054 void (*callback
)(struct sys_notify_context
*ctx
,
2056 struct notify_event
*ev
),
2057 void *private_data
, void *handle_p
)
2059 VFS_FIND(notify_watch
);
2060 return handle
->fns
->notify_watch_fn(handle
, ctx
, path
,
2061 filter
, subdir_filter
, callback
,
2062 private_data
, handle_p
);
2065 int smb_vfs_call_chflags(struct vfs_handle_struct
*handle
, const char *path
,
2069 return handle
->fns
->chflags_fn(handle
, path
, flags
);
2072 struct file_id
smb_vfs_call_file_id_create(struct vfs_handle_struct
*handle
,
2073 const SMB_STRUCT_STAT
*sbuf
)
2075 VFS_FIND(file_id_create
);
2076 return handle
->fns
->file_id_create_fn(handle
, sbuf
);
2079 NTSTATUS
smb_vfs_call_streaminfo(struct vfs_handle_struct
*handle
,
2080 struct files_struct
*fsp
,
2082 TALLOC_CTX
*mem_ctx
,
2083 unsigned int *num_streams
,
2084 struct stream_struct
**streams
)
2086 VFS_FIND(streaminfo
);
2087 return handle
->fns
->streaminfo_fn(handle
, fsp
, fname
, mem_ctx
,
2088 num_streams
, streams
);
2091 int smb_vfs_call_get_real_filename(struct vfs_handle_struct
*handle
,
2092 const char *path
, const char *name
,
2093 TALLOC_CTX
*mem_ctx
, char **found_name
)
2095 VFS_FIND(get_real_filename
);
2096 return handle
->fns
->get_real_filename_fn(handle
, path
, name
, mem_ctx
,
2100 const char *smb_vfs_call_connectpath(struct vfs_handle_struct
*handle
,
2101 const char *filename
)
2103 VFS_FIND(connectpath
);
2104 return handle
->fns
->connectpath_fn(handle
, filename
);
2107 bool smb_vfs_call_strict_lock(struct vfs_handle_struct
*handle
,
2108 struct files_struct
*fsp
,
2109 struct lock_struct
*plock
)
2111 VFS_FIND(strict_lock
);
2112 return handle
->fns
->strict_lock_fn(handle
, fsp
, plock
);
2115 void smb_vfs_call_strict_unlock(struct vfs_handle_struct
*handle
,
2116 struct files_struct
*fsp
,
2117 struct lock_struct
*plock
)
2119 VFS_FIND(strict_unlock
);
2120 handle
->fns
->strict_unlock_fn(handle
, fsp
, plock
);
2123 NTSTATUS
smb_vfs_call_translate_name(struct vfs_handle_struct
*handle
,
2125 enum vfs_translate_direction direction
,
2126 TALLOC_CTX
*mem_ctx
,
2129 VFS_FIND(translate_name
);
2130 return handle
->fns
->translate_name_fn(handle
, name
, direction
, mem_ctx
,
2134 NTSTATUS
smb_vfs_call_fsctl(struct vfs_handle_struct
*handle
,
2135 struct files_struct
*fsp
,
2139 const uint8_t *in_data
,
2142 uint32_t max_out_len
,
2146 return handle
->fns
->fsctl_fn(handle
, fsp
, ctx
, function
, req_flags
,
2147 in_data
, in_len
, out_data
, max_out_len
,
2151 NTSTATUS
smb_vfs_call_fget_nt_acl(struct vfs_handle_struct
*handle
,
2152 struct files_struct
*fsp
,
2153 uint32 security_info
,
2154 struct security_descriptor
**ppdesc
)
2156 VFS_FIND(fget_nt_acl
);
2157 return handle
->fns
->fget_nt_acl_fn(handle
, fsp
, security_info
,
2161 NTSTATUS
smb_vfs_call_get_nt_acl(struct vfs_handle_struct
*handle
,
2163 uint32 security_info
,
2164 struct security_descriptor
**ppdesc
)
2166 VFS_FIND(get_nt_acl
);
2167 return handle
->fns
->get_nt_acl_fn(handle
, name
, security_info
, ppdesc
);
2170 NTSTATUS
smb_vfs_call_fset_nt_acl(struct vfs_handle_struct
*handle
,
2171 struct files_struct
*fsp
,
2172 uint32 security_info_sent
,
2173 const struct security_descriptor
*psd
)
2175 VFS_FIND(fset_nt_acl
);
2176 return handle
->fns
->fset_nt_acl_fn(handle
, fsp
, security_info_sent
,
2180 NTSTATUS
smb_vfs_call_audit_file(struct vfs_handle_struct
*handle
,
2181 struct smb_filename
*file
,
2182 struct security_acl
*sacl
,
2183 uint32_t access_requested
,
2184 uint32_t access_denied
)
2186 VFS_FIND(audit_file
);
2187 return handle
->fns
->audit_file_fn(handle
,
2194 int smb_vfs_call_chmod_acl(struct vfs_handle_struct
*handle
, const char *name
,
2197 VFS_FIND(chmod_acl
);
2198 return handle
->fns
->chmod_acl_fn(handle
, name
, mode
);
2201 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct
*handle
,
2202 struct files_struct
*fsp
, mode_t mode
)
2204 VFS_FIND(fchmod_acl
);
2205 return handle
->fns
->fchmod_acl_fn(handle
, fsp
, mode
);
2208 int smb_vfs_call_sys_acl_get_entry(struct vfs_handle_struct
*handle
,
2209 SMB_ACL_T theacl
, int entry_id
,
2210 SMB_ACL_ENTRY_T
*entry_p
)
2212 VFS_FIND(sys_acl_get_entry
);
2213 return handle
->fns
->sys_acl_get_entry_fn(handle
, theacl
, entry_id
,
2217 int smb_vfs_call_sys_acl_get_tag_type(struct vfs_handle_struct
*handle
,
2218 SMB_ACL_ENTRY_T entry_d
,
2219 SMB_ACL_TAG_T
*tag_type_p
)
2221 VFS_FIND(sys_acl_get_tag_type
);
2222 return handle
->fns
->sys_acl_get_tag_type_fn(handle
, entry_d
,
2226 int smb_vfs_call_sys_acl_get_permset(struct vfs_handle_struct
*handle
,
2227 SMB_ACL_ENTRY_T entry_d
,
2228 SMB_ACL_PERMSET_T
*permset_p
)
2230 VFS_FIND(sys_acl_get_permset
);
2231 return handle
->fns
->sys_acl_get_permset_fn(handle
, entry_d
, permset_p
);
2234 void * smb_vfs_call_sys_acl_get_qualifier(struct vfs_handle_struct
*handle
,
2235 SMB_ACL_ENTRY_T entry_d
)
2237 VFS_FIND(sys_acl_get_qualifier
);
2238 return handle
->fns
->sys_acl_get_qualifier_fn(handle
, entry_d
);
2241 SMB_ACL_T
smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct
*handle
,
2243 SMB_ACL_TYPE_T type
)
2245 VFS_FIND(sys_acl_get_file
);
2246 return handle
->fns
->sys_acl_get_file_fn(handle
, path_p
, type
);
2249 SMB_ACL_T
smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct
*handle
,
2250 struct files_struct
*fsp
)
2252 VFS_FIND(sys_acl_get_fd
);
2253 return handle
->fns
->sys_acl_get_fd_fn(handle
, fsp
);
2256 int smb_vfs_call_sys_acl_clear_perms(struct vfs_handle_struct
*handle
,
2257 SMB_ACL_PERMSET_T permset
)
2259 VFS_FIND(sys_acl_clear_perms
);
2260 return handle
->fns
->sys_acl_clear_perms_fn(handle
, permset
);
2263 int smb_vfs_call_sys_acl_add_perm(struct vfs_handle_struct
*handle
,
2264 SMB_ACL_PERMSET_T permset
,
2265 SMB_ACL_PERM_T perm
)
2267 VFS_FIND(sys_acl_add_perm
);
2268 return handle
->fns
->sys_acl_add_perm_fn(handle
, permset
, perm
);
2271 char * smb_vfs_call_sys_acl_to_text(struct vfs_handle_struct
*handle
,
2272 SMB_ACL_T theacl
, ssize_t
*plen
)
2274 VFS_FIND(sys_acl_to_text
);
2275 return handle
->fns
->sys_acl_to_text_fn(handle
, theacl
, plen
);
2278 SMB_ACL_T
smb_vfs_call_sys_acl_init(struct vfs_handle_struct
*handle
,
2281 VFS_FIND(sys_acl_init
);
2282 return handle
->fns
->sys_acl_init_fn(handle
, count
);
2285 int smb_vfs_call_sys_acl_create_entry(struct vfs_handle_struct
*handle
,
2286 SMB_ACL_T
*pacl
, SMB_ACL_ENTRY_T
*pentry
)
2288 VFS_FIND(sys_acl_create_entry
);
2289 return handle
->fns
->sys_acl_create_entry_fn(handle
, pacl
, pentry
);
2292 int smb_vfs_call_sys_acl_set_tag_type(struct vfs_handle_struct
*handle
,
2293 SMB_ACL_ENTRY_T entry
,
2294 SMB_ACL_TAG_T tagtype
)
2296 VFS_FIND(sys_acl_set_tag_type
);
2297 return handle
->fns
->sys_acl_set_tag_type_fn(handle
, entry
, tagtype
);
2300 int smb_vfs_call_sys_acl_set_qualifier(struct vfs_handle_struct
*handle
,
2301 SMB_ACL_ENTRY_T entry
, void *qual
)
2303 VFS_FIND(sys_acl_set_qualifier
);
2304 return handle
->fns
->sys_acl_set_qualifier_fn(handle
, entry
, qual
);
2307 int smb_vfs_call_sys_acl_set_permset(struct vfs_handle_struct
*handle
,
2308 SMB_ACL_ENTRY_T entry
,
2309 SMB_ACL_PERMSET_T permset
)
2311 VFS_FIND(sys_acl_set_permset
);
2312 return handle
->fns
->sys_acl_set_permset_fn(handle
, entry
, permset
);
2315 int smb_vfs_call_sys_acl_valid(struct vfs_handle_struct
*handle
,
2318 VFS_FIND(sys_acl_valid
);
2319 return handle
->fns
->sys_acl_valid_fn(handle
, theacl
);
2322 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct
*handle
,
2323 const char *name
, SMB_ACL_TYPE_T acltype
,
2326 VFS_FIND(sys_acl_set_file
);
2327 return handle
->fns
->sys_acl_set_file_fn(handle
, name
, acltype
, theacl
);
2330 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct
*handle
,
2331 struct files_struct
*fsp
, SMB_ACL_T theacl
)
2333 VFS_FIND(sys_acl_set_fd
);
2334 return handle
->fns
->sys_acl_set_fd_fn(handle
, fsp
, theacl
);
2337 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct
*handle
,
2340 VFS_FIND(sys_acl_delete_def_file
);
2341 return handle
->fns
->sys_acl_delete_def_file_fn(handle
, path
);
2344 int smb_vfs_call_sys_acl_get_perm(struct vfs_handle_struct
*handle
,
2345 SMB_ACL_PERMSET_T permset
,
2346 SMB_ACL_PERM_T perm
)
2348 VFS_FIND(sys_acl_get_perm
);
2349 return handle
->fns
->sys_acl_get_perm_fn(handle
, permset
, perm
);
2352 int smb_vfs_call_sys_acl_free_text(struct vfs_handle_struct
*handle
,
2355 VFS_FIND(sys_acl_free_text
);
2356 return handle
->fns
->sys_acl_free_text_fn(handle
, text
);
2359 int smb_vfs_call_sys_acl_free_acl(struct vfs_handle_struct
*handle
,
2360 SMB_ACL_T posix_acl
)
2362 VFS_FIND(sys_acl_free_acl
);
2363 return handle
->fns
->sys_acl_free_acl_fn(handle
, posix_acl
);
2366 int smb_vfs_call_sys_acl_free_qualifier(struct vfs_handle_struct
*handle
,
2367 void *qualifier
, SMB_ACL_TAG_T tagtype
)
2369 VFS_FIND(sys_acl_free_qualifier
);
2370 return handle
->fns
->sys_acl_free_qualifier_fn(handle
, qualifier
,
2374 ssize_t
smb_vfs_call_getxattr(struct vfs_handle_struct
*handle
,
2375 const char *path
, const char *name
, void *value
,
2379 return handle
->fns
->getxattr_fn(handle
, path
, name
, value
, size
);
2382 ssize_t
smb_vfs_call_fgetxattr(struct vfs_handle_struct
*handle
,
2383 struct files_struct
*fsp
, const char *name
,
2384 void *value
, size_t size
)
2386 VFS_FIND(fgetxattr
);
2387 return handle
->fns
->fgetxattr_fn(handle
, fsp
, name
, value
, size
);
2390 ssize_t
smb_vfs_call_listxattr(struct vfs_handle_struct
*handle
,
2391 const char *path
, char *list
, size_t size
)
2393 VFS_FIND(listxattr
);
2394 return handle
->fns
->listxattr_fn(handle
, path
, list
, size
);
2397 ssize_t
smb_vfs_call_flistxattr(struct vfs_handle_struct
*handle
,
2398 struct files_struct
*fsp
, char *list
,
2401 VFS_FIND(flistxattr
);
2402 return handle
->fns
->flistxattr_fn(handle
, fsp
, list
, size
);
2405 int smb_vfs_call_removexattr(struct vfs_handle_struct
*handle
,
2406 const char *path
, const char *name
)
2408 VFS_FIND(removexattr
);
2409 return handle
->fns
->removexattr_fn(handle
, path
, name
);
2412 int smb_vfs_call_fremovexattr(struct vfs_handle_struct
*handle
,
2413 struct files_struct
*fsp
, const char *name
)
2415 VFS_FIND(fremovexattr
);
2416 return handle
->fns
->fremovexattr_fn(handle
, fsp
, name
);
2419 int smb_vfs_call_setxattr(struct vfs_handle_struct
*handle
, const char *path
,
2420 const char *name
, const void *value
, size_t size
,
2424 return handle
->fns
->setxattr_fn(handle
, path
, name
, value
, size
, flags
);
2427 int smb_vfs_call_fsetxattr(struct vfs_handle_struct
*handle
,
2428 struct files_struct
*fsp
, const char *name
,
2429 const void *value
, size_t size
, int flags
)
2431 VFS_FIND(fsetxattr
);
2432 return handle
->fns
->fsetxattr_fn(handle
, fsp
, name
, value
, size
, flags
);
2435 bool smb_vfs_call_aio_force(struct vfs_handle_struct
*handle
,
2436 struct files_struct
*fsp
)
2438 VFS_FIND(aio_force
);
2439 return handle
->fns
->aio_force_fn(handle
, fsp
);
2442 bool smb_vfs_call_is_offline(struct vfs_handle_struct
*handle
,
2443 const struct smb_filename
*fname
,
2444 SMB_STRUCT_STAT
*sbuf
)
2446 VFS_FIND(is_offline
);
2447 return handle
->fns
->is_offline_fn(handle
, fname
, sbuf
);
2450 int smb_vfs_call_set_offline(struct vfs_handle_struct
*handle
,
2451 const struct smb_filename
*fname
)
2453 VFS_FIND(set_offline
);
2454 return handle
->fns
->set_offline_fn(handle
, fname
);