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"
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_t *)(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
);
332 /* No need to load vfs modules for printer connections */
337 vfs_objects
= lp_vfs_objects(SNUM(conn
));
339 /* Override VFS functions if 'vfs object' was not specified*/
340 if (!vfs_objects
|| !vfs_objects
[0])
343 for (i
=0; vfs_objects
[i
] ;) {
347 for (j
=i
-1; j
>= 0; j
--) {
348 if (!vfs_init_custom(conn
, vfs_objects
[j
])) {
349 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects
[j
]));
356 /*******************************************************************
357 Check if a file exists in the vfs.
358 ********************************************************************/
360 NTSTATUS
vfs_file_exist(connection_struct
*conn
, struct smb_filename
*smb_fname
)
362 /* Only return OK if stat was successful and S_ISREG */
363 if ((SMB_VFS_STAT(conn
, smb_fname
) != -1) &&
364 S_ISREG(smb_fname
->st
.st_ex_mode
)) {
368 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
371 /****************************************************************************
372 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
373 ****************************************************************************/
375 ssize_t
vfs_read_data(files_struct
*fsp
, char *buf
, size_t byte_count
)
379 while (total
< byte_count
)
381 ssize_t ret
= SMB_VFS_READ(fsp
, buf
+ total
,
384 if (ret
== 0) return total
;
393 return (ssize_t
)total
;
396 /****************************************************************************
397 Write data to a fd on the vfs.
398 ****************************************************************************/
400 ssize_t
vfs_write_data(struct smb_request
*req
,
408 if (req
&& req
->unread_bytes
) {
409 int sockfd
= req
->xconn
->transport
.sock
;
411 SMB_ASSERT(req
->unread_bytes
== N
);
412 /* VFS_RECVFILE must drain the socket
413 * before returning. */
414 req
->unread_bytes
= 0;
415 /* Ensure the socket is blocking. */
416 old_flags
= fcntl(sockfd
, F_GETFL
, 0);
417 if (set_blocking(sockfd
, true) == -1) {
420 ret
= SMB_VFS_RECVFILE(sockfd
,
424 if (fcntl(sockfd
, F_SETFL
, old_flags
) == -1) {
431 ret
= SMB_VFS_WRITE(fsp
, buffer
+ total
, N
- total
);
440 return (ssize_t
)total
;
443 ssize_t
vfs_pwrite_data(struct smb_request
*req
,
452 if (req
&& req
->unread_bytes
) {
453 int sockfd
= req
->xconn
->transport
.sock
;
454 SMB_ASSERT(req
->unread_bytes
== N
);
455 /* VFS_RECVFILE must drain the socket
456 * before returning. */
457 req
->unread_bytes
= 0;
459 * Leave the socket non-blocking and
460 * use SMB_VFS_RECVFILE. If it returns
461 * EAGAIN || EWOULDBLOCK temporarily set
462 * the socket blocking and retry
466 ret
= SMB_VFS_RECVFILE(sockfd
,
470 if (ret
== 0 || (ret
== -1 &&
472 errno
== EWOULDBLOCK
))) {
474 /* Ensure the socket is blocking. */
475 old_flags
= fcntl(sockfd
, F_GETFL
, 0);
476 if (set_blocking(sockfd
, true) == -1) {
479 ret
= SMB_VFS_RECVFILE(sockfd
,
483 if (fcntl(sockfd
, F_SETFL
, old_flags
) == -1) {
490 return (ssize_t
)total
;
492 /* Any other error case. */
498 return (ssize_t
)total
;
502 ret
= SMB_VFS_PWRITE(fsp
, buffer
+ total
, N
- total
,
512 return (ssize_t
)total
;
514 /****************************************************************************
515 An allocate file space call using the vfs interface.
516 Allocates space for a file from a filedescriptor.
517 Returns 0 on success, -1 on failure.
518 ****************************************************************************/
520 int vfs_allocate_file_space(files_struct
*fsp
, uint64_t len
)
523 connection_struct
*conn
= fsp
->conn
;
524 uint64_t space_avail
;
525 uint64_t bsize
,dfree
,dsize
;
529 * Actually try and commit the space on disk....
532 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
533 fsp_str_dbg(fsp
), (double)len
));
535 if (((off_t
)len
) < 0) {
536 DEBUG(0,("vfs_allocate_file_space: %s negative len "
537 "requested.\n", fsp_str_dbg(fsp
)));
542 status
= vfs_stat_fsp(fsp
);
543 if (!NT_STATUS_IS_OK(status
)) {
547 if (len
== (uint64_t)fsp
->fsp_name
->st
.st_ex_size
)
550 if (len
< (uint64_t)fsp
->fsp_name
->st
.st_ex_size
) {
551 /* Shrink - use ftruncate. */
553 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
554 "size %.0f\n", fsp_str_dbg(fsp
),
555 (double)fsp
->fsp_name
->st
.st_ex_size
));
557 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_ALLOC_SHRINK
);
559 flush_write_cache(fsp
, SAMBA_SIZECHANGE_FLUSH
);
560 if ((ret
= SMB_VFS_FTRUNCATE(fsp
, (off_t
)len
)) != -1) {
561 set_filelen_write_cache(fsp
, len
);
564 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_ALLOC_SHRINK
);
569 /* Grow - we need to test if we have enough space. */
571 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_ALLOC_GROW
);
573 if (lp_strict_allocate(SNUM(fsp
->conn
))) {
574 /* See if we have a syscall that will allocate beyond
575 end-of-file without changing EOF. */
576 ret
= SMB_VFS_FALLOCATE(fsp
, VFS_FALLOCATE_FL_KEEP_SIZE
,
582 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_ALLOC_GROW
);
585 /* We changed the allocation size on disk, but not
586 EOF - exactly as required. We're done ! */
590 if (ret
== -1 && errno
== ENOSPC
) {
594 len
-= fsp
->fsp_name
->st
.st_ex_size
;
595 len
/= 1024; /* Len is now number of 1k blocks needed. */
596 space_avail
= get_dfree_info(conn
, fsp
->fsp_name
->base_name
,
597 &bsize
, &dfree
, &dsize
);
598 if (space_avail
== (uint64_t)-1) {
602 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
603 "needed blocks = %.0f, space avail = %.0f\n",
604 fsp_str_dbg(fsp
), (double)fsp
->fsp_name
->st
.st_ex_size
, (double)len
,
605 (double)space_avail
));
607 if (len
> space_avail
) {
615 /****************************************************************************
616 A vfs set_filelen call.
617 set the length of a file from a filedescriptor.
618 Returns 0 on success, -1 on failure.
619 ****************************************************************************/
621 int vfs_set_filelen(files_struct
*fsp
, off_t len
)
625 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_SET_FILE_LEN
);
627 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
628 fsp_str_dbg(fsp
), (double)len
));
629 flush_write_cache(fsp
, SAMBA_SIZECHANGE_FLUSH
);
630 if ((ret
= SMB_VFS_FTRUNCATE(fsp
, len
)) != -1) {
631 set_filelen_write_cache(fsp
, len
);
632 notify_fname(fsp
->conn
, NOTIFY_ACTION_MODIFIED
,
633 FILE_NOTIFY_CHANGE_SIZE
634 | FILE_NOTIFY_CHANGE_ATTRIBUTES
,
635 fsp
->fsp_name
->base_name
);
638 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_SET_FILE_LEN
);
643 /****************************************************************************
644 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
645 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
646 as this is also called from the default SMB_VFS_FTRUNCATE code.
647 Always extends the file size.
648 Returns 0 on success, -1 on failure.
649 ****************************************************************************/
651 #define SPARSE_BUF_WRITE_SIZE (32*1024)
653 int vfs_slow_fallocate(files_struct
*fsp
, off_t offset
, off_t len
)
659 sparse_buf
= SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE
);
666 while (total
< len
) {
667 size_t curr_write_size
= MIN(SPARSE_BUF_WRITE_SIZE
, (len
- total
));
669 pwrite_ret
= SMB_VFS_PWRITE(fsp
, sparse_buf
, curr_write_size
, offset
+ total
);
670 if (pwrite_ret
== -1) {
671 int saved_errno
= errno
;
672 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
673 "%s failed with error %s\n",
674 fsp_str_dbg(fsp
), strerror(saved_errno
)));
684 /****************************************************************************
685 A vfs fill sparse call.
686 Writes zeros from the end of file to len, if len is greater than EOF.
687 Used only by strict_sync.
688 Returns 0 on success, -1 on failure.
689 ****************************************************************************/
691 int vfs_fill_sparse(files_struct
*fsp
, off_t len
)
698 status
= vfs_stat_fsp(fsp
);
699 if (!NT_STATUS_IS_OK(status
)) {
703 if (len
<= fsp
->fsp_name
->st
.st_ex_size
) {
708 if (S_ISFIFO(fsp
->fsp_name
->st
.st_ex_mode
)) {
713 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
714 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp
),
715 (double)fsp
->fsp_name
->st
.st_ex_size
, (double)len
,
716 (double)(len
- fsp
->fsp_name
->st
.st_ex_size
)));
718 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_FILL_SPARSE
);
720 flush_write_cache(fsp
, SAMBA_SIZECHANGE_FLUSH
);
722 offset
= fsp
->fsp_name
->st
.st_ex_size
;
723 num_to_write
= len
- fsp
->fsp_name
->st
.st_ex_size
;
725 /* Only do this on non-stream file handles. */
726 if (fsp
->base_fsp
== NULL
) {
727 /* for allocation try fallocate first. This can fail on some
728 * platforms e.g. when the filesystem doesn't support it and no
729 * emulation is being done by the libc (like on AIX with JFS1). In that
730 * case we do our own emulation. fallocate implementations can
731 * return ENOTSUP or EINVAL in cases like that. */
732 ret
= SMB_VFS_FALLOCATE(fsp
, 0, offset
, num_to_write
);
733 if (ret
== -1 && errno
== ENOSPC
) {
739 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
740 "error %d. Falling back to slow manual allocation\n", ret
));
743 ret
= vfs_slow_fallocate(fsp
, offset
, num_to_write
);
748 set_filelen_write_cache(fsp
, len
);
751 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_FILL_SPARSE
);
755 /****************************************************************************
756 Transfer some data (n bytes) between two file_struct's.
757 ****************************************************************************/
759 static ssize_t
vfs_pread_fn(void *file
, void *buf
, size_t len
, off_t offset
)
761 struct files_struct
*fsp
= (struct files_struct
*)file
;
763 return SMB_VFS_PREAD(fsp
, buf
, len
, offset
);
766 static ssize_t
vfs_pwrite_fn(void *file
, const void *buf
, size_t len
, off_t offset
)
768 struct files_struct
*fsp
= (struct files_struct
*)file
;
770 return SMB_VFS_PWRITE(fsp
, buf
, len
, offset
);
773 off_t
vfs_transfer_file(files_struct
*in
, files_struct
*out
, off_t n
)
775 return transfer_file_internal((void *)in
, (void *)out
, n
,
776 vfs_pread_fn
, vfs_pwrite_fn
);
779 /*******************************************************************
780 A vfs_readdir wrapper which just returns the file name.
781 ********************************************************************/
783 const char *vfs_readdirname(connection_struct
*conn
, void *p
,
784 SMB_STRUCT_STAT
*sbuf
, char **talloced
)
786 struct dirent
*ptr
= NULL
;
794 ptr
= SMB_VFS_READDIR(conn
, (DIR *)p
, sbuf
);
806 #ifdef HAVE_BROKEN_READDIR_NAME
807 /* using /usr/ucb/cc is BAD */
811 status
= SMB_VFS_TRANSLATE_NAME(conn
, dname
, vfs_translate_to_windows
,
812 talloc_tos(), &translated
);
813 if (NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
817 *talloced
= translated
;
818 if (!NT_STATUS_IS_OK(status
)) {
824 /*******************************************************************
825 A wrapper for vfs_chdir().
826 ********************************************************************/
828 int vfs_ChDir(connection_struct
*conn
, const char *path
)
833 LastDir
= SMB_STRDUP("");
840 if (*path
== '/' && strcsequal(LastDir
,path
)) {
844 DEBUG(4,("vfs_ChDir to %s\n",path
));
846 ret
= SMB_VFS_CHDIR(conn
,path
);
850 LastDir
= SMB_STRDUP(path
);
853 TALLOC_FREE(conn
->cwd
);
854 conn
->cwd
= vfs_GetWd(conn
, conn
);
855 DEBUG(4,("vfs_ChDir got %s\n",conn
->cwd
));
860 /*******************************************************************
861 Return the absolute current directory path - given a UNIX pathname.
862 Note that this path is returned in DOS format, not UNIX
863 format. Note this can be called with conn == NULL.
864 ********************************************************************/
866 char *vfs_GetWd(TALLOC_CTX
*ctx
, connection_struct
*conn
)
868 char *current_dir
= NULL
;
870 DATA_BLOB cache_value
;
872 struct smb_filename
*smb_fname_dot
= NULL
;
873 struct smb_filename
*smb_fname_full
= NULL
;
875 if (!lp_getwd_cache()) {
879 smb_fname_dot
= synthetic_smb_fname(ctx
, ".", NULL
, NULL
);
880 if (smb_fname_dot
== NULL
) {
885 if (SMB_VFS_STAT(conn
, smb_fname_dot
) == -1) {
887 * Known to fail for root: the directory may be NFS-mounted
888 * and exported with root_squash (so has no root access).
890 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
891 "(NFS problem ?)\n", strerror(errno
) ));
895 key
= vfs_file_id_from_sbuf(conn
, &smb_fname_dot
->st
);
897 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE
,
898 data_blob_const(&key
, sizeof(key
)),
903 SMB_ASSERT((cache_value
.length
> 0)
904 && (cache_value
.data
[cache_value
.length
-1] == '\0'));
906 smb_fname_full
= synthetic_smb_fname(ctx
, (char *)cache_value
.data
,
908 if (smb_fname_full
== NULL
) {
913 if ((SMB_VFS_STAT(conn
, smb_fname_full
) == 0) &&
914 (smb_fname_dot
->st
.st_ex_dev
== smb_fname_full
->st
.st_ex_dev
) &&
915 (smb_fname_dot
->st
.st_ex_ino
== smb_fname_full
->st
.st_ex_ino
) &&
916 (S_ISDIR(smb_fname_dot
->st
.st_ex_mode
))) {
920 result
= talloc_strdup(ctx
, smb_fname_full
->base_name
);
921 if (result
== NULL
) {
930 * We don't have the information to hand so rely on traditional
931 * methods. The very slow getcwd, which spawns a process on some
932 * systems, or the not quite so bad getwd.
935 current_dir
= SMB_VFS_GETWD(conn
);
936 if (current_dir
== NULL
) {
937 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
942 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot
->st
)) {
943 key
= vfs_file_id_from_sbuf(conn
, &smb_fname_dot
->st
);
945 memcache_add(smbd_memcache(), GETWD_CACHE
,
946 data_blob_const(&key
, sizeof(key
)),
947 data_blob_const(current_dir
,
948 strlen(current_dir
)+1));
951 result
= talloc_strdup(ctx
, current_dir
);
952 if (result
== NULL
) {
957 TALLOC_FREE(smb_fname_dot
);
958 TALLOC_FREE(smb_fname_full
);
959 SAFE_FREE(current_dir
);
963 /*******************************************************************
964 Reduce a file name, removing .. elements and checking that
965 it is below dir in the heirachy. This uses realpath.
966 This function must run as root, and will return names
967 and valid stat structs that can be checked on open.
968 ********************************************************************/
970 NTSTATUS
check_reduced_name_with_privilege(connection_struct
*conn
,
972 struct smb_request
*smbreq
)
975 TALLOC_CTX
*ctx
= talloc_tos();
976 const char *conn_rootdir
;
978 char *dir_name
= NULL
;
979 const char *last_component
= NULL
;
980 char *resolved_name
= NULL
;
981 char *saved_dir
= NULL
;
982 struct smb_filename
*smb_fname_cwd
= NULL
;
983 struct privilege_paths
*priv_paths
= NULL
;
986 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
991 priv_paths
= talloc_zero(smbreq
, struct privilege_paths
);
993 status
= NT_STATUS_NO_MEMORY
;
997 if (!parent_dirname(ctx
, fname
, &dir_name
, &last_component
)) {
998 status
= NT_STATUS_NO_MEMORY
;
1002 priv_paths
->parent_name
.base_name
= talloc_strdup(priv_paths
, dir_name
);
1003 priv_paths
->file_name
.base_name
= talloc_strdup(priv_paths
, last_component
);
1005 if (priv_paths
->parent_name
.base_name
== NULL
||
1006 priv_paths
->file_name
.base_name
== NULL
) {
1007 status
= NT_STATUS_NO_MEMORY
;
1011 if (SMB_VFS_STAT(conn
, &priv_paths
->parent_name
) != 0) {
1012 status
= map_nt_error_from_unix(errno
);
1015 /* Remember where we were. */
1016 saved_dir
= vfs_GetWd(ctx
, conn
);
1018 status
= map_nt_error_from_unix(errno
);
1022 /* Go to the parent directory to lock in memory. */
1023 if (vfs_ChDir(conn
, priv_paths
->parent_name
.base_name
) == -1) {
1024 status
= map_nt_error_from_unix(errno
);
1028 /* Get the absolute path of the parent directory. */
1029 resolved_name
= SMB_VFS_REALPATH(conn
,".");
1030 if (!resolved_name
) {
1031 status
= map_nt_error_from_unix(errno
);
1035 if (*resolved_name
!= '/') {
1036 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1037 "doesn't return absolute paths !\n"));
1038 status
= NT_STATUS_OBJECT_NAME_INVALID
;
1042 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1043 priv_paths
->parent_name
.base_name
,
1046 /* Now check the stat value is the same. */
1047 smb_fname_cwd
= synthetic_smb_fname(talloc_tos(), ".", NULL
, NULL
);
1048 if (smb_fname_cwd
== NULL
) {
1049 status
= NT_STATUS_NO_MEMORY
;
1053 if (SMB_VFS_LSTAT(conn
, smb_fname_cwd
) != 0) {
1054 status
= map_nt_error_from_unix(errno
);
1058 /* Ensure we're pointing at the same place. */
1059 if (!check_same_stat(&smb_fname_cwd
->st
, &priv_paths
->parent_name
.st
)) {
1060 DEBUG(0,("check_reduced_name_with_privilege: "
1061 "device/inode/uid/gid on directory %s changed. "
1062 "Denying access !\n",
1063 priv_paths
->parent_name
.base_name
));
1064 status
= NT_STATUS_ACCESS_DENIED
;
1068 /* Ensure we're below the connect path. */
1070 conn_rootdir
= SMB_VFS_CONNECTPATH(conn
, fname
);
1071 if (conn_rootdir
== NULL
) {
1072 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1074 status
= NT_STATUS_ACCESS_DENIED
;
1078 rootdir_len
= strlen(conn_rootdir
);
1079 if (strncmp(conn_rootdir
, resolved_name
, rootdir_len
) != 0) {
1080 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1081 "attempt: %s is a symlink outside the "
1084 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir
));
1085 DEBUGADD(2, ("resolved_name=%s\n", resolved_name
));
1086 status
= NT_STATUS_ACCESS_DENIED
;
1090 /* Now ensure that the last component either doesn't
1091 exist, or is *NOT* a symlink. */
1093 ret
= SMB_VFS_LSTAT(conn
, &priv_paths
->file_name
);
1095 /* Errno must be ENOENT for this be ok. */
1096 if (errno
!= ENOENT
) {
1097 status
= map_nt_error_from_unix(errno
);
1098 DEBUG(2, ("check_reduced_name_with_privilege: "
1099 "LSTAT on %s failed with %s\n",
1100 priv_paths
->file_name
.base_name
,
1101 nt_errstr(status
)));
1106 if (VALID_STAT(priv_paths
->file_name
.st
) &&
1107 S_ISLNK(priv_paths
->file_name
.st
.st_ex_mode
)) {
1108 DEBUG(2, ("check_reduced_name_with_privilege: "
1109 "Last component %s is a symlink. Denying"
1111 priv_paths
->file_name
.base_name
));
1112 status
= NT_STATUS_ACCESS_DENIED
;
1116 smbreq
->priv_paths
= priv_paths
;
1117 status
= NT_STATUS_OK
;
1122 vfs_ChDir(conn
, saved_dir
);
1124 SAFE_FREE(resolved_name
);
1125 if (!NT_STATUS_IS_OK(status
)) {
1126 TALLOC_FREE(priv_paths
);
1128 TALLOC_FREE(dir_name
);
1132 /*******************************************************************
1133 Reduce a file name, removing .. elements and checking that
1134 it is below dir in the heirachy. This uses realpath.
1135 ********************************************************************/
1137 NTSTATUS
check_reduced_name(connection_struct
*conn
, const char *fname
)
1139 char *resolved_name
= NULL
;
1140 bool allow_symlinks
= true;
1141 bool allow_widelinks
= false;
1143 DBG_DEBUG("check_reduced_name [%s] [%s]\n", fname
, conn
->connectpath
);
1145 resolved_name
= SMB_VFS_REALPATH(conn
,fname
);
1147 if (!resolved_name
) {
1150 DEBUG(3,("check_reduced_name: Component not a "
1151 "directory in getting realpath for "
1153 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1156 TALLOC_CTX
*ctx
= talloc_tos();
1157 char *dir_name
= NULL
;
1158 const char *last_component
= NULL
;
1159 char *new_name
= NULL
;
1162 /* Last component didn't exist.
1163 Remove it and try and canonicalise
1164 the directory name. */
1165 if (!parent_dirname(ctx
, fname
,
1168 return NT_STATUS_NO_MEMORY
;
1171 resolved_name
= SMB_VFS_REALPATH(conn
,dir_name
);
1172 if (!resolved_name
) {
1173 NTSTATUS status
= map_nt_error_from_unix(errno
);
1175 if (errno
== ENOENT
|| errno
== ENOTDIR
) {
1176 status
= NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1179 DEBUG(3,("check_reduce_name: "
1180 "couldn't get realpath for "
1183 nt_errstr(status
)));
1186 ret
= asprintf(&new_name
, "%s/%s",
1187 resolved_name
, last_component
);
1188 SAFE_FREE(resolved_name
);
1190 return NT_STATUS_NO_MEMORY
;
1192 resolved_name
= new_name
;
1196 DEBUG(3,("check_reduced_name: couldn't get "
1197 "realpath for %s\n", fname
));
1198 return map_nt_error_from_unix(errno
);
1202 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname
,
1205 if (*resolved_name
!= '/') {
1206 DEBUG(0,("check_reduced_name: realpath doesn't return "
1207 "absolute paths !\n"));
1208 SAFE_FREE(resolved_name
);
1209 return NT_STATUS_OBJECT_NAME_INVALID
;
1212 allow_widelinks
= lp_widelinks(SNUM(conn
));
1213 allow_symlinks
= lp_follow_symlinks(SNUM(conn
));
1215 /* Common widelinks and symlinks checks. */
1216 if (!allow_widelinks
|| !allow_symlinks
) {
1217 const char *conn_rootdir
;
1220 conn_rootdir
= SMB_VFS_CONNECTPATH(conn
, fname
);
1221 if (conn_rootdir
== NULL
) {
1222 DEBUG(2, ("check_reduced_name: Could not get "
1224 SAFE_FREE(resolved_name
);
1225 return NT_STATUS_ACCESS_DENIED
;
1228 rootdir_len
= strlen(conn_rootdir
);
1229 if (strncmp(conn_rootdir
, resolved_name
,
1230 rootdir_len
) != 0) {
1231 DEBUG(2, ("check_reduced_name: Bad access "
1232 "attempt: %s is a symlink outside the "
1233 "share path\n", fname
));
1234 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir
));
1235 DEBUGADD(2, ("resolved_name=%s\n", resolved_name
));
1236 SAFE_FREE(resolved_name
);
1237 return NT_STATUS_ACCESS_DENIED
;
1240 /* Extra checks if all symlinks are disallowed. */
1241 if (!allow_symlinks
) {
1242 /* fname can't have changed in resolved_path. */
1243 const char *p
= &resolved_name
[rootdir_len
];
1245 /* *p can be '\0' if fname was "." */
1246 if (*p
== '\0' && ISDOT(fname
)) {
1251 DEBUG(2, ("check_reduced_name: logic error (%c) "
1252 "in resolved_name: %s\n",
1255 SAFE_FREE(resolved_name
);
1256 return NT_STATUS_ACCESS_DENIED
;
1260 if (strcmp(fname
, p
)!=0) {
1261 DEBUG(2, ("check_reduced_name: Bad access "
1262 "attempt: %s is a symlink to %s\n",
1264 SAFE_FREE(resolved_name
);
1265 return NT_STATUS_ACCESS_DENIED
;
1272 DBG_INFO("%s reduced to %s\n", fname
, resolved_name
);
1273 SAFE_FREE(resolved_name
);
1274 return NT_STATUS_OK
;
1278 * XXX: This is temporary and there should be no callers of this once
1279 * smb_filename is plumbed through all path based operations.
1281 * Called when we know stream name parsing has already been done.
1283 int vfs_stat_smb_basename(struct connection_struct
*conn
, const char *fname
,
1284 SMB_STRUCT_STAT
*psbuf
)
1286 struct smb_filename smb_fname
= {
1287 .base_name
= discard_const_p(char, fname
)
1291 if (lp_posix_pathnames()) {
1292 ret
= SMB_VFS_LSTAT(conn
, &smb_fname
);
1294 ret
= SMB_VFS_STAT(conn
, &smb_fname
);
1298 *psbuf
= smb_fname
.st
;
1304 * Ensure LSTAT is called for POSIX paths.
1307 NTSTATUS
vfs_stat_fsp(files_struct
*fsp
)
1311 if(fsp
->fh
->fd
== -1) {
1312 if (fsp
->posix_open
) {
1313 ret
= SMB_VFS_LSTAT(fsp
->conn
, fsp
->fsp_name
);
1315 ret
= SMB_VFS_STAT(fsp
->conn
, fsp
->fsp_name
);
1318 return map_nt_error_from_unix(errno
);
1321 if(SMB_VFS_FSTAT(fsp
, &fsp
->fsp_name
->st
) != 0) {
1322 return map_nt_error_from_unix(errno
);
1325 return NT_STATUS_OK
;
1329 * Initialize num_streams and streams, then call VFS op streaminfo
1331 NTSTATUS
vfs_streaminfo(connection_struct
*conn
,
1332 struct files_struct
*fsp
,
1334 TALLOC_CTX
*mem_ctx
,
1335 unsigned int *num_streams
,
1336 struct stream_struct
**streams
)
1340 return SMB_VFS_STREAMINFO(conn
, fsp
, fname
, mem_ctx
, num_streams
, streams
);
1344 generate a file_id from a stat structure
1346 struct file_id
vfs_file_id_from_sbuf(connection_struct
*conn
, const SMB_STRUCT_STAT
*sbuf
)
1348 return SMB_VFS_FILE_ID_CREATE(conn
, sbuf
);
1351 int smb_vfs_call_connect(struct vfs_handle_struct
*handle
,
1352 const char *service
, const char *user
)
1355 return handle
->fns
->connect_fn(handle
, service
, user
);
1358 void smb_vfs_call_disconnect(struct vfs_handle_struct
*handle
)
1360 VFS_FIND(disconnect
);
1361 handle
->fns
->disconnect_fn(handle
);
1364 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct
*handle
,
1365 const char *path
, uint64_t *bsize
,
1366 uint64_t *dfree
, uint64_t *dsize
)
1368 VFS_FIND(disk_free
);
1369 return handle
->fns
->disk_free_fn(handle
, path
, bsize
, dfree
, dsize
);
1372 int smb_vfs_call_get_quota(struct vfs_handle_struct
*handle
,
1373 enum SMB_QUOTA_TYPE qtype
, unid_t id
,
1376 VFS_FIND(get_quota
);
1377 return handle
->fns
->get_quota_fn(handle
, qtype
, id
, qt
);
1380 int smb_vfs_call_set_quota(struct vfs_handle_struct
*handle
,
1381 enum SMB_QUOTA_TYPE qtype
, unid_t id
,
1384 VFS_FIND(set_quota
);
1385 return handle
->fns
->set_quota_fn(handle
, qtype
, id
, qt
);
1388 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct
*handle
,
1389 struct files_struct
*fsp
,
1390 struct shadow_copy_data
*shadow_copy_data
,
1393 VFS_FIND(get_shadow_copy_data
);
1394 return handle
->fns
->get_shadow_copy_data_fn(handle
, fsp
,
1398 int smb_vfs_call_statvfs(struct vfs_handle_struct
*handle
, const char *path
,
1399 struct vfs_statvfs_struct
*statbuf
)
1402 return handle
->fns
->statvfs_fn(handle
, path
, statbuf
);
1405 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct
*handle
,
1406 enum timestamp_set_resolution
*p_ts_res
)
1408 VFS_FIND(fs_capabilities
);
1409 return handle
->fns
->fs_capabilities_fn(handle
, p_ts_res
);
1412 NTSTATUS
smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct
*handle
,
1413 struct dfs_GetDFSReferral
*r
)
1415 VFS_FIND(get_dfs_referrals
);
1416 return handle
->fns
->get_dfs_referrals_fn(handle
, r
);
1419 DIR *smb_vfs_call_opendir(struct vfs_handle_struct
*handle
,
1420 const char *fname
, const char *mask
,
1421 uint32_t attributes
)
1424 return handle
->fns
->opendir_fn(handle
, fname
, mask
, attributes
);
1427 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct
*handle
,
1428 struct files_struct
*fsp
,
1430 uint32_t attributes
)
1432 VFS_FIND(fdopendir
);
1433 return handle
->fns
->fdopendir_fn(handle
, fsp
, mask
, attributes
);
1436 struct dirent
*smb_vfs_call_readdir(struct vfs_handle_struct
*handle
,
1438 SMB_STRUCT_STAT
*sbuf
)
1441 return handle
->fns
->readdir_fn(handle
, dirp
, sbuf
);
1444 void smb_vfs_call_seekdir(struct vfs_handle_struct
*handle
,
1445 DIR *dirp
, long offset
)
1448 handle
->fns
->seekdir_fn(handle
, dirp
, offset
);
1451 long smb_vfs_call_telldir(struct vfs_handle_struct
*handle
,
1455 return handle
->fns
->telldir_fn(handle
, dirp
);
1458 void smb_vfs_call_rewind_dir(struct vfs_handle_struct
*handle
,
1461 VFS_FIND(rewind_dir
);
1462 handle
->fns
->rewind_dir_fn(handle
, dirp
);
1465 int smb_vfs_call_mkdir(struct vfs_handle_struct
*handle
, const char *path
,
1469 return handle
->fns
->mkdir_fn(handle
, path
, mode
);
1472 int smb_vfs_call_rmdir(struct vfs_handle_struct
*handle
, const char *path
)
1475 return handle
->fns
->rmdir_fn(handle
, path
);
1478 int smb_vfs_call_closedir(struct vfs_handle_struct
*handle
,
1482 return handle
->fns
->closedir_fn(handle
, dir
);
1485 void smb_vfs_call_init_search_op(struct vfs_handle_struct
*handle
,
1488 VFS_FIND(init_search_op
);
1489 handle
->fns
->init_search_op_fn(handle
, dirp
);
1492 int smb_vfs_call_open(struct vfs_handle_struct
*handle
,
1493 struct smb_filename
*smb_fname
, struct files_struct
*fsp
,
1494 int flags
, mode_t mode
)
1497 return handle
->fns
->open_fn(handle
, smb_fname
, fsp
, flags
, mode
);
1500 NTSTATUS
smb_vfs_call_create_file(struct vfs_handle_struct
*handle
,
1501 struct smb_request
*req
,
1502 uint16_t root_dir_fid
,
1503 struct smb_filename
*smb_fname
,
1504 uint32_t access_mask
,
1505 uint32_t share_access
,
1506 uint32_t create_disposition
,
1507 uint32_t create_options
,
1508 uint32_t file_attributes
,
1509 uint32_t oplock_request
,
1510 struct smb2_lease
*lease
,
1511 uint64_t allocation_size
,
1512 uint32_t private_flags
,
1513 struct security_descriptor
*sd
,
1514 struct ea_list
*ea_list
,
1515 files_struct
**result
,
1517 const struct smb2_create_blobs
*in_context_blobs
,
1518 struct smb2_create_blobs
*out_context_blobs
)
1520 VFS_FIND(create_file
);
1521 return handle
->fns
->create_file_fn(
1522 handle
, req
, root_dir_fid
, smb_fname
, access_mask
,
1523 share_access
, create_disposition
, create_options
,
1524 file_attributes
, oplock_request
, lease
, allocation_size
,
1525 private_flags
, sd
, ea_list
,
1526 result
, pinfo
, in_context_blobs
, out_context_blobs
);
1529 int smb_vfs_call_close(struct vfs_handle_struct
*handle
,
1530 struct files_struct
*fsp
)
1533 return handle
->fns
->close_fn(handle
, fsp
);
1536 ssize_t
smb_vfs_call_read(struct vfs_handle_struct
*handle
,
1537 struct files_struct
*fsp
, void *data
, size_t n
)
1540 return handle
->fns
->read_fn(handle
, fsp
, data
, n
);
1543 ssize_t
smb_vfs_call_pread(struct vfs_handle_struct
*handle
,
1544 struct files_struct
*fsp
, void *data
, size_t n
,
1548 return handle
->fns
->pread_fn(handle
, fsp
, data
, n
, offset
);
1551 struct smb_vfs_call_pread_state
{
1552 ssize_t (*recv_fn
)(struct tevent_req
*req
, int *err
);
1556 static void smb_vfs_call_pread_done(struct tevent_req
*subreq
);
1558 struct tevent_req
*smb_vfs_call_pread_send(struct vfs_handle_struct
*handle
,
1559 TALLOC_CTX
*mem_ctx
,
1560 struct tevent_context
*ev
,
1561 struct files_struct
*fsp
,
1563 size_t n
, off_t offset
)
1565 struct tevent_req
*req
, *subreq
;
1566 struct smb_vfs_call_pread_state
*state
;
1568 req
= tevent_req_create(mem_ctx
, &state
,
1569 struct smb_vfs_call_pread_state
);
1573 VFS_FIND(pread_send
);
1574 state
->recv_fn
= handle
->fns
->pread_recv_fn
;
1576 subreq
= handle
->fns
->pread_send_fn(handle
, state
, ev
, fsp
, data
, n
,
1578 if (tevent_req_nomem(subreq
, req
)) {
1579 return tevent_req_post(req
, ev
);
1581 tevent_req_set_callback(subreq
, smb_vfs_call_pread_done
, req
);
1585 static void smb_vfs_call_pread_done(struct tevent_req
*subreq
)
1587 struct tevent_req
*req
= tevent_req_callback_data(
1588 subreq
, struct tevent_req
);
1589 struct smb_vfs_call_pread_state
*state
= tevent_req_data(
1590 req
, struct smb_vfs_call_pread_state
);
1593 state
->retval
= state
->recv_fn(subreq
, &err
);
1594 TALLOC_FREE(subreq
);
1595 if (state
->retval
== -1) {
1596 tevent_req_error(req
, err
);
1599 tevent_req_done(req
);
1602 ssize_t
SMB_VFS_PREAD_RECV(struct tevent_req
*req
, int *perrno
)
1604 struct smb_vfs_call_pread_state
*state
= tevent_req_data(
1605 req
, struct smb_vfs_call_pread_state
);
1608 if (tevent_req_is_unix_error(req
, &err
)) {
1612 return state
->retval
;
1615 ssize_t
smb_vfs_call_write(struct vfs_handle_struct
*handle
,
1616 struct files_struct
*fsp
, const void *data
,
1620 return handle
->fns
->write_fn(handle
, fsp
, data
, n
);
1623 ssize_t
smb_vfs_call_pwrite(struct vfs_handle_struct
*handle
,
1624 struct files_struct
*fsp
, const void *data
,
1625 size_t n
, off_t offset
)
1628 return handle
->fns
->pwrite_fn(handle
, fsp
, data
, n
, offset
);
1631 struct smb_vfs_call_pwrite_state
{
1632 ssize_t (*recv_fn
)(struct tevent_req
*req
, int *err
);
1636 static void smb_vfs_call_pwrite_done(struct tevent_req
*subreq
);
1638 struct tevent_req
*smb_vfs_call_pwrite_send(struct vfs_handle_struct
*handle
,
1639 TALLOC_CTX
*mem_ctx
,
1640 struct tevent_context
*ev
,
1641 struct files_struct
*fsp
,
1643 size_t n
, off_t offset
)
1645 struct tevent_req
*req
, *subreq
;
1646 struct smb_vfs_call_pwrite_state
*state
;
1648 req
= tevent_req_create(mem_ctx
, &state
,
1649 struct smb_vfs_call_pwrite_state
);
1653 VFS_FIND(pwrite_send
);
1654 state
->recv_fn
= handle
->fns
->pwrite_recv_fn
;
1656 subreq
= handle
->fns
->pwrite_send_fn(handle
, state
, ev
, fsp
, data
, n
,
1658 if (tevent_req_nomem(subreq
, req
)) {
1659 return tevent_req_post(req
, ev
);
1661 tevent_req_set_callback(subreq
, smb_vfs_call_pwrite_done
, req
);
1665 static void smb_vfs_call_pwrite_done(struct tevent_req
*subreq
)
1667 struct tevent_req
*req
= tevent_req_callback_data(
1668 subreq
, struct tevent_req
);
1669 struct smb_vfs_call_pwrite_state
*state
= tevent_req_data(
1670 req
, struct smb_vfs_call_pwrite_state
);
1673 state
->retval
= state
->recv_fn(subreq
, &err
);
1674 TALLOC_FREE(subreq
);
1675 if (state
->retval
== -1) {
1676 tevent_req_error(req
, err
);
1679 tevent_req_done(req
);
1682 ssize_t
SMB_VFS_PWRITE_RECV(struct tevent_req
*req
, int *perrno
)
1684 struct smb_vfs_call_pwrite_state
*state
= tevent_req_data(
1685 req
, struct smb_vfs_call_pwrite_state
);
1688 if (tevent_req_is_unix_error(req
, &err
)) {
1692 return state
->retval
;
1695 off_t
smb_vfs_call_lseek(struct vfs_handle_struct
*handle
,
1696 struct files_struct
*fsp
, off_t offset
,
1700 return handle
->fns
->lseek_fn(handle
, fsp
, offset
, whence
);
1703 ssize_t
smb_vfs_call_sendfile(struct vfs_handle_struct
*handle
, int tofd
,
1704 files_struct
*fromfsp
, const DATA_BLOB
*header
,
1705 off_t offset
, size_t count
)
1708 return handle
->fns
->sendfile_fn(handle
, tofd
, fromfsp
, header
, offset
,
1712 ssize_t
smb_vfs_call_recvfile(struct vfs_handle_struct
*handle
, int fromfd
,
1713 files_struct
*tofsp
, off_t offset
,
1717 return handle
->fns
->recvfile_fn(handle
, fromfd
, tofsp
, offset
, count
);
1720 int smb_vfs_call_rename(struct vfs_handle_struct
*handle
,
1721 const struct smb_filename
*smb_fname_src
,
1722 const struct smb_filename
*smb_fname_dst
)
1725 return handle
->fns
->rename_fn(handle
, smb_fname_src
, smb_fname_dst
);
1728 int smb_vfs_call_fsync(struct vfs_handle_struct
*handle
,
1729 struct files_struct
*fsp
)
1732 return handle
->fns
->fsync_fn(handle
, fsp
);
1735 struct smb_vfs_call_fsync_state
{
1736 int (*recv_fn
)(struct tevent_req
*req
, int *err
);
1740 static void smb_vfs_call_fsync_done(struct tevent_req
*subreq
);
1742 struct tevent_req
*smb_vfs_call_fsync_send(struct vfs_handle_struct
*handle
,
1743 TALLOC_CTX
*mem_ctx
,
1744 struct tevent_context
*ev
,
1745 struct files_struct
*fsp
)
1747 struct tevent_req
*req
, *subreq
;
1748 struct smb_vfs_call_fsync_state
*state
;
1750 req
= tevent_req_create(mem_ctx
, &state
,
1751 struct smb_vfs_call_fsync_state
);
1755 VFS_FIND(fsync_send
);
1756 state
->recv_fn
= handle
->fns
->fsync_recv_fn
;
1758 subreq
= handle
->fns
->fsync_send_fn(handle
, state
, ev
, fsp
);
1759 if (tevent_req_nomem(subreq
, req
)) {
1760 return tevent_req_post(req
, ev
);
1762 tevent_req_set_callback(subreq
, smb_vfs_call_fsync_done
, req
);
1766 static void smb_vfs_call_fsync_done(struct tevent_req
*subreq
)
1768 struct tevent_req
*req
= tevent_req_callback_data(
1769 subreq
, struct tevent_req
);
1770 struct smb_vfs_call_fsync_state
*state
= tevent_req_data(
1771 req
, struct smb_vfs_call_fsync_state
);
1774 state
->retval
= state
->recv_fn(subreq
, &err
);
1775 TALLOC_FREE(subreq
);
1776 if (state
->retval
== -1) {
1777 tevent_req_error(req
, err
);
1780 tevent_req_done(req
);
1783 int SMB_VFS_FSYNC_RECV(struct tevent_req
*req
, int *perrno
)
1785 struct smb_vfs_call_fsync_state
*state
= tevent_req_data(
1786 req
, struct smb_vfs_call_fsync_state
);
1789 if (tevent_req_is_unix_error(req
, &err
)) {
1793 return state
->retval
;
1797 int smb_vfs_call_stat(struct vfs_handle_struct
*handle
,
1798 struct smb_filename
*smb_fname
)
1801 return handle
->fns
->stat_fn(handle
, smb_fname
);
1804 int smb_vfs_call_fstat(struct vfs_handle_struct
*handle
,
1805 struct files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
1808 return handle
->fns
->fstat_fn(handle
, fsp
, sbuf
);
1811 int smb_vfs_call_lstat(struct vfs_handle_struct
*handle
,
1812 struct smb_filename
*smb_filename
)
1815 return handle
->fns
->lstat_fn(handle
, smb_filename
);
1818 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct
*handle
,
1819 struct files_struct
*fsp
,
1820 const SMB_STRUCT_STAT
*sbuf
)
1822 VFS_FIND(get_alloc_size
);
1823 return handle
->fns
->get_alloc_size_fn(handle
, fsp
, sbuf
);
1826 int smb_vfs_call_unlink(struct vfs_handle_struct
*handle
,
1827 const struct smb_filename
*smb_fname
)
1830 return handle
->fns
->unlink_fn(handle
, smb_fname
);
1833 int smb_vfs_call_chmod(struct vfs_handle_struct
*handle
, const char *path
,
1837 return handle
->fns
->chmod_fn(handle
, path
, mode
);
1840 int smb_vfs_call_fchmod(struct vfs_handle_struct
*handle
,
1841 struct files_struct
*fsp
, mode_t mode
)
1844 return handle
->fns
->fchmod_fn(handle
, fsp
, mode
);
1847 int smb_vfs_call_chown(struct vfs_handle_struct
*handle
, const char *path
,
1848 uid_t uid
, gid_t gid
)
1851 return handle
->fns
->chown_fn(handle
, path
, uid
, gid
);
1854 int smb_vfs_call_fchown(struct vfs_handle_struct
*handle
,
1855 struct files_struct
*fsp
, uid_t uid
, gid_t gid
)
1858 return handle
->fns
->fchown_fn(handle
, fsp
, uid
, gid
);
1861 int smb_vfs_call_lchown(struct vfs_handle_struct
*handle
, const char *path
,
1862 uid_t uid
, gid_t gid
)
1865 return handle
->fns
->lchown_fn(handle
, path
, uid
, gid
);
1868 NTSTATUS
vfs_chown_fsp(files_struct
*fsp
, uid_t uid
, gid_t gid
)
1871 bool as_root
= false;
1873 char *saved_dir
= NULL
;
1874 char *parent_dir
= NULL
;
1877 if (fsp
->fh
->fd
!= -1) {
1879 ret
= SMB_VFS_FCHOWN(fsp
, uid
, gid
);
1881 return NT_STATUS_OK
;
1883 if (ret
== -1 && errno
!= ENOSYS
) {
1884 return map_nt_error_from_unix(errno
);
1888 as_root
= (geteuid() == 0);
1892 * We are being asked to chown as root. Make
1893 * sure we chdir() into the path to pin it,
1894 * and always act using lchown to ensure we
1895 * don't deref any symbolic links.
1897 const char *final_component
= NULL
;
1898 struct smb_filename local_fname
;
1900 saved_dir
= vfs_GetWd(talloc_tos(),fsp
->conn
);
1902 status
= map_nt_error_from_unix(errno
);
1903 DEBUG(0,("vfs_chown_fsp: failed to get "
1904 "current working directory. Error was %s\n",
1909 if (!parent_dirname(talloc_tos(),
1910 fsp
->fsp_name
->base_name
,
1912 &final_component
)) {
1913 return NT_STATUS_NO_MEMORY
;
1916 /* cd into the parent dir to pin it. */
1917 ret
= vfs_ChDir(fsp
->conn
, parent_dir
);
1919 return map_nt_error_from_unix(errno
);
1922 ZERO_STRUCT(local_fname
);
1923 local_fname
.base_name
= discard_const_p(char, final_component
);
1925 /* Must use lstat here. */
1926 ret
= SMB_VFS_LSTAT(fsp
->conn
, &local_fname
);
1928 status
= map_nt_error_from_unix(errno
);
1932 /* Ensure it matches the fsp stat. */
1933 if (!check_same_stat(&local_fname
.st
, &fsp
->fsp_name
->st
)) {
1934 status
= NT_STATUS_ACCESS_DENIED
;
1937 path
= final_component
;
1939 path
= fsp
->fsp_name
->base_name
;
1942 if (fsp
->posix_open
|| as_root
) {
1943 ret
= SMB_VFS_LCHOWN(fsp
->conn
,
1947 ret
= SMB_VFS_CHOWN(fsp
->conn
,
1953 status
= NT_STATUS_OK
;
1955 status
= map_nt_error_from_unix(errno
);
1961 vfs_ChDir(fsp
->conn
,saved_dir
);
1962 TALLOC_FREE(saved_dir
);
1963 TALLOC_FREE(parent_dir
);
1968 int smb_vfs_call_chdir(struct vfs_handle_struct
*handle
, const char *path
)
1971 return handle
->fns
->chdir_fn(handle
, path
);
1974 char *smb_vfs_call_getwd(struct vfs_handle_struct
*handle
)
1977 return handle
->fns
->getwd_fn(handle
);
1980 int smb_vfs_call_ntimes(struct vfs_handle_struct
*handle
,
1981 const struct smb_filename
*smb_fname
,
1982 struct smb_file_time
*ft
)
1985 return handle
->fns
->ntimes_fn(handle
, smb_fname
, ft
);
1988 int smb_vfs_call_ftruncate(struct vfs_handle_struct
*handle
,
1989 struct files_struct
*fsp
, off_t offset
)
1991 VFS_FIND(ftruncate
);
1992 return handle
->fns
->ftruncate_fn(handle
, fsp
, offset
);
1995 int smb_vfs_call_fallocate(struct vfs_handle_struct
*handle
,
1996 struct files_struct
*fsp
,
2001 VFS_FIND(fallocate
);
2002 return handle
->fns
->fallocate_fn(handle
, fsp
, mode
, offset
, len
);
2005 int smb_vfs_call_kernel_flock(struct vfs_handle_struct
*handle
,
2006 struct files_struct
*fsp
, uint32_t share_mode
,
2007 uint32_t access_mask
)
2009 VFS_FIND(kernel_flock
);
2010 return handle
->fns
->kernel_flock_fn(handle
, fsp
, share_mode
,
2014 int smb_vfs_call_linux_setlease(struct vfs_handle_struct
*handle
,
2015 struct files_struct
*fsp
, int leasetype
)
2017 VFS_FIND(linux_setlease
);
2018 return handle
->fns
->linux_setlease_fn(handle
, fsp
, leasetype
);
2021 int smb_vfs_call_symlink(struct vfs_handle_struct
*handle
, const char *oldpath
,
2022 const char *newpath
)
2025 return handle
->fns
->symlink_fn(handle
, oldpath
, newpath
);
2028 int smb_vfs_call_readlink(struct vfs_handle_struct
*handle
,
2029 const char *path
, char *buf
, size_t bufsiz
)
2032 return handle
->fns
->readlink_fn(handle
, path
, buf
, bufsiz
);
2035 int smb_vfs_call_link(struct vfs_handle_struct
*handle
, const char *oldpath
,
2036 const char *newpath
)
2039 return handle
->fns
->link_fn(handle
, oldpath
, newpath
);
2042 int smb_vfs_call_mknod(struct vfs_handle_struct
*handle
, const char *path
,
2043 mode_t mode
, SMB_DEV_T dev
)
2046 return handle
->fns
->mknod_fn(handle
, path
, mode
, dev
);
2049 char *smb_vfs_call_realpath(struct vfs_handle_struct
*handle
, const char *path
)
2052 return handle
->fns
->realpath_fn(handle
, path
);
2055 int smb_vfs_call_chflags(struct vfs_handle_struct
*handle
, const char *path
,
2059 return handle
->fns
->chflags_fn(handle
, path
, flags
);
2062 struct file_id
smb_vfs_call_file_id_create(struct vfs_handle_struct
*handle
,
2063 const SMB_STRUCT_STAT
*sbuf
)
2065 VFS_FIND(file_id_create
);
2066 return handle
->fns
->file_id_create_fn(handle
, sbuf
);
2069 NTSTATUS
smb_vfs_call_streaminfo(struct vfs_handle_struct
*handle
,
2070 struct files_struct
*fsp
,
2072 TALLOC_CTX
*mem_ctx
,
2073 unsigned int *num_streams
,
2074 struct stream_struct
**streams
)
2076 VFS_FIND(streaminfo
);
2077 return handle
->fns
->streaminfo_fn(handle
, fsp
, fname
, mem_ctx
,
2078 num_streams
, streams
);
2081 int smb_vfs_call_get_real_filename(struct vfs_handle_struct
*handle
,
2082 const char *path
, const char *name
,
2083 TALLOC_CTX
*mem_ctx
, char **found_name
)
2085 VFS_FIND(get_real_filename
);
2086 return handle
->fns
->get_real_filename_fn(handle
, path
, name
, mem_ctx
,
2090 const char *smb_vfs_call_connectpath(struct vfs_handle_struct
*handle
,
2091 const char *filename
)
2093 VFS_FIND(connectpath
);
2094 return handle
->fns
->connectpath_fn(handle
, filename
);
2097 bool smb_vfs_call_strict_lock(struct vfs_handle_struct
*handle
,
2098 struct files_struct
*fsp
,
2099 struct lock_struct
*plock
)
2101 VFS_FIND(strict_lock
);
2102 return handle
->fns
->strict_lock_fn(handle
, fsp
, plock
);
2105 void smb_vfs_call_strict_unlock(struct vfs_handle_struct
*handle
,
2106 struct files_struct
*fsp
,
2107 struct lock_struct
*plock
)
2109 VFS_FIND(strict_unlock
);
2110 handle
->fns
->strict_unlock_fn(handle
, fsp
, plock
);
2113 NTSTATUS
smb_vfs_call_translate_name(struct vfs_handle_struct
*handle
,
2115 enum vfs_translate_direction direction
,
2116 TALLOC_CTX
*mem_ctx
,
2119 VFS_FIND(translate_name
);
2120 return handle
->fns
->translate_name_fn(handle
, name
, direction
, mem_ctx
,
2124 NTSTATUS
smb_vfs_call_fsctl(struct vfs_handle_struct
*handle
,
2125 struct files_struct
*fsp
,
2129 const uint8_t *in_data
,
2132 uint32_t max_out_len
,
2136 return handle
->fns
->fsctl_fn(handle
, fsp
, ctx
, function
, req_flags
,
2137 in_data
, in_len
, out_data
, max_out_len
,
2141 struct tevent_req
*smb_vfs_call_copy_chunk_send(struct vfs_handle_struct
*handle
,
2142 TALLOC_CTX
*mem_ctx
,
2143 struct tevent_context
*ev
,
2144 struct files_struct
*src_fsp
,
2146 struct files_struct
*dest_fsp
,
2150 VFS_FIND(copy_chunk_send
);
2151 return handle
->fns
->copy_chunk_send_fn(handle
, mem_ctx
, ev
, src_fsp
,
2152 src_off
, dest_fsp
, dest_off
, num
);
2155 NTSTATUS
smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct
*handle
,
2156 struct tevent_req
*req
,
2159 VFS_FIND(copy_chunk_recv
);
2160 return handle
->fns
->copy_chunk_recv_fn(handle
, req
, copied
);
2163 NTSTATUS
smb_vfs_call_get_compression(vfs_handle_struct
*handle
,
2164 TALLOC_CTX
*mem_ctx
,
2165 struct files_struct
*fsp
,
2166 struct smb_filename
*smb_fname
,
2167 uint16_t *_compression_fmt
)
2169 VFS_FIND(get_compression
);
2170 return handle
->fns
->get_compression_fn(handle
, mem_ctx
, fsp
, smb_fname
,
2174 NTSTATUS
smb_vfs_call_set_compression(vfs_handle_struct
*handle
,
2175 TALLOC_CTX
*mem_ctx
,
2176 struct files_struct
*fsp
,
2177 uint16_t compression_fmt
)
2179 VFS_FIND(set_compression
);
2180 return handle
->fns
->set_compression_fn(handle
, mem_ctx
, fsp
,
2184 NTSTATUS
smb_vfs_call_snap_check_path(vfs_handle_struct
*handle
,
2185 TALLOC_CTX
*mem_ctx
,
2186 const char *service_path
,
2189 VFS_FIND(snap_check_path
);
2190 return handle
->fns
->snap_check_path_fn(handle
, mem_ctx
, service_path
,
2194 NTSTATUS
smb_vfs_call_snap_create(struct vfs_handle_struct
*handle
,
2195 TALLOC_CTX
*mem_ctx
,
2196 const char *base_volume
,
2202 VFS_FIND(snap_create
);
2203 return handle
->fns
->snap_create_fn(handle
, mem_ctx
, base_volume
, tstamp
,
2204 rw
, base_path
, snap_path
);
2207 NTSTATUS
smb_vfs_call_snap_delete(struct vfs_handle_struct
*handle
,
2208 TALLOC_CTX
*mem_ctx
,
2212 VFS_FIND(snap_delete
);
2213 return handle
->fns
->snap_delete_fn(handle
, mem_ctx
, base_path
,
2217 NTSTATUS
smb_vfs_call_fget_nt_acl(struct vfs_handle_struct
*handle
,
2218 struct files_struct
*fsp
,
2219 uint32_t security_info
,
2220 TALLOC_CTX
*mem_ctx
,
2221 struct security_descriptor
**ppdesc
)
2223 VFS_FIND(fget_nt_acl
);
2224 return handle
->fns
->fget_nt_acl_fn(handle
, fsp
, security_info
,
2228 NTSTATUS
smb_vfs_call_get_nt_acl(struct vfs_handle_struct
*handle
,
2230 uint32_t security_info
,
2231 TALLOC_CTX
*mem_ctx
,
2232 struct security_descriptor
**ppdesc
)
2234 VFS_FIND(get_nt_acl
);
2235 return handle
->fns
->get_nt_acl_fn(handle
, name
, security_info
, mem_ctx
, ppdesc
);
2238 NTSTATUS
smb_vfs_call_fset_nt_acl(struct vfs_handle_struct
*handle
,
2239 struct files_struct
*fsp
,
2240 uint32_t security_info_sent
,
2241 const struct security_descriptor
*psd
)
2243 VFS_FIND(fset_nt_acl
);
2244 return handle
->fns
->fset_nt_acl_fn(handle
, fsp
, security_info_sent
,
2248 NTSTATUS
smb_vfs_call_audit_file(struct vfs_handle_struct
*handle
,
2249 struct smb_filename
*file
,
2250 struct security_acl
*sacl
,
2251 uint32_t access_requested
,
2252 uint32_t access_denied
)
2254 VFS_FIND(audit_file
);
2255 return handle
->fns
->audit_file_fn(handle
,
2262 int smb_vfs_call_chmod_acl(struct vfs_handle_struct
*handle
, const char *name
,
2265 VFS_FIND(chmod_acl
);
2266 return handle
->fns
->chmod_acl_fn(handle
, name
, mode
);
2269 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct
*handle
,
2270 struct files_struct
*fsp
, mode_t mode
)
2272 VFS_FIND(fchmod_acl
);
2273 return handle
->fns
->fchmod_acl_fn(handle
, fsp
, mode
);
2276 SMB_ACL_T
smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct
*handle
,
2278 SMB_ACL_TYPE_T type
,
2279 TALLOC_CTX
*mem_ctx
)
2281 VFS_FIND(sys_acl_get_file
);
2282 return handle
->fns
->sys_acl_get_file_fn(handle
, path_p
, type
, mem_ctx
);
2285 SMB_ACL_T
smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct
*handle
,
2286 struct files_struct
*fsp
,
2287 TALLOC_CTX
*mem_ctx
)
2289 VFS_FIND(sys_acl_get_fd
);
2290 return handle
->fns
->sys_acl_get_fd_fn(handle
, fsp
, mem_ctx
);
2293 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct
*handle
,
2295 TALLOC_CTX
*mem_ctx
,
2296 char **blob_description
,
2299 VFS_FIND(sys_acl_blob_get_file
);
2300 return handle
->fns
->sys_acl_blob_get_file_fn(handle
, path_p
, mem_ctx
, blob_description
, blob
);
2303 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct
*handle
,
2304 struct files_struct
*fsp
,
2305 TALLOC_CTX
*mem_ctx
,
2306 char **blob_description
,
2309 VFS_FIND(sys_acl_blob_get_fd
);
2310 return handle
->fns
->sys_acl_blob_get_fd_fn(handle
, fsp
, mem_ctx
, blob_description
, blob
);
2313 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct
*handle
,
2314 const char *name
, SMB_ACL_TYPE_T acltype
,
2317 VFS_FIND(sys_acl_set_file
);
2318 return handle
->fns
->sys_acl_set_file_fn(handle
, name
, acltype
, theacl
);
2321 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct
*handle
,
2322 struct files_struct
*fsp
, SMB_ACL_T theacl
)
2324 VFS_FIND(sys_acl_set_fd
);
2325 return handle
->fns
->sys_acl_set_fd_fn(handle
, fsp
, theacl
);
2328 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct
*handle
,
2331 VFS_FIND(sys_acl_delete_def_file
);
2332 return handle
->fns
->sys_acl_delete_def_file_fn(handle
, path
);
2335 ssize_t
smb_vfs_call_getxattr(struct vfs_handle_struct
*handle
,
2336 const char *path
, const char *name
, void *value
,
2340 return handle
->fns
->getxattr_fn(handle
, path
, name
, value
, size
);
2343 ssize_t
smb_vfs_call_fgetxattr(struct vfs_handle_struct
*handle
,
2344 struct files_struct
*fsp
, const char *name
,
2345 void *value
, size_t size
)
2347 VFS_FIND(fgetxattr
);
2348 return handle
->fns
->fgetxattr_fn(handle
, fsp
, name
, value
, size
);
2351 ssize_t
smb_vfs_call_listxattr(struct vfs_handle_struct
*handle
,
2352 const char *path
, char *list
, size_t size
)
2354 VFS_FIND(listxattr
);
2355 return handle
->fns
->listxattr_fn(handle
, path
, list
, size
);
2358 ssize_t
smb_vfs_call_flistxattr(struct vfs_handle_struct
*handle
,
2359 struct files_struct
*fsp
, char *list
,
2362 VFS_FIND(flistxattr
);
2363 return handle
->fns
->flistxattr_fn(handle
, fsp
, list
, size
);
2366 int smb_vfs_call_removexattr(struct vfs_handle_struct
*handle
,
2367 const char *path
, const char *name
)
2369 VFS_FIND(removexattr
);
2370 return handle
->fns
->removexattr_fn(handle
, path
, name
);
2373 int smb_vfs_call_fremovexattr(struct vfs_handle_struct
*handle
,
2374 struct files_struct
*fsp
, const char *name
)
2376 VFS_FIND(fremovexattr
);
2377 return handle
->fns
->fremovexattr_fn(handle
, fsp
, name
);
2380 int smb_vfs_call_setxattr(struct vfs_handle_struct
*handle
, const char *path
,
2381 const char *name
, const void *value
, size_t size
,
2385 return handle
->fns
->setxattr_fn(handle
, path
, name
, value
, size
, flags
);
2388 int smb_vfs_call_fsetxattr(struct vfs_handle_struct
*handle
,
2389 struct files_struct
*fsp
, const char *name
,
2390 const void *value
, size_t size
, int flags
)
2392 VFS_FIND(fsetxattr
);
2393 return handle
->fns
->fsetxattr_fn(handle
, fsp
, name
, value
, size
, flags
);
2396 bool smb_vfs_call_aio_force(struct vfs_handle_struct
*handle
,
2397 struct files_struct
*fsp
)
2399 VFS_FIND(aio_force
);
2400 return handle
->fns
->aio_force_fn(handle
, fsp
);
2403 bool smb_vfs_call_is_offline(struct vfs_handle_struct
*handle
,
2404 const struct smb_filename
*fname
,
2405 SMB_STRUCT_STAT
*sbuf
)
2407 VFS_FIND(is_offline
);
2408 return handle
->fns
->is_offline_fn(handle
, fname
, sbuf
);
2411 int smb_vfs_call_set_offline(struct vfs_handle_struct
*handle
,
2412 const struct smb_filename
*fname
)
2414 VFS_FIND(set_offline
);
2415 return handle
->fns
->set_offline_fn(handle
, fname
);
2418 NTSTATUS
smb_vfs_call_durable_cookie(struct vfs_handle_struct
*handle
,
2419 struct files_struct
*fsp
,
2420 TALLOC_CTX
*mem_ctx
,
2423 VFS_FIND(durable_cookie
);
2424 return handle
->fns
->durable_cookie_fn(handle
, fsp
, mem_ctx
, cookie
);
2427 NTSTATUS
smb_vfs_call_durable_disconnect(struct vfs_handle_struct
*handle
,
2428 struct files_struct
*fsp
,
2429 const DATA_BLOB old_cookie
,
2430 TALLOC_CTX
*mem_ctx
,
2431 DATA_BLOB
*new_cookie
)
2433 VFS_FIND(durable_disconnect
);
2434 return handle
->fns
->durable_disconnect_fn(handle
, fsp
, old_cookie
,
2435 mem_ctx
, new_cookie
);
2438 NTSTATUS
smb_vfs_call_durable_reconnect(struct vfs_handle_struct
*handle
,
2439 struct smb_request
*smb1req
,
2440 struct smbXsrv_open
*op
,
2441 const DATA_BLOB old_cookie
,
2442 TALLOC_CTX
*mem_ctx
,
2443 struct files_struct
**fsp
,
2444 DATA_BLOB
*new_cookie
)
2446 VFS_FIND(durable_reconnect
);
2447 return handle
->fns
->durable_reconnect_fn(handle
, smb1req
, op
,
2448 old_cookie
, mem_ctx
, fsp
,
2452 NTSTATUS
smb_vfs_call_readdir_attr(struct vfs_handle_struct
*handle
,
2453 const struct smb_filename
*fname
,
2454 TALLOC_CTX
*mem_ctx
,
2455 struct readdir_attr_data
**attr_data
)
2457 VFS_FIND(readdir_attr
);
2458 return handle
->fns
->readdir_attr_fn(handle
, fname
, mem_ctx
, attr_data
);