2 Unix SMB/Netbios implementation.
4 VFS initialisation and support functions
5 Copyright (C) Tim Potter 1999
6 Copyright (C) Alexander Bokovoy 2002
7 Copyright (C) James Peach 2006
8 Copyright (C) Volker Lendecke 2009
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 This work was sponsored by Optifacio Software Services, Inc.
27 #include "system/filesys.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "../lib/util/memcache.h"
31 #include "transfer_file.h"
33 #include "lib/util/tevent_unix.h"
34 #include "lib/util/tevent_ntstatus.h"
35 #include "lib/util/sys_rw.h"
38 #define DBGC_CLASS DBGC_VFS
43 struct vfs_fsp_data
*next
;
44 struct vfs_handle_struct
*owner
;
45 void (*destroy
)(void *p_data
);
47 /* NOTE: This structure contains four pointers so that we can guarantee
48 * that the end of the structure is always both 4-byte and 8-byte aligned.
52 struct vfs_init_function_entry
{
54 struct vfs_init_function_entry
*prev
, *next
;
55 const struct vfs_fn_pointers
*fns
;
58 /****************************************************************************
59 maintain the list of available backends
60 ****************************************************************************/
62 static struct vfs_init_function_entry
*vfs_find_backend_entry(const char *name
)
64 struct vfs_init_function_entry
*entry
= backends
;
66 DEBUG(10, ("vfs_find_backend_entry called for %s\n", name
));
69 if (strcmp(entry
->name
, name
)==0) return entry
;
76 NTSTATUS
smb_register_vfs(int version
, const char *name
,
77 const struct vfs_fn_pointers
*fns
)
79 struct vfs_init_function_entry
*entry
= backends
;
81 if ((version
!= SMB_VFS_INTERFACE_VERSION
)) {
82 DEBUG(0, ("Failed to register vfs module.\n"
83 "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
84 "current SMB_VFS_INTERFACE_VERSION is %d.\n"
85 "Please recompile against the current Samba Version!\n",
86 version
, SMB_VFS_INTERFACE_VERSION
));
87 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
90 if (!name
|| !name
[0]) {
91 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
92 return NT_STATUS_INVALID_PARAMETER
;
95 if (vfs_find_backend_entry(name
)) {
96 DEBUG(0,("VFS module %s already loaded!\n", name
));
97 return NT_STATUS_OBJECT_NAME_COLLISION
;
100 entry
= SMB_XMALLOC_P(struct vfs_init_function_entry
);
101 entry
->name
= smb_xstrdup(name
);
104 DLIST_ADD(backends
, entry
);
105 DEBUG(5, ("Successfully added vfs backend '%s'\n", name
));
109 /****************************************************************************
110 initialise default vfs hooks
111 ****************************************************************************/
113 static void vfs_init_default(connection_struct
*conn
)
115 DEBUG(3, ("Initialising default vfs hooks\n"));
116 vfs_init_custom(conn
, DEFAULT_VFS_MODULE_NAME
);
119 /****************************************************************************
120 initialise custom vfs hooks
121 ****************************************************************************/
123 bool vfs_init_custom(connection_struct
*conn
, const char *vfs_object
)
125 char *module_path
= NULL
;
126 char *module_name
= NULL
;
127 char *module_param
= NULL
, *p
;
128 vfs_handle_struct
*handle
;
129 const struct vfs_init_function_entry
*entry
;
131 if (!conn
||!vfs_object
||!vfs_object
[0]) {
132 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
133 "empty vfs_object!\n"));
138 static_init_vfs(NULL
);
141 DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object
));
143 module_path
= smb_xstrdup(vfs_object
);
145 p
= strchr_m(module_path
, ':');
150 trim_char(module_param
, ' ', ' ');
153 trim_char(module_path
, ' ', ' ');
155 module_name
= smb_xstrdup(module_path
);
157 if ((module_name
[0] == '/') &&
158 (strcmp(module_path
, DEFAULT_VFS_MODULE_NAME
) != 0)) {
161 * Extract the module name from the path. Just use the base
162 * name of the last path component.
165 SAFE_FREE(module_name
);
166 module_name
= smb_xstrdup(strrchr_m(module_path
, '/')+1);
168 p
= strchr_m(module_name
, '.');
175 /* First, try to load the module with the new module system */
176 entry
= vfs_find_backend_entry(module_name
);
180 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
183 status
= smb_load_module("vfs", module_path
);
184 if (!NT_STATUS_IS_OK(status
)) {
185 DEBUG(0, ("error probing vfs module '%s': %s\n",
186 module_path
, nt_errstr(status
)));
190 entry
= vfs_find_backend_entry(module_name
);
192 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object
));
197 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object
));
199 handle
= talloc_zero(conn
, vfs_handle_struct
);
201 DEBUG(0,("TALLOC_ZERO() failed!\n"));
205 handle
->fns
= entry
->fns
;
207 handle
->param
= talloc_strdup(conn
, module_param
);
209 DLIST_ADD(conn
->vfs_handles
, handle
);
211 SAFE_FREE(module_path
);
212 SAFE_FREE(module_name
);
216 SAFE_FREE(module_path
);
217 SAFE_FREE(module_name
);
221 /*****************************************************************
222 Allow VFS modules to extend files_struct with VFS-specific state.
223 This will be ok for small numbers of extensions, but might need to
224 be refactored if it becomes more widely used.
225 ******************************************************************/
227 #define EXT_DATA_AREA(e) ((uint8_t *)(e) + sizeof(struct vfs_fsp_data))
229 void *vfs_add_fsp_extension_notype(vfs_handle_struct
*handle
,
230 files_struct
*fsp
, size_t ext_size
,
231 void (*destroy_fn
)(void *p_data
))
233 struct vfs_fsp_data
*ext
;
236 /* Prevent VFS modules adding multiple extensions. */
237 if ((ext_data
= vfs_fetch_fsp_extension(handle
, fsp
))) {
241 ext
= (struct vfs_fsp_data
*)TALLOC_ZERO(
242 handle
->conn
, sizeof(struct vfs_fsp_data
) + ext_size
);
248 ext
->next
= fsp
->vfs_extension
;
249 ext
->destroy
= destroy_fn
;
250 fsp
->vfs_extension
= ext
;
251 return EXT_DATA_AREA(ext
);
254 void vfs_remove_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
256 struct vfs_fsp_data
*curr
;
257 struct vfs_fsp_data
*prev
;
259 for (curr
= fsp
->vfs_extension
, prev
= NULL
;
261 prev
= curr
, curr
= curr
->next
) {
262 if (curr
->owner
== handle
) {
264 prev
->next
= curr
->next
;
266 fsp
->vfs_extension
= curr
->next
;
269 curr
->destroy(EXT_DATA_AREA(curr
));
277 void vfs_remove_all_fsp_extensions(files_struct
*fsp
)
279 struct vfs_fsp_data
*curr
;
280 struct vfs_fsp_data
*next
;
282 for (curr
= fsp
->vfs_extension
; curr
; curr
= next
) {
285 fsp
->vfs_extension
= next
;
288 curr
->destroy(EXT_DATA_AREA(curr
));
294 void *vfs_memctx_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
296 struct vfs_fsp_data
*head
;
298 for (head
= fsp
->vfs_extension
; head
; head
= head
->next
) {
299 if (head
->owner
== handle
) {
307 void *vfs_fetch_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
309 struct vfs_fsp_data
*head
;
311 head
= (struct vfs_fsp_data
*)vfs_memctx_fsp_extension(handle
, fsp
);
313 return EXT_DATA_AREA(head
);
322 * Ensure this module catches all VFS functions.
325 void smb_vfs_assert_all_fns(const struct vfs_fn_pointers
* fns
,
328 bool missing_fn
= false;
330 const uintptr_t *end
= (const uintptr_t *)(fns
+ 1);
332 for (idx
= 0; ((const uintptr_t *)fns
+ idx
) < end
; idx
++) {
333 if (*((const uintptr_t *)fns
+ idx
) == 0) {
334 DBG_ERR("VFS function at index %d not implemented "
335 "in module %s\n", idx
, module
);
341 smb_panic("Required VFS function not implemented in module.\n");
345 void smb_vfs_assert_all_fns(const struct vfs_fn_pointers
* fns
,
351 /*****************************************************************
353 ******************************************************************/
355 bool smbd_vfs_init(connection_struct
*conn
)
357 const char **vfs_objects
;
361 /* Normal share - initialise with disk access functions */
362 vfs_init_default(conn
);
364 /* No need to load vfs modules for printer connections */
369 if (lp_widelinks(SNUM(conn
))) {
371 * As the widelinks logic is now moving into a
372 * vfs_widelinks module, we need to custom load
373 * it after the default module is initialized.
374 * That way no changes to smb.conf files are
377 bool ok
= vfs_init_custom(conn
, "widelinks");
379 DBG_ERR("widelinks enabled and vfs_init_custom "
380 "failed for vfs_widelinks module\n");
385 vfs_objects
= lp_vfs_objects(SNUM(conn
));
387 /* Override VFS functions if 'vfs object' was not specified*/
388 if (!vfs_objects
|| !vfs_objects
[0])
391 for (i
=0; vfs_objects
[i
] ;) {
395 for (j
=i
-1; j
>= 0; j
--) {
396 if (!vfs_init_custom(conn
, vfs_objects
[j
])) {
397 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects
[j
]));
404 /*******************************************************************
405 Check if a file exists in the vfs.
406 ********************************************************************/
408 NTSTATUS
vfs_file_exist(connection_struct
*conn
, struct smb_filename
*smb_fname
)
410 /* Only return OK if stat was successful and S_ISREG */
411 if ((SMB_VFS_STAT(conn
, smb_fname
) != -1) &&
412 S_ISREG(smb_fname
->st
.st_ex_mode
)) {
416 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
419 bool vfs_valid_pread_range(off_t offset
, size_t length
)
421 return sys_valid_io_range(offset
, length
);
424 bool vfs_valid_pwrite_range(off_t offset
, size_t length
)
427 * See MAXFILESIZE in [MS-FSA] 2.1.5.3 Server Requests a Write
429 static const uint64_t maxfilesize
= 0xfffffff0000;
430 uint64_t last_byte_ofs
;
433 ok
= sys_valid_io_range(offset
, length
);
442 last_byte_ofs
= offset
+ length
;
443 if (last_byte_ofs
> maxfilesize
) {
450 ssize_t
vfs_pwrite_data(struct smb_request
*req
,
460 ok
= vfs_valid_pwrite_range(offset
, N
);
466 if (req
&& req
->unread_bytes
) {
467 int sockfd
= req
->xconn
->transport
.sock
;
468 SMB_ASSERT(req
->unread_bytes
== N
);
469 /* VFS_RECVFILE must drain the socket
470 * before returning. */
471 req
->unread_bytes
= 0;
473 * Leave the socket non-blocking and
474 * use SMB_VFS_RECVFILE. If it returns
475 * EAGAIN || EWOULDBLOCK temporarily set
476 * the socket blocking and retry
480 ret
= SMB_VFS_RECVFILE(sockfd
,
484 if (ret
== 0 || (ret
== -1 &&
486 errno
== EWOULDBLOCK
))) {
488 /* Ensure the socket is blocking. */
489 old_flags
= fcntl(sockfd
, F_GETFL
, 0);
490 if (set_blocking(sockfd
, true) == -1) {
493 ret
= SMB_VFS_RECVFILE(sockfd
,
497 if (fcntl(sockfd
, F_SETFL
, old_flags
) == -1) {
504 return (ssize_t
)total
;
506 /* Any other error case. */
512 return (ssize_t
)total
;
516 ret
= SMB_VFS_PWRITE(fsp
, buffer
+ total
, N
- total
,
526 return (ssize_t
)total
;
528 /****************************************************************************
529 An allocate file space call using the vfs interface.
530 Allocates space for a file from a filedescriptor.
531 Returns 0 on success, -1 on failure.
532 ****************************************************************************/
534 int vfs_allocate_file_space(files_struct
*fsp
, uint64_t len
)
537 connection_struct
*conn
= fsp
->conn
;
538 uint64_t space_avail
;
539 uint64_t bsize
,dfree
,dsize
;
544 * Actually try and commit the space on disk....
547 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
548 fsp_str_dbg(fsp
), (double)len
));
550 ok
= vfs_valid_pwrite_range((off_t
)len
, 0);
552 DEBUG(0,("vfs_allocate_file_space: %s negative/invalid len "
553 "requested.\n", fsp_str_dbg(fsp
)));
558 status
= vfs_stat_fsp(fsp
);
559 if (!NT_STATUS_IS_OK(status
)) {
563 if (len
== (uint64_t)fsp
->fsp_name
->st
.st_ex_size
)
566 if (len
< (uint64_t)fsp
->fsp_name
->st
.st_ex_size
) {
567 /* Shrink - use ftruncate. */
569 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
570 "size %.0f\n", fsp_str_dbg(fsp
),
571 (double)fsp
->fsp_name
->st
.st_ex_size
));
573 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_ALLOC_SHRINK
);
575 ret
= SMB_VFS_FTRUNCATE(fsp
, (off_t
)len
);
577 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_ALLOC_SHRINK
);
582 /* Grow - we need to test if we have enough space. */
584 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_ALLOC_GROW
);
586 if (lp_strict_allocate(SNUM(fsp
->conn
))) {
587 /* See if we have a syscall that will allocate beyond
588 end-of-file without changing EOF. */
589 ret
= SMB_VFS_FALLOCATE(fsp
, VFS_FALLOCATE_FL_KEEP_SIZE
,
595 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_ALLOC_GROW
);
598 /* We changed the allocation size on disk, but not
599 EOF - exactly as required. We're done ! */
603 if (ret
== -1 && errno
== ENOSPC
) {
607 len
-= fsp
->fsp_name
->st
.st_ex_size
;
608 len
/= 1024; /* Len is now number of 1k blocks needed. */
610 get_dfree_info(conn
, fsp
->fsp_name
, &bsize
, &dfree
, &dsize
);
611 if (space_avail
== (uint64_t)-1) {
615 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
616 "needed blocks = %.0f, space avail = %.0f\n",
617 fsp_str_dbg(fsp
), (double)fsp
->fsp_name
->st
.st_ex_size
, (double)len
,
618 (double)space_avail
));
620 if (len
> space_avail
) {
628 /****************************************************************************
629 A vfs set_filelen call.
630 set the length of a file from a filedescriptor.
631 Returns 0 on success, -1 on failure.
632 ****************************************************************************/
634 int vfs_set_filelen(files_struct
*fsp
, off_t len
)
639 ok
= vfs_valid_pwrite_range(len
, 0);
645 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_SET_FILE_LEN
);
647 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
648 fsp_str_dbg(fsp
), (double)len
));
649 if ((ret
= SMB_VFS_FTRUNCATE(fsp
, len
)) != -1) {
650 notify_fname(fsp
->conn
, NOTIFY_ACTION_MODIFIED
,
651 FILE_NOTIFY_CHANGE_SIZE
652 | FILE_NOTIFY_CHANGE_ATTRIBUTES
,
653 fsp
->fsp_name
->base_name
);
656 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_SET_FILE_LEN
);
661 /****************************************************************************
662 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
663 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
664 as this is also called from the default SMB_VFS_FTRUNCATE code.
665 Always extends the file size.
666 Returns 0 on success, -1 on failure.
667 ****************************************************************************/
669 #define SPARSE_BUF_WRITE_SIZE (32*1024)
671 int vfs_slow_fallocate(files_struct
*fsp
, off_t offset
, off_t len
)
677 ok
= vfs_valid_pwrite_range(offset
, len
);
684 sparse_buf
= SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE
);
691 while (total
< len
) {
692 size_t curr_write_size
= MIN(SPARSE_BUF_WRITE_SIZE
, (len
- total
));
694 pwrite_ret
= SMB_VFS_PWRITE(fsp
, sparse_buf
, curr_write_size
, offset
+ total
);
695 if (pwrite_ret
== -1) {
696 int saved_errno
= errno
;
697 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
698 "%s failed with error %s\n",
699 fsp_str_dbg(fsp
), strerror(saved_errno
)));
709 /****************************************************************************
710 A vfs fill sparse call.
711 Writes zeros from the end of file to len, if len is greater than EOF.
712 Used only by strict_sync.
713 Returns 0 on success, -1 on failure.
714 ****************************************************************************/
716 int vfs_fill_sparse(files_struct
*fsp
, off_t len
)
724 ok
= vfs_valid_pwrite_range(len
, 0);
730 status
= vfs_stat_fsp(fsp
);
731 if (!NT_STATUS_IS_OK(status
)) {
735 if (len
<= fsp
->fsp_name
->st
.st_ex_size
) {
740 if (S_ISFIFO(fsp
->fsp_name
->st
.st_ex_mode
)) {
745 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
746 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp
),
747 (double)fsp
->fsp_name
->st
.st_ex_size
, (double)len
,
748 (double)(len
- fsp
->fsp_name
->st
.st_ex_size
)));
750 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_FILL_SPARSE
);
752 offset
= fsp
->fsp_name
->st
.st_ex_size
;
753 num_to_write
= len
- fsp
->fsp_name
->st
.st_ex_size
;
755 /* Only do this on non-stream file handles. */
756 if (fsp
->base_fsp
== NULL
) {
757 /* for allocation try fallocate first. This can fail on some
758 * platforms e.g. when the filesystem doesn't support it and no
759 * emulation is being done by the libc (like on AIX with JFS1). In that
760 * case we do our own emulation. fallocate implementations can
761 * return ENOTSUP or EINVAL in cases like that. */
762 ret
= SMB_VFS_FALLOCATE(fsp
, 0, offset
, num_to_write
);
763 if (ret
== -1 && errno
== ENOSPC
) {
769 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
770 "error %d. Falling back to slow manual allocation\n", ret
));
773 ret
= vfs_slow_fallocate(fsp
, offset
, num_to_write
);
777 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_FILL_SPARSE
);
781 /*******************************************************************************
782 Set a fd into blocking/nonblocking mode through VFS
783 *******************************************************************************/
785 int vfs_set_blocking(files_struct
*fsp
, bool set
)
789 #define FLAG_TO_SET O_NONBLOCK
792 #define FLAG_TO_SET O_NDELAY
794 #define FLAG_TO_SET FNDELAY
797 val
= SMB_VFS_FCNTL(fsp
, F_GETFL
, 0);
808 return SMB_VFS_FCNTL(fsp
, F_SETFL
, val
);
812 /****************************************************************************
813 Transfer some data (n bytes) between two file_struct's.
814 ****************************************************************************/
816 static ssize_t
vfs_pread_fn(void *file
, void *buf
, size_t len
, off_t offset
)
818 struct files_struct
*fsp
= (struct files_struct
*)file
;
820 return SMB_VFS_PREAD(fsp
, buf
, len
, offset
);
823 static ssize_t
vfs_pwrite_fn(void *file
, const void *buf
, size_t len
, off_t offset
)
825 struct files_struct
*fsp
= (struct files_struct
*)file
;
827 return SMB_VFS_PWRITE(fsp
, buf
, len
, offset
);
830 off_t
vfs_transfer_file(files_struct
*in
, files_struct
*out
, off_t n
)
832 return transfer_file_internal((void *)in
, (void *)out
, n
,
833 vfs_pread_fn
, vfs_pwrite_fn
);
836 /*******************************************************************
837 A vfs_readdir wrapper which just returns the file name.
838 ********************************************************************/
840 const char *vfs_readdirname(connection_struct
*conn
, void *p
,
841 SMB_STRUCT_STAT
*sbuf
, char **talloced
)
843 struct dirent
*ptr
= NULL
;
851 ptr
= SMB_VFS_READDIR(conn
, (DIR *)p
, sbuf
);
863 #ifdef HAVE_BROKEN_READDIR_NAME
864 /* using /usr/ucb/cc is BAD */
868 status
= SMB_VFS_TRANSLATE_NAME(conn
, dname
, vfs_translate_to_windows
,
869 talloc_tos(), &translated
);
870 if (NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
874 *talloced
= translated
;
875 if (!NT_STATUS_IS_OK(status
)) {
881 /*******************************************************************
882 A wrapper for vfs_chdir().
883 ********************************************************************/
885 int vfs_ChDir(connection_struct
*conn
, const struct smb_filename
*smb_fname
)
888 struct smb_filename
*cwd
= NULL
;
891 LastDir
= SMB_STRDUP("");
894 if (ISDOT(smb_fname
->base_name
)) {
898 if (*smb_fname
->base_name
== '/' &&
899 strcsequal(LastDir
,smb_fname
->base_name
)) {
903 DEBUG(4,("vfs_ChDir to %s\n", smb_fname
->base_name
));
905 ret
= SMB_VFS_CHDIR(conn
, smb_fname
);
911 * Always replace conn->cwd_fsp. We
912 * don't know if it's been modified by
913 * VFS modules in the stack.
917 cwd
= vfs_GetWd(conn
, conn
);
920 * vfs_GetWd() failed.
921 * We must be able to read cwd.
922 * Return to original directory
925 int saved_errno
= errno
;
927 if (conn
->cwd_fsp
->fsp_name
== NULL
) {
929 * Failed on the very first chdir()+getwd()
930 * for this connection. We can't
933 smb_panic("conn->cwd getwd failed\n");
938 /* Return to the previous $cwd. */
939 ret
= SMB_VFS_CHDIR(conn
, conn
->cwd_fsp
->fsp_name
);
941 smb_panic("conn->cwd getwd failed\n");
946 /* And fail the chdir(). */
950 /* vfs_GetWd() succeeded. */
951 /* Replace global cache. */
953 LastDir
= SMB_STRDUP(smb_fname
->base_name
);
956 * (Indirect) Callers of vfs_ChDir() may still hold references to the
957 * old conn->cwd_fsp->fsp_name. Move it to talloc_tos(), that way
958 * callers can use it for the lifetime of the SMB request.
960 talloc_move(talloc_tos(), &conn
->cwd_fsp
->fsp_name
);
962 conn
->cwd_fsp
->fsp_name
= talloc_move(conn
->cwd_fsp
, &cwd
);
963 conn
->cwd_fsp
->fh
->fd
= AT_FDCWD
;
965 DBG_INFO("vfs_ChDir got %s\n", fsp_str_dbg(conn
->cwd_fsp
));
970 /*******************************************************************
971 Return the absolute current directory path - given a UNIX pathname.
972 Note that this path is returned in DOS format, not UNIX
973 format. Note this can be called with conn == NULL.
974 ********************************************************************/
976 struct smb_filename
*vfs_GetWd(TALLOC_CTX
*ctx
, connection_struct
*conn
)
978 struct smb_filename
*current_dir_fname
= NULL
;
980 struct smb_filename
*smb_fname_dot
= NULL
;
981 struct smb_filename
*smb_fname_full
= NULL
;
982 struct smb_filename
*result
= NULL
;
984 if (!lp_getwd_cache()) {
988 smb_fname_dot
= synthetic_smb_fname(ctx
,
994 if (smb_fname_dot
== NULL
) {
999 if (SMB_VFS_STAT(conn
, smb_fname_dot
) == -1) {
1001 * Known to fail for root: the directory may be NFS-mounted
1002 * and exported with root_squash (so has no root access).
1004 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
1005 "(NFS problem ?)\n", strerror(errno
) ));
1009 key
= vfs_file_id_from_sbuf(conn
, &smb_fname_dot
->st
);
1011 smb_fname_full
= (struct smb_filename
*)memcache_lookup_talloc(
1014 data_blob_const(&key
, sizeof(key
)));
1016 if (smb_fname_full
== NULL
) {
1020 if ((SMB_VFS_STAT(conn
, smb_fname_full
) == 0) &&
1021 (smb_fname_dot
->st
.st_ex_dev
== smb_fname_full
->st
.st_ex_dev
) &&
1022 (smb_fname_dot
->st
.st_ex_ino
== smb_fname_full
->st
.st_ex_ino
) &&
1023 (S_ISDIR(smb_fname_dot
->st
.st_ex_mode
))) {
1026 * Note: smb_fname_full is owned by smbd_memcache()
1027 * so we must make a copy to return.
1029 result
= cp_smb_filename(ctx
, smb_fname_full
);
1030 if (result
== NULL
) {
1039 * We don't have the information to hand so rely on traditional
1040 * methods. The very slow getcwd, which spawns a process on some
1041 * systems, or the not quite so bad getwd.
1044 current_dir_fname
= SMB_VFS_GETWD(conn
, ctx
);
1045 if (current_dir_fname
== NULL
) {
1046 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
1051 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot
->st
)) {
1052 key
= vfs_file_id_from_sbuf(conn
, &smb_fname_dot
->st
);
1055 * smbd_memcache() will own current_dir_fname after the
1056 * memcache_add_talloc call, so we must make
1057 * a copy on ctx to return.
1059 result
= cp_smb_filename(ctx
, current_dir_fname
);
1060 if (result
== NULL
) {
1065 * Ensure the memory going into the cache
1066 * doesn't have a destructor so it can be
1069 talloc_set_destructor(current_dir_fname
, NULL
);
1071 memcache_add_talloc(smbd_memcache(),
1073 data_blob_const(&key
, sizeof(key
)),
1074 ¤t_dir_fname
);
1075 /* current_dir_fname is now == NULL here. */
1077 /* current_dir_fname is already allocated on ctx. */
1078 result
= current_dir_fname
;
1082 TALLOC_FREE(smb_fname_dot
);
1084 * Don't free current_dir_fname here. It's either been moved
1085 * to the memcache or is being returned in result.
1090 /*******************************************************************
1091 Reduce a file name, removing .. elements and checking that
1092 it is below dir in the hierarchy. This uses realpath.
1093 This function must run as root, and will return names
1094 and valid stat structs that can be checked on open.
1095 ********************************************************************/
1097 NTSTATUS
check_reduced_name_with_privilege(connection_struct
*conn
,
1098 const struct smb_filename
*smb_fname
,
1099 struct smb_request
*smbreq
)
1102 TALLOC_CTX
*ctx
= talloc_tos();
1103 const char *conn_rootdir
;
1105 char *resolved_name
= NULL
;
1106 struct smb_filename
*resolved_fname
= NULL
;
1107 struct smb_filename
*saved_dir_fname
= NULL
;
1108 struct smb_filename
*smb_fname_cwd
= NULL
;
1110 struct smb_filename
*parent_name
= NULL
;
1111 struct smb_filename
*file_name
= NULL
;
1114 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
1115 smb_fname
->base_name
,
1116 conn
->connectpath
));
1119 ok
= parent_smb_fname(ctx
,
1124 status
= NT_STATUS_NO_MEMORY
;
1128 if (SMB_VFS_STAT(conn
, parent_name
) != 0) {
1129 status
= map_nt_error_from_unix(errno
);
1132 /* Remember where we were. */
1133 saved_dir_fname
= vfs_GetWd(ctx
, conn
);
1134 if (!saved_dir_fname
) {
1135 status
= map_nt_error_from_unix(errno
);
1139 if (vfs_ChDir(conn
, parent_name
) == -1) {
1140 status
= map_nt_error_from_unix(errno
);
1144 smb_fname_cwd
= synthetic_smb_fname(talloc_tos(),
1150 if (smb_fname_cwd
== NULL
) {
1151 status
= NT_STATUS_NO_MEMORY
;
1155 /* Get the absolute path of the parent directory. */
1156 resolved_fname
= SMB_VFS_REALPATH(conn
, ctx
, smb_fname_cwd
);
1157 if (resolved_fname
== NULL
) {
1158 status
= map_nt_error_from_unix(errno
);
1161 resolved_name
= resolved_fname
->base_name
;
1163 if (*resolved_name
!= '/') {
1164 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1165 "doesn't return absolute paths !\n"));
1166 status
= NT_STATUS_OBJECT_NAME_INVALID
;
1170 DBG_DEBUG("realpath [%s] -> [%s]\n",
1171 smb_fname_str_dbg(parent_name
),
1174 /* Now check the stat value is the same. */
1175 if (SMB_VFS_LSTAT(conn
, smb_fname_cwd
) != 0) {
1176 status
= map_nt_error_from_unix(errno
);
1180 /* Ensure we're pointing at the same place. */
1181 if (!check_same_stat(&smb_fname_cwd
->st
, &parent_name
->st
)) {
1182 DBG_ERR("device/inode/uid/gid on directory %s changed. "
1183 "Denying access !\n",
1184 smb_fname_str_dbg(parent_name
));
1185 status
= NT_STATUS_ACCESS_DENIED
;
1189 /* Ensure we're below the connect path. */
1191 conn_rootdir
= SMB_VFS_CONNECTPATH(conn
, smb_fname
);
1192 if (conn_rootdir
== NULL
) {
1193 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1195 status
= NT_STATUS_ACCESS_DENIED
;
1199 rootdir_len
= strlen(conn_rootdir
);
1202 * In the case of rootdir_len == 1, we know that conn_rootdir is
1203 * "/", and we also know that resolved_name starts with a slash.
1204 * So, in this corner case, resolved_name is automatically a
1205 * sub-directory of the conn_rootdir. Thus we can skip the string
1206 * comparison and the next character checks (which are even
1207 * wrong in this case).
1209 if (rootdir_len
!= 1) {
1212 matched
= (strncmp(conn_rootdir
, resolved_name
,
1215 if (!matched
|| (resolved_name
[rootdir_len
] != '/' &&
1216 resolved_name
[rootdir_len
] != '\0')) {
1217 DBG_WARNING("%s is a symlink outside the "
1219 smb_fname_str_dbg(parent_name
));
1220 DEBUGADD(1, ("conn_rootdir =%s\n", conn_rootdir
));
1221 DEBUGADD(1, ("resolved_name=%s\n", resolved_name
));
1222 status
= NT_STATUS_ACCESS_DENIED
;
1227 /* Now ensure that the last component either doesn't
1228 exist, or is *NOT* a symlink. */
1230 ret
= SMB_VFS_LSTAT(conn
, file_name
);
1232 /* Errno must be ENOENT for this be ok. */
1233 if (errno
!= ENOENT
) {
1234 status
= map_nt_error_from_unix(errno
);
1235 DBG_WARNING("LSTAT on %s failed with %s\n",
1236 smb_fname_str_dbg(file_name
),
1242 if (VALID_STAT(file_name
->st
) &&
1243 S_ISLNK(file_name
->st
.st_ex_mode
))
1245 DBG_WARNING("Last component %s is a symlink. Denying"
1247 smb_fname_str_dbg(file_name
));
1248 status
= NT_STATUS_ACCESS_DENIED
;
1252 status
= NT_STATUS_OK
;
1256 if (saved_dir_fname
!= NULL
) {
1257 vfs_ChDir(conn
, saved_dir_fname
);
1258 TALLOC_FREE(saved_dir_fname
);
1260 TALLOC_FREE(resolved_fname
);
1261 TALLOC_FREE(parent_name
);
1265 /*******************************************************************
1266 Reduce a file name, removing .. elements and checking that
1267 it is below dir in the hierarchy. This uses realpath.
1269 If cwd_name == NULL then fname is a client given path relative
1270 to the root path of the share.
1272 If cwd_name != NULL then fname is a client given path relative
1273 to cwd_name. cwd_name is relative to the root path of the share.
1274 ********************************************************************/
1276 NTSTATUS
check_reduced_name(connection_struct
*conn
,
1277 const struct smb_filename
*cwd_fname
,
1278 const struct smb_filename
*smb_fname
)
1280 TALLOC_CTX
*ctx
= talloc_tos();
1281 const char *cwd_name
= cwd_fname
? cwd_fname
->base_name
: NULL
;
1282 const char *fname
= smb_fname
->base_name
;
1283 struct smb_filename
*resolved_fname
;
1284 char *resolved_name
= NULL
;
1285 char *new_fname
= NULL
;
1286 bool allow_symlinks
= true;
1287 const char *conn_rootdir
;
1291 DBG_DEBUG("check_reduced_name [%s] [%s]\n", fname
, conn
->connectpath
);
1293 resolved_fname
= SMB_VFS_REALPATH(conn
, ctx
, smb_fname
);
1295 if (resolved_fname
== NULL
) {
1298 DEBUG(3,("check_reduced_name: Component not a "
1299 "directory in getting realpath for "
1301 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1304 struct smb_filename
*dir_fname
= NULL
;
1305 struct smb_filename
*last_component
= NULL
;
1307 /* Last component didn't exist.
1308 Remove it and try and canonicalise
1309 the directory name. */
1311 ok
= parent_smb_fname(ctx
,
1316 return NT_STATUS_NO_MEMORY
;
1319 resolved_fname
= SMB_VFS_REALPATH(conn
,
1322 if (resolved_fname
== NULL
) {
1323 NTSTATUS status
= map_nt_error_from_unix(errno
);
1325 if (errno
== ENOENT
|| errno
== ENOTDIR
) {
1326 status
= NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1329 DEBUG(3,("check_reduce_name: "
1330 "couldn't get realpath for "
1332 smb_fname_str_dbg(dir_fname
),
1333 nt_errstr(status
)));
1336 resolved_name
= talloc_asprintf(ctx
,
1338 resolved_fname
->base_name
,
1339 last_component
->base_name
);
1340 if (resolved_name
== NULL
) {
1341 return NT_STATUS_NO_MEMORY
;
1346 DEBUG(3,("check_reduced_name: couldn't get "
1347 "realpath for %s\n", fname
));
1348 return map_nt_error_from_unix(errno
);
1351 resolved_name
= resolved_fname
->base_name
;
1354 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname
,
1357 if (*resolved_name
!= '/') {
1358 DEBUG(0,("check_reduced_name: realpath doesn't return "
1359 "absolute paths !\n"));
1360 TALLOC_FREE(resolved_fname
);
1361 return NT_STATUS_OBJECT_NAME_INVALID
;
1364 /* Common widelinks and symlinks checks. */
1365 conn_rootdir
= SMB_VFS_CONNECTPATH(conn
, smb_fname
);
1366 if (conn_rootdir
== NULL
) {
1367 DBG_NOTICE("Could not get conn_rootdir\n");
1368 TALLOC_FREE(resolved_fname
);
1369 return NT_STATUS_ACCESS_DENIED
;
1372 rootdir_len
= strlen(conn_rootdir
);
1375 * In the case of rootdir_len == 1, we know that
1376 * conn_rootdir is "/", and we also know that
1377 * resolved_name starts with a slash. So, in this
1378 * corner case, resolved_name is automatically a
1379 * sub-directory of the conn_rootdir. Thus we can skip
1380 * the string comparison and the next character checks
1381 * (which are even wrong in this case).
1383 if (rootdir_len
!= 1) {
1386 matched
= (strncmp(conn_rootdir
, resolved_name
,
1388 if (!matched
|| (resolved_name
[rootdir_len
] != '/' &&
1389 resolved_name
[rootdir_len
] != '\0')) {
1390 DBG_NOTICE("Bad access attempt: %s is a symlink "
1393 "conn_rootdir =%s\n"
1394 "resolved_name=%s\n",
1398 TALLOC_FREE(resolved_fname
);
1399 return NT_STATUS_ACCESS_DENIED
;
1403 /* Extra checks if all symlinks are disallowed. */
1404 allow_symlinks
= lp_follow_symlinks(SNUM(conn
));
1405 if (!allow_symlinks
) {
1406 /* fname can't have changed in resolved_path. */
1407 const char *p
= &resolved_name
[rootdir_len
];
1410 * UNIX filesystem semantics, names consisting
1411 * only of "." or ".." CANNOT be symlinks.
1413 if (ISDOT(fname
) || ISDOTDOT(fname
)) {
1418 DBG_NOTICE("logic error (%c) "
1419 "in resolved_name: %s\n",
1422 TALLOC_FREE(resolved_fname
);
1423 return NT_STATUS_ACCESS_DENIED
;
1429 * If cwd_name is present and not ".",
1430 * then fname is relative to that, not
1431 * the root of the share. Make sure the
1432 * path we check is the one the client
1433 * sent (cwd_name+fname).
1435 if (cwd_name
!= NULL
&& !ISDOT(cwd_name
)) {
1436 new_fname
= talloc_asprintf(ctx
,
1440 if (new_fname
== NULL
) {
1441 TALLOC_FREE(resolved_fname
);
1442 return NT_STATUS_NO_MEMORY
;
1447 if (strcmp(fname
, p
)!=0) {
1448 DBG_NOTICE("Bad access "
1449 "attempt: %s is a symlink to %s\n",
1452 TALLOC_FREE(resolved_fname
);
1453 TALLOC_FREE(new_fname
);
1454 return NT_STATUS_ACCESS_DENIED
;
1460 DBG_INFO("%s reduced to %s\n", fname
, resolved_name
);
1461 TALLOC_FREE(resolved_fname
);
1462 TALLOC_FREE(new_fname
);
1463 return NT_STATUS_OK
;
1467 * XXX: This is temporary and there should be no callers of this once
1468 * smb_filename is plumbed through all path based operations.
1470 * Called when we know stream name parsing has already been done.
1472 int vfs_stat_smb_basename(struct connection_struct
*conn
,
1473 const struct smb_filename
*smb_fname_in
,
1474 SMB_STRUCT_STAT
*psbuf
)
1476 struct smb_filename smb_fname
= {
1477 .base_name
= discard_const_p(char, smb_fname_in
->base_name
),
1478 .flags
= smb_fname_in
->flags
,
1479 .twrp
= smb_fname_in
->twrp
,
1483 if (smb_fname
.flags
& SMB_FILENAME_POSIX_PATH
) {
1484 ret
= SMB_VFS_LSTAT(conn
, &smb_fname
);
1486 ret
= SMB_VFS_STAT(conn
, &smb_fname
);
1490 *psbuf
= smb_fname
.st
;
1496 * Ensure LSTAT is called for POSIX paths.
1499 NTSTATUS
vfs_stat_fsp(files_struct
*fsp
)
1502 struct stat_ex saved_stat
= fsp
->fsp_name
->st
;
1504 if(fsp
->fh
->fd
== -1) {
1505 if (fsp
->posix_flags
& FSP_POSIX_FLAGS_OPEN
) {
1506 ret
= SMB_VFS_LSTAT(fsp
->conn
, fsp
->fsp_name
);
1508 ret
= SMB_VFS_STAT(fsp
->conn
, fsp
->fsp_name
);
1511 ret
= SMB_VFS_FSTAT(fsp
, &fsp
->fsp_name
->st
);
1514 return map_nt_error_from_unix(errno
);
1516 update_stat_ex_from_saved_stat(&fsp
->fsp_name
->st
, &saved_stat
);
1517 return NT_STATUS_OK
;
1520 void init_smb_file_time(struct smb_file_time
*ft
)
1522 *ft
= (struct smb_file_time
) {
1523 .atime
= make_omit_timespec(),
1524 .ctime
= make_omit_timespec(),
1525 .mtime
= make_omit_timespec(),
1526 .create_time
= make_omit_timespec()
1531 * Initialize num_streams and streams, then call VFS op streaminfo
1533 NTSTATUS
vfs_streaminfo(connection_struct
*conn
,
1534 struct files_struct
*fsp
,
1535 const struct smb_filename
*smb_fname
,
1536 TALLOC_CTX
*mem_ctx
,
1537 unsigned int *num_streams
,
1538 struct stream_struct
**streams
)
1542 return SMB_VFS_STREAMINFO(conn
,
1551 generate a file_id from a stat structure
1553 struct file_id
vfs_file_id_from_sbuf(connection_struct
*conn
, const SMB_STRUCT_STAT
*sbuf
)
1555 return SMB_VFS_FILE_ID_CREATE(conn
, sbuf
);
1558 NTSTATUS
vfs_at_fspcwd(TALLOC_CTX
*mem_ctx
,
1559 struct connection_struct
*conn
,
1560 struct files_struct
**_fsp
)
1562 struct files_struct
*fsp
= NULL
;
1564 fsp
= talloc_zero(mem_ctx
, struct files_struct
);
1566 return NT_STATUS_NO_MEMORY
;
1569 fsp
->fsp_name
= synthetic_smb_fname(fsp
, ".", NULL
, NULL
, 0, 0);
1570 if (fsp
->fsp_name
== NULL
) {
1572 return NT_STATUS_NO_MEMORY
;
1575 fsp
->fh
= talloc_zero(fsp
, struct fd_handle
);
1576 if (fsp
->fh
== NULL
) {
1578 return NT_STATUS_NO_MEMORY
;
1581 fsp
->fh
->fd
= AT_FDCWD
;
1582 fsp
->fnum
= FNUM_FIELD_INVALID
;
1586 return NT_STATUS_OK
;
1589 int smb_vfs_call_connect(struct vfs_handle_struct
*handle
,
1590 const char *service
, const char *user
)
1593 return handle
->fns
->connect_fn(handle
, service
, user
);
1596 void smb_vfs_call_disconnect(struct vfs_handle_struct
*handle
)
1598 VFS_FIND(disconnect
);
1599 handle
->fns
->disconnect_fn(handle
);
1602 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct
*handle
,
1603 const struct smb_filename
*smb_fname
,
1608 VFS_FIND(disk_free
);
1609 return handle
->fns
->disk_free_fn(handle
, smb_fname
,
1610 bsize
, dfree
, dsize
);
1613 int smb_vfs_call_get_quota(struct vfs_handle_struct
*handle
,
1614 const struct smb_filename
*smb_fname
,
1615 enum SMB_QUOTA_TYPE qtype
,
1619 VFS_FIND(get_quota
);
1620 return handle
->fns
->get_quota_fn(handle
, smb_fname
, qtype
, id
, qt
);
1623 int smb_vfs_call_set_quota(struct vfs_handle_struct
*handle
,
1624 enum SMB_QUOTA_TYPE qtype
, unid_t id
,
1627 VFS_FIND(set_quota
);
1628 return handle
->fns
->set_quota_fn(handle
, qtype
, id
, qt
);
1631 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct
*handle
,
1632 struct files_struct
*fsp
,
1633 struct shadow_copy_data
*shadow_copy_data
,
1636 VFS_FIND(get_shadow_copy_data
);
1637 return handle
->fns
->get_shadow_copy_data_fn(handle
, fsp
,
1641 int smb_vfs_call_statvfs(struct vfs_handle_struct
*handle
,
1642 const struct smb_filename
*smb_fname
,
1643 struct vfs_statvfs_struct
*statbuf
)
1646 return handle
->fns
->statvfs_fn(handle
, smb_fname
, statbuf
);
1649 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct
*handle
,
1650 enum timestamp_set_resolution
*p_ts_res
)
1652 VFS_FIND(fs_capabilities
);
1653 return handle
->fns
->fs_capabilities_fn(handle
, p_ts_res
);
1656 NTSTATUS
smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct
*handle
,
1657 struct dfs_GetDFSReferral
*r
)
1659 VFS_FIND(get_dfs_referrals
);
1660 return handle
->fns
->get_dfs_referrals_fn(handle
, r
);
1663 NTSTATUS
smb_vfs_call_create_dfs_pathat(struct vfs_handle_struct
*handle
,
1664 struct files_struct
*dirfsp
,
1665 const struct smb_filename
*smb_fname
,
1666 const struct referral
*reflist
,
1667 size_t referral_count
)
1669 VFS_FIND(create_dfs_pathat
);
1670 return handle
->fns
->create_dfs_pathat_fn(handle
,
1677 NTSTATUS
smb_vfs_call_read_dfs_pathat(struct vfs_handle_struct
*handle
,
1678 TALLOC_CTX
*mem_ctx
,
1679 struct files_struct
*dirfsp
,
1680 const struct smb_filename
*smb_fname
,
1681 struct referral
**ppreflist
,
1682 size_t *preferral_count
)
1684 VFS_FIND(read_dfs_pathat
);
1685 return handle
->fns
->read_dfs_pathat_fn(handle
,
1693 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct
*handle
,
1694 struct files_struct
*fsp
,
1696 uint32_t attributes
)
1698 VFS_FIND(fdopendir
);
1699 return handle
->fns
->fdopendir_fn(handle
, fsp
, mask
, attributes
);
1702 struct dirent
*smb_vfs_call_readdir(struct vfs_handle_struct
*handle
,
1704 SMB_STRUCT_STAT
*sbuf
)
1707 return handle
->fns
->readdir_fn(handle
, dirp
, sbuf
);
1710 void smb_vfs_call_seekdir(struct vfs_handle_struct
*handle
,
1711 DIR *dirp
, long offset
)
1714 handle
->fns
->seekdir_fn(handle
, dirp
, offset
);
1717 long smb_vfs_call_telldir(struct vfs_handle_struct
*handle
,
1721 return handle
->fns
->telldir_fn(handle
, dirp
);
1724 void smb_vfs_call_rewind_dir(struct vfs_handle_struct
*handle
,
1727 VFS_FIND(rewind_dir
);
1728 handle
->fns
->rewind_dir_fn(handle
, dirp
);
1731 int smb_vfs_call_mkdirat(struct vfs_handle_struct
*handle
,
1732 struct files_struct
*dirfsp
,
1733 const struct smb_filename
*smb_fname
,
1737 return handle
->fns
->mkdirat_fn(handle
,
1743 int smb_vfs_call_closedir(struct vfs_handle_struct
*handle
,
1747 return handle
->fns
->closedir_fn(handle
, dir
);
1750 int smb_vfs_call_open(struct vfs_handle_struct
*handle
,
1751 struct smb_filename
*smb_fname
, struct files_struct
*fsp
,
1752 int flags
, mode_t mode
)
1755 return handle
->fns
->open_fn(handle
, smb_fname
, fsp
, flags
, mode
);
1758 int smb_vfs_call_openat(struct vfs_handle_struct
*handle
,
1759 const struct files_struct
*dirfsp
,
1760 const struct smb_filename
*smb_fname
,
1761 struct files_struct
*fsp
,
1766 return handle
->fns
->openat_fn(handle
,
1774 NTSTATUS
smb_vfs_call_create_file(struct vfs_handle_struct
*handle
,
1775 struct smb_request
*req
,
1776 struct files_struct
**dirfsp
,
1777 struct smb_filename
*smb_fname
,
1778 uint32_t access_mask
,
1779 uint32_t share_access
,
1780 uint32_t create_disposition
,
1781 uint32_t create_options
,
1782 uint32_t file_attributes
,
1783 uint32_t oplock_request
,
1784 const struct smb2_lease
*lease
,
1785 uint64_t allocation_size
,
1786 uint32_t private_flags
,
1787 struct security_descriptor
*sd
,
1788 struct ea_list
*ea_list
,
1789 files_struct
**result
,
1791 const struct smb2_create_blobs
*in_context_blobs
,
1792 struct smb2_create_blobs
*out_context_blobs
)
1794 VFS_FIND(create_file
);
1795 return handle
->fns
->create_file_fn(
1796 handle
, req
, dirfsp
, smb_fname
,
1797 access_mask
, share_access
, create_disposition
, create_options
,
1798 file_attributes
, oplock_request
, lease
, allocation_size
,
1799 private_flags
, sd
, ea_list
,
1800 result
, pinfo
, in_context_blobs
, out_context_blobs
);
1803 int smb_vfs_call_close(struct vfs_handle_struct
*handle
,
1804 struct files_struct
*fsp
)
1807 return handle
->fns
->close_fn(handle
, fsp
);
1810 ssize_t
smb_vfs_call_pread(struct vfs_handle_struct
*handle
,
1811 struct files_struct
*fsp
, void *data
, size_t n
,
1815 return handle
->fns
->pread_fn(handle
, fsp
, data
, n
, offset
);
1818 struct smb_vfs_call_pread_state
{
1819 ssize_t (*recv_fn
)(struct tevent_req
*req
, struct vfs_aio_state
*vfs_aio_state
);
1821 struct vfs_aio_state vfs_aio_state
;
1824 static void smb_vfs_call_pread_done(struct tevent_req
*subreq
);
1826 struct tevent_req
*smb_vfs_call_pread_send(struct vfs_handle_struct
*handle
,
1827 TALLOC_CTX
*mem_ctx
,
1828 struct tevent_context
*ev
,
1829 struct files_struct
*fsp
,
1831 size_t n
, off_t offset
)
1833 struct tevent_req
*req
, *subreq
;
1834 struct smb_vfs_call_pread_state
*state
;
1836 req
= tevent_req_create(mem_ctx
, &state
,
1837 struct smb_vfs_call_pread_state
);
1841 VFS_FIND(pread_send
);
1842 state
->recv_fn
= handle
->fns
->pread_recv_fn
;
1844 subreq
= handle
->fns
->pread_send_fn(handle
, state
, ev
, fsp
, data
, n
,
1846 if (tevent_req_nomem(subreq
, req
)) {
1847 return tevent_req_post(req
, ev
);
1849 tevent_req_set_callback(subreq
, smb_vfs_call_pread_done
, req
);
1853 static void smb_vfs_call_pread_done(struct tevent_req
*subreq
)
1855 struct tevent_req
*req
= tevent_req_callback_data(
1856 subreq
, struct tevent_req
);
1857 struct smb_vfs_call_pread_state
*state
= tevent_req_data(
1858 req
, struct smb_vfs_call_pread_state
);
1860 state
->retval
= state
->recv_fn(subreq
, &state
->vfs_aio_state
);
1861 TALLOC_FREE(subreq
);
1862 if (state
->retval
== -1) {
1863 tevent_req_error(req
, state
->vfs_aio_state
.error
);
1866 tevent_req_done(req
);
1869 ssize_t
SMB_VFS_PREAD_RECV(struct tevent_req
*req
,
1870 struct vfs_aio_state
*vfs_aio_state
)
1872 struct smb_vfs_call_pread_state
*state
= tevent_req_data(
1873 req
, struct smb_vfs_call_pread_state
);
1876 if (tevent_req_is_unix_error(req
, &vfs_aio_state
->error
)) {
1877 tevent_req_received(req
);
1880 *vfs_aio_state
= state
->vfs_aio_state
;
1881 retval
= state
->retval
;
1882 tevent_req_received(req
);
1886 ssize_t
smb_vfs_call_pwrite(struct vfs_handle_struct
*handle
,
1887 struct files_struct
*fsp
, const void *data
,
1888 size_t n
, off_t offset
)
1891 return handle
->fns
->pwrite_fn(handle
, fsp
, data
, n
, offset
);
1894 struct smb_vfs_call_pwrite_state
{
1895 ssize_t (*recv_fn
)(struct tevent_req
*req
, struct vfs_aio_state
*vfs_aio_state
);
1897 struct vfs_aio_state vfs_aio_state
;
1900 static void smb_vfs_call_pwrite_done(struct tevent_req
*subreq
);
1902 struct tevent_req
*smb_vfs_call_pwrite_send(struct vfs_handle_struct
*handle
,
1903 TALLOC_CTX
*mem_ctx
,
1904 struct tevent_context
*ev
,
1905 struct files_struct
*fsp
,
1907 size_t n
, off_t offset
)
1909 struct tevent_req
*req
, *subreq
;
1910 struct smb_vfs_call_pwrite_state
*state
;
1912 req
= tevent_req_create(mem_ctx
, &state
,
1913 struct smb_vfs_call_pwrite_state
);
1917 VFS_FIND(pwrite_send
);
1918 state
->recv_fn
= handle
->fns
->pwrite_recv_fn
;
1920 subreq
= handle
->fns
->pwrite_send_fn(handle
, state
, ev
, fsp
, data
, n
,
1922 if (tevent_req_nomem(subreq
, req
)) {
1923 return tevent_req_post(req
, ev
);
1925 tevent_req_set_callback(subreq
, smb_vfs_call_pwrite_done
, req
);
1929 static void smb_vfs_call_pwrite_done(struct tevent_req
*subreq
)
1931 struct tevent_req
*req
= tevent_req_callback_data(
1932 subreq
, struct tevent_req
);
1933 struct smb_vfs_call_pwrite_state
*state
= tevent_req_data(
1934 req
, struct smb_vfs_call_pwrite_state
);
1936 state
->retval
= state
->recv_fn(subreq
, &state
->vfs_aio_state
);
1937 TALLOC_FREE(subreq
);
1938 if (state
->retval
== -1) {
1939 tevent_req_error(req
, state
->vfs_aio_state
.error
);
1942 tevent_req_done(req
);
1945 ssize_t
SMB_VFS_PWRITE_RECV(struct tevent_req
*req
,
1946 struct vfs_aio_state
*vfs_aio_state
)
1948 struct smb_vfs_call_pwrite_state
*state
= tevent_req_data(
1949 req
, struct smb_vfs_call_pwrite_state
);
1952 if (tevent_req_is_unix_error(req
, &vfs_aio_state
->error
)) {
1953 tevent_req_received(req
);
1956 *vfs_aio_state
= state
->vfs_aio_state
;
1957 retval
= state
->retval
;
1958 tevent_req_received(req
);
1962 off_t
smb_vfs_call_lseek(struct vfs_handle_struct
*handle
,
1963 struct files_struct
*fsp
, off_t offset
,
1967 return handle
->fns
->lseek_fn(handle
, fsp
, offset
, whence
);
1970 ssize_t
smb_vfs_call_sendfile(struct vfs_handle_struct
*handle
, int tofd
,
1971 files_struct
*fromfsp
, const DATA_BLOB
*header
,
1972 off_t offset
, size_t count
)
1975 return handle
->fns
->sendfile_fn(handle
, tofd
, fromfsp
, header
, offset
,
1979 ssize_t
smb_vfs_call_recvfile(struct vfs_handle_struct
*handle
, int fromfd
,
1980 files_struct
*tofsp
, off_t offset
,
1984 return handle
->fns
->recvfile_fn(handle
, fromfd
, tofsp
, offset
, count
);
1987 int smb_vfs_call_renameat(struct vfs_handle_struct
*handle
,
1988 files_struct
*srcfsp
,
1989 const struct smb_filename
*smb_fname_src
,
1990 files_struct
*dstfsp
,
1991 const struct smb_filename
*smb_fname_dst
)
1994 return handle
->fns
->renameat_fn(handle
,
2001 struct smb_vfs_call_fsync_state
{
2002 int (*recv_fn
)(struct tevent_req
*req
, struct vfs_aio_state
*vfs_aio_state
);
2004 struct vfs_aio_state vfs_aio_state
;
2007 static void smb_vfs_call_fsync_done(struct tevent_req
*subreq
);
2009 struct tevent_req
*smb_vfs_call_fsync_send(struct vfs_handle_struct
*handle
,
2010 TALLOC_CTX
*mem_ctx
,
2011 struct tevent_context
*ev
,
2012 struct files_struct
*fsp
)
2014 struct tevent_req
*req
, *subreq
;
2015 struct smb_vfs_call_fsync_state
*state
;
2017 req
= tevent_req_create(mem_ctx
, &state
,
2018 struct smb_vfs_call_fsync_state
);
2022 VFS_FIND(fsync_send
);
2023 state
->recv_fn
= handle
->fns
->fsync_recv_fn
;
2025 subreq
= handle
->fns
->fsync_send_fn(handle
, state
, ev
, fsp
);
2026 if (tevent_req_nomem(subreq
, req
)) {
2027 return tevent_req_post(req
, ev
);
2029 tevent_req_set_callback(subreq
, smb_vfs_call_fsync_done
, req
);
2033 static void smb_vfs_call_fsync_done(struct tevent_req
*subreq
)
2035 struct tevent_req
*req
= tevent_req_callback_data(
2036 subreq
, struct tevent_req
);
2037 struct smb_vfs_call_fsync_state
*state
= tevent_req_data(
2038 req
, struct smb_vfs_call_fsync_state
);
2040 state
->retval
= state
->recv_fn(subreq
, &state
->vfs_aio_state
);
2041 TALLOC_FREE(subreq
);
2042 if (state
->retval
== -1) {
2043 tevent_req_error(req
, state
->vfs_aio_state
.error
);
2046 tevent_req_done(req
);
2049 int SMB_VFS_FSYNC_RECV(struct tevent_req
*req
, struct vfs_aio_state
*vfs_aio_state
)
2051 struct smb_vfs_call_fsync_state
*state
= tevent_req_data(
2052 req
, struct smb_vfs_call_fsync_state
);
2055 if (tevent_req_is_unix_error(req
, &vfs_aio_state
->error
)) {
2056 tevent_req_received(req
);
2059 *vfs_aio_state
= state
->vfs_aio_state
;
2060 retval
= state
->retval
;
2061 tevent_req_received(req
);
2066 * Synchronous version of fsync, built from backend
2067 * async VFS primitives. Uses a temporary sub-event
2068 * context (NOT NESTED).
2071 int smb_vfs_fsync_sync(files_struct
*fsp
)
2073 TALLOC_CTX
*frame
= talloc_stackframe();
2074 struct tevent_req
*req
= NULL
;
2075 struct vfs_aio_state aio_state
= { 0 };
2078 struct tevent_context
*ev
= samba_tevent_context_init(frame
);
2084 req
= SMB_VFS_FSYNC_SEND(talloc_tos(), ev
, fsp
);
2089 ok
= tevent_req_poll(req
, ev
);
2094 ret
= SMB_VFS_FSYNC_RECV(req
, &aio_state
);
2099 if (aio_state
.error
!= 0) {
2100 errno
= aio_state
.error
;
2105 int smb_vfs_call_stat(struct vfs_handle_struct
*handle
,
2106 struct smb_filename
*smb_fname
)
2109 return handle
->fns
->stat_fn(handle
, smb_fname
);
2112 int smb_vfs_call_fstat(struct vfs_handle_struct
*handle
,
2113 struct files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
2116 return handle
->fns
->fstat_fn(handle
, fsp
, sbuf
);
2119 int smb_vfs_call_lstat(struct vfs_handle_struct
*handle
,
2120 struct smb_filename
*smb_filename
)
2123 return handle
->fns
->lstat_fn(handle
, smb_filename
);
2126 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct
*handle
,
2127 struct files_struct
*fsp
,
2128 const SMB_STRUCT_STAT
*sbuf
)
2130 VFS_FIND(get_alloc_size
);
2131 return handle
->fns
->get_alloc_size_fn(handle
, fsp
, sbuf
);
2134 int smb_vfs_call_unlinkat(struct vfs_handle_struct
*handle
,
2135 struct files_struct
*dirfsp
,
2136 const struct smb_filename
*smb_fname
,
2140 return handle
->fns
->unlinkat_fn(handle
,
2146 int smb_vfs_call_chmod(struct vfs_handle_struct
*handle
,
2147 const struct smb_filename
*smb_fname
,
2151 return handle
->fns
->chmod_fn(handle
, smb_fname
, mode
);
2154 int smb_vfs_call_fchmod(struct vfs_handle_struct
*handle
,
2155 struct files_struct
*fsp
, mode_t mode
)
2158 return handle
->fns
->fchmod_fn(handle
, fsp
, mode
);
2161 int smb_vfs_call_fchown(struct vfs_handle_struct
*handle
,
2162 struct files_struct
*fsp
, uid_t uid
, gid_t gid
)
2165 return handle
->fns
->fchown_fn(handle
, fsp
, uid
, gid
);
2168 int smb_vfs_call_lchown(struct vfs_handle_struct
*handle
,
2169 const struct smb_filename
*smb_fname
,
2174 return handle
->fns
->lchown_fn(handle
, smb_fname
, uid
, gid
);
2177 int smb_vfs_call_chdir(struct vfs_handle_struct
*handle
,
2178 const struct smb_filename
*smb_fname
)
2181 return handle
->fns
->chdir_fn(handle
, smb_fname
);
2184 struct smb_filename
*smb_vfs_call_getwd(struct vfs_handle_struct
*handle
,
2188 return handle
->fns
->getwd_fn(handle
, ctx
);
2191 int smb_vfs_call_ntimes(struct vfs_handle_struct
*handle
,
2192 const struct smb_filename
*smb_fname
,
2193 struct smb_file_time
*ft
)
2196 return handle
->fns
->ntimes_fn(handle
, smb_fname
, ft
);
2199 int smb_vfs_call_ftruncate(struct vfs_handle_struct
*handle
,
2200 struct files_struct
*fsp
, off_t offset
)
2202 VFS_FIND(ftruncate
);
2203 return handle
->fns
->ftruncate_fn(handle
, fsp
, offset
);
2206 int smb_vfs_call_fallocate(struct vfs_handle_struct
*handle
,
2207 struct files_struct
*fsp
,
2212 VFS_FIND(fallocate
);
2213 return handle
->fns
->fallocate_fn(handle
, fsp
, mode
, offset
, len
);
2216 int smb_vfs_call_kernel_flock(struct vfs_handle_struct
*handle
,
2217 struct files_struct
*fsp
, uint32_t share_mode
,
2218 uint32_t access_mask
)
2220 VFS_FIND(kernel_flock
);
2221 return handle
->fns
->kernel_flock_fn(handle
, fsp
, share_mode
,
2225 int smb_vfs_call_fcntl(struct vfs_handle_struct
*handle
,
2226 struct files_struct
*fsp
, int cmd
, ...)
2233 va_start(cmd_arg
, cmd
);
2234 result
= handle
->fns
->fcntl_fn(handle
, fsp
, cmd
, cmd_arg
);
2240 int smb_vfs_call_linux_setlease(struct vfs_handle_struct
*handle
,
2241 struct files_struct
*fsp
, int leasetype
)
2243 VFS_FIND(linux_setlease
);
2244 return handle
->fns
->linux_setlease_fn(handle
, fsp
, leasetype
);
2247 int smb_vfs_call_symlinkat(struct vfs_handle_struct
*handle
,
2248 const struct smb_filename
*link_target
,
2249 struct files_struct
*dirfsp
,
2250 const struct smb_filename
*new_smb_fname
)
2252 VFS_FIND(symlinkat
);
2253 return handle
->fns
->symlinkat_fn(handle
,
2259 int smb_vfs_call_readlinkat(struct vfs_handle_struct
*handle
,
2260 files_struct
*dirfsp
,
2261 const struct smb_filename
*smb_fname
,
2265 VFS_FIND(readlinkat
);
2266 return handle
->fns
->readlinkat_fn(handle
,
2273 int smb_vfs_call_linkat(struct vfs_handle_struct
*handle
,
2274 struct files_struct
*srcfsp
,
2275 const struct smb_filename
*old_smb_fname
,
2276 struct files_struct
*dstfsp
,
2277 const struct smb_filename
*new_smb_fname
,
2281 return handle
->fns
->linkat_fn(handle
,
2289 int smb_vfs_call_mknodat(struct vfs_handle_struct
*handle
,
2290 struct files_struct
*dirfsp
,
2291 const struct smb_filename
*smb_fname
,
2296 return handle
->fns
->mknodat_fn(handle
,
2303 struct smb_filename
*smb_vfs_call_realpath(struct vfs_handle_struct
*handle
,
2305 const struct smb_filename
*smb_fname
)
2308 return handle
->fns
->realpath_fn(handle
, ctx
, smb_fname
);
2311 int smb_vfs_call_chflags(struct vfs_handle_struct
*handle
,
2312 const struct smb_filename
*smb_fname
,
2316 return handle
->fns
->chflags_fn(handle
, smb_fname
, flags
);
2319 struct file_id
smb_vfs_call_file_id_create(struct vfs_handle_struct
*handle
,
2320 const SMB_STRUCT_STAT
*sbuf
)
2322 VFS_FIND(file_id_create
);
2323 return handle
->fns
->file_id_create_fn(handle
, sbuf
);
2326 uint64_t smb_vfs_call_fs_file_id(struct vfs_handle_struct
*handle
,
2327 const SMB_STRUCT_STAT
*sbuf
)
2329 VFS_FIND(fs_file_id
);
2330 return handle
->fns
->fs_file_id_fn(handle
, sbuf
);
2333 NTSTATUS
smb_vfs_call_streaminfo(struct vfs_handle_struct
*handle
,
2334 struct files_struct
*fsp
,
2335 const struct smb_filename
*smb_fname
,
2336 TALLOC_CTX
*mem_ctx
,
2337 unsigned int *num_streams
,
2338 struct stream_struct
**streams
)
2340 VFS_FIND(streaminfo
);
2341 return handle
->fns
->streaminfo_fn(handle
, fsp
, smb_fname
, mem_ctx
,
2342 num_streams
, streams
);
2345 int smb_vfs_call_get_real_filename(struct vfs_handle_struct
*handle
,
2346 const struct smb_filename
*path
,
2348 TALLOC_CTX
*mem_ctx
,
2351 VFS_FIND(get_real_filename
);
2352 return handle
->fns
->get_real_filename_fn(handle
, path
, name
, mem_ctx
,
2356 const char *smb_vfs_call_connectpath(struct vfs_handle_struct
*handle
,
2357 const struct smb_filename
*smb_fname
)
2359 VFS_FIND(connectpath
);
2360 return handle
->fns
->connectpath_fn(handle
, smb_fname
);
2363 bool smb_vfs_call_strict_lock_check(struct vfs_handle_struct
*handle
,
2364 struct files_struct
*fsp
,
2365 struct lock_struct
*plock
)
2367 VFS_FIND(strict_lock_check
);
2368 return handle
->fns
->strict_lock_check_fn(handle
, fsp
, plock
);
2371 NTSTATUS
smb_vfs_call_translate_name(struct vfs_handle_struct
*handle
,
2373 enum vfs_translate_direction direction
,
2374 TALLOC_CTX
*mem_ctx
,
2377 VFS_FIND(translate_name
);
2378 return handle
->fns
->translate_name_fn(handle
, name
, direction
, mem_ctx
,
2382 NTSTATUS
smb_vfs_call_fsctl(struct vfs_handle_struct
*handle
,
2383 struct files_struct
*fsp
,
2387 const uint8_t *in_data
,
2390 uint32_t max_out_len
,
2394 return handle
->fns
->fsctl_fn(handle
, fsp
, ctx
, function
, req_flags
,
2395 in_data
, in_len
, out_data
, max_out_len
,
2399 NTSTATUS
smb_vfs_call_get_dos_attributes(struct vfs_handle_struct
*handle
,
2400 struct smb_filename
*smb_fname
,
2403 VFS_FIND(get_dos_attributes
);
2404 return handle
->fns
->get_dos_attributes_fn(handle
, smb_fname
, dosmode
);
2407 NTSTATUS
smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct
*handle
,
2408 struct files_struct
*fsp
,
2411 VFS_FIND(fget_dos_attributes
);
2412 return handle
->fns
->fget_dos_attributes_fn(handle
, fsp
, dosmode
);
2415 NTSTATUS
smb_vfs_call_set_dos_attributes(struct vfs_handle_struct
*handle
,
2416 const struct smb_filename
*smb_fname
,
2419 VFS_FIND(set_dos_attributes
);
2420 return handle
->fns
->set_dos_attributes_fn(handle
, smb_fname
, dosmode
);
2423 NTSTATUS
smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct
*handle
,
2424 struct files_struct
*fsp
,
2427 VFS_FIND(set_dos_attributes
);
2428 return handle
->fns
->fset_dos_attributes_fn(handle
, fsp
, dosmode
);
2431 struct tevent_req
*smb_vfs_call_offload_read_send(TALLOC_CTX
*mem_ctx
,
2432 struct tevent_context
*ev
,
2433 struct vfs_handle_struct
*handle
,
2434 struct files_struct
*fsp
,
2440 VFS_FIND(offload_read_send
);
2441 return handle
->fns
->offload_read_send_fn(mem_ctx
, ev
, handle
,
2443 ttl
, offset
, to_copy
);
2446 NTSTATUS
smb_vfs_call_offload_read_recv(struct tevent_req
*req
,
2447 struct vfs_handle_struct
*handle
,
2448 TALLOC_CTX
*mem_ctx
,
2449 DATA_BLOB
*token_blob
)
2451 VFS_FIND(offload_read_recv
);
2452 return handle
->fns
->offload_read_recv_fn(req
, handle
, mem_ctx
, token_blob
);
2455 struct tevent_req
*smb_vfs_call_offload_write_send(struct vfs_handle_struct
*handle
,
2456 TALLOC_CTX
*mem_ctx
,
2457 struct tevent_context
*ev
,
2460 off_t transfer_offset
,
2461 struct files_struct
*dest_fsp
,
2465 VFS_FIND(offload_write_send
);
2466 return handle
->fns
->offload_write_send_fn(handle
, mem_ctx
, ev
, fsctl
,
2467 token
, transfer_offset
,
2468 dest_fsp
, dest_off
, num
);
2471 NTSTATUS
smb_vfs_call_offload_write_recv(struct vfs_handle_struct
*handle
,
2472 struct tevent_req
*req
,
2475 VFS_FIND(offload_write_recv
);
2476 return handle
->fns
->offload_write_recv_fn(handle
, req
, copied
);
2479 struct smb_vfs_call_get_dos_attributes_state
{
2480 files_struct
*dir_fsp
;
2481 NTSTATUS (*recv_fn
)(struct tevent_req
*req
,
2482 struct vfs_aio_state
*aio_state
,
2484 struct vfs_aio_state aio_state
;
2485 uint32_t dos_attributes
;
2488 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req
*subreq
);
2490 struct tevent_req
*smb_vfs_call_get_dos_attributes_send(
2491 TALLOC_CTX
*mem_ctx
,
2492 struct tevent_context
*ev
,
2493 struct vfs_handle_struct
*handle
,
2494 files_struct
*dir_fsp
,
2495 struct smb_filename
*smb_fname
)
2497 struct tevent_req
*req
= NULL
;
2498 struct smb_vfs_call_get_dos_attributes_state
*state
= NULL
;
2499 struct tevent_req
*subreq
= NULL
;
2501 req
= tevent_req_create(mem_ctx
, &state
,
2502 struct smb_vfs_call_get_dos_attributes_state
);
2507 VFS_FIND(get_dos_attributes_send
);
2509 *state
= (struct smb_vfs_call_get_dos_attributes_state
) {
2511 .recv_fn
= handle
->fns
->get_dos_attributes_recv_fn
,
2514 subreq
= handle
->fns
->get_dos_attributes_send_fn(mem_ctx
,
2519 if (tevent_req_nomem(subreq
, req
)) {
2520 return tevent_req_post(req
, ev
);
2522 tevent_req_defer_callback(req
, ev
);
2524 tevent_req_set_callback(subreq
,
2525 smb_vfs_call_get_dos_attributes_done
,
2531 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req
*subreq
)
2533 struct tevent_req
*req
=
2534 tevent_req_callback_data(subreq
,
2536 struct smb_vfs_call_get_dos_attributes_state
*state
=
2537 tevent_req_data(req
,
2538 struct smb_vfs_call_get_dos_attributes_state
);
2543 * Make sure we run as the user again
2545 ok
= change_to_user_and_service_by_fsp(state
->dir_fsp
);
2548 status
= state
->recv_fn(subreq
,
2550 &state
->dos_attributes
);
2551 TALLOC_FREE(subreq
);
2552 if (tevent_req_nterror(req
, status
)) {
2556 tevent_req_done(req
);
2559 NTSTATUS
smb_vfs_call_get_dos_attributes_recv(
2560 struct tevent_req
*req
,
2561 struct vfs_aio_state
*aio_state
,
2562 uint32_t *dos_attributes
)
2564 struct smb_vfs_call_get_dos_attributes_state
*state
=
2565 tevent_req_data(req
,
2566 struct smb_vfs_call_get_dos_attributes_state
);
2569 if (tevent_req_is_nterror(req
, &status
)) {
2570 tevent_req_received(req
);
2574 *aio_state
= state
->aio_state
;
2575 *dos_attributes
= state
->dos_attributes
;
2576 tevent_req_received(req
);
2577 return NT_STATUS_OK
;
2580 NTSTATUS
smb_vfs_call_get_compression(vfs_handle_struct
*handle
,
2581 TALLOC_CTX
*mem_ctx
,
2582 struct files_struct
*fsp
,
2583 struct smb_filename
*smb_fname
,
2584 uint16_t *_compression_fmt
)
2586 VFS_FIND(get_compression
);
2587 return handle
->fns
->get_compression_fn(handle
, mem_ctx
, fsp
, smb_fname
,
2591 NTSTATUS
smb_vfs_call_set_compression(vfs_handle_struct
*handle
,
2592 TALLOC_CTX
*mem_ctx
,
2593 struct files_struct
*fsp
,
2594 uint16_t compression_fmt
)
2596 VFS_FIND(set_compression
);
2597 return handle
->fns
->set_compression_fn(handle
, mem_ctx
, fsp
,
2601 NTSTATUS
smb_vfs_call_snap_check_path(vfs_handle_struct
*handle
,
2602 TALLOC_CTX
*mem_ctx
,
2603 const char *service_path
,
2606 VFS_FIND(snap_check_path
);
2607 return handle
->fns
->snap_check_path_fn(handle
, mem_ctx
, service_path
,
2611 NTSTATUS
smb_vfs_call_snap_create(struct vfs_handle_struct
*handle
,
2612 TALLOC_CTX
*mem_ctx
,
2613 const char *base_volume
,
2619 VFS_FIND(snap_create
);
2620 return handle
->fns
->snap_create_fn(handle
, mem_ctx
, base_volume
, tstamp
,
2621 rw
, base_path
, snap_path
);
2624 NTSTATUS
smb_vfs_call_snap_delete(struct vfs_handle_struct
*handle
,
2625 TALLOC_CTX
*mem_ctx
,
2629 VFS_FIND(snap_delete
);
2630 return handle
->fns
->snap_delete_fn(handle
, mem_ctx
, base_path
,
2634 NTSTATUS
smb_vfs_call_fget_nt_acl(struct vfs_handle_struct
*handle
,
2635 struct files_struct
*fsp
,
2636 uint32_t security_info
,
2637 TALLOC_CTX
*mem_ctx
,
2638 struct security_descriptor
**ppdesc
)
2640 VFS_FIND(fget_nt_acl
);
2641 return handle
->fns
->fget_nt_acl_fn(handle
, fsp
, security_info
,
2645 NTSTATUS
smb_vfs_call_get_nt_acl_at(struct vfs_handle_struct
*handle
,
2646 struct files_struct
*dirfsp
,
2647 const struct smb_filename
*smb_fname
,
2648 uint32_t security_info
,
2649 TALLOC_CTX
*mem_ctx
,
2650 struct security_descriptor
**ppdesc
)
2652 VFS_FIND(get_nt_acl_at
);
2653 return handle
->fns
->get_nt_acl_at_fn(handle
,
2661 NTSTATUS
smb_vfs_call_fset_nt_acl(struct vfs_handle_struct
*handle
,
2662 struct files_struct
*fsp
,
2663 uint32_t security_info_sent
,
2664 const struct security_descriptor
*psd
)
2666 VFS_FIND(fset_nt_acl
);
2667 return handle
->fns
->fset_nt_acl_fn(handle
, fsp
, security_info_sent
,
2671 NTSTATUS
smb_vfs_call_audit_file(struct vfs_handle_struct
*handle
,
2672 struct smb_filename
*file
,
2673 struct security_acl
*sacl
,
2674 uint32_t access_requested
,
2675 uint32_t access_denied
)
2677 VFS_FIND(audit_file
);
2678 return handle
->fns
->audit_file_fn(handle
,
2685 SMB_ACL_T
smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct
*handle
,
2686 const struct smb_filename
*smb_fname
,
2687 SMB_ACL_TYPE_T type
,
2688 TALLOC_CTX
*mem_ctx
)
2690 VFS_FIND(sys_acl_get_file
);
2691 return handle
->fns
->sys_acl_get_file_fn(handle
, smb_fname
, type
, mem_ctx
);
2694 SMB_ACL_T
smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct
*handle
,
2695 struct files_struct
*fsp
,
2696 TALLOC_CTX
*mem_ctx
)
2698 VFS_FIND(sys_acl_get_fd
);
2699 return handle
->fns
->sys_acl_get_fd_fn(handle
, fsp
, mem_ctx
);
2702 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct
*handle
,
2703 const struct smb_filename
*smb_fname
,
2704 TALLOC_CTX
*mem_ctx
,
2705 char **blob_description
,
2708 VFS_FIND(sys_acl_blob_get_file
);
2709 return handle
->fns
->sys_acl_blob_get_file_fn(handle
, smb_fname
,
2710 mem_ctx
, blob_description
, blob
);
2713 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct
*handle
,
2714 struct files_struct
*fsp
,
2715 TALLOC_CTX
*mem_ctx
,
2716 char **blob_description
,
2719 VFS_FIND(sys_acl_blob_get_fd
);
2720 return handle
->fns
->sys_acl_blob_get_fd_fn(handle
, fsp
, mem_ctx
, blob_description
, blob
);
2723 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct
*handle
,
2724 const struct smb_filename
*smb_fname
,
2725 SMB_ACL_TYPE_T acltype
,
2728 VFS_FIND(sys_acl_set_file
);
2729 return handle
->fns
->sys_acl_set_file_fn(handle
, smb_fname
,
2733 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct
*handle
,
2734 struct files_struct
*fsp
, SMB_ACL_T theacl
)
2736 VFS_FIND(sys_acl_set_fd
);
2737 return handle
->fns
->sys_acl_set_fd_fn(handle
, fsp
, theacl
);
2740 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct
*handle
,
2741 const struct smb_filename
*smb_fname
)
2743 VFS_FIND(sys_acl_delete_def_file
);
2744 return handle
->fns
->sys_acl_delete_def_file_fn(handle
, smb_fname
);
2747 ssize_t
smb_vfs_call_getxattr(struct vfs_handle_struct
*handle
,
2748 const struct smb_filename
*smb_fname
,
2754 return handle
->fns
->getxattr_fn(handle
, smb_fname
, name
, value
, size
);
2758 struct smb_vfs_call_getxattrat_state
{
2759 files_struct
*dir_fsp
;
2760 ssize_t (*recv_fn
)(struct tevent_req
*req
,
2761 struct vfs_aio_state
*aio_state
,
2762 TALLOC_CTX
*mem_ctx
,
2763 uint8_t **xattr_value
);
2765 uint8_t *xattr_value
;
2766 struct vfs_aio_state aio_state
;
2769 static void smb_vfs_call_getxattrat_done(struct tevent_req
*subreq
);
2771 struct tevent_req
*smb_vfs_call_getxattrat_send(
2772 TALLOC_CTX
*mem_ctx
,
2773 struct tevent_context
*ev
,
2774 struct vfs_handle_struct
*handle
,
2775 files_struct
*dir_fsp
,
2776 const struct smb_filename
*smb_fname
,
2777 const char *xattr_name
,
2780 struct tevent_req
*req
= NULL
;
2781 struct smb_vfs_call_getxattrat_state
*state
= NULL
;
2782 struct tevent_req
*subreq
= NULL
;
2784 req
= tevent_req_create(mem_ctx
, &state
,
2785 struct smb_vfs_call_getxattrat_state
);
2790 VFS_FIND(getxattrat_send
);
2792 *state
= (struct smb_vfs_call_getxattrat_state
) {
2794 .recv_fn
= handle
->fns
->getxattrat_recv_fn
,
2797 subreq
= handle
->fns
->getxattrat_send_fn(mem_ctx
,
2804 if (tevent_req_nomem(subreq
, req
)) {
2805 return tevent_req_post(req
, ev
);
2807 tevent_req_defer_callback(req
, ev
);
2809 tevent_req_set_callback(subreq
, smb_vfs_call_getxattrat_done
, req
);
2813 static void smb_vfs_call_getxattrat_done(struct tevent_req
*subreq
)
2815 struct tevent_req
*req
= tevent_req_callback_data(
2816 subreq
, struct tevent_req
);
2817 struct smb_vfs_call_getxattrat_state
*state
= tevent_req_data(
2818 req
, struct smb_vfs_call_getxattrat_state
);
2822 * Make sure we run as the user again
2824 ok
= change_to_user_and_service_by_fsp(state
->dir_fsp
);
2827 state
->retval
= state
->recv_fn(subreq
,
2830 &state
->xattr_value
);
2831 TALLOC_FREE(subreq
);
2832 if (state
->retval
== -1) {
2833 tevent_req_error(req
, state
->aio_state
.error
);
2837 tevent_req_done(req
);
2840 ssize_t
smb_vfs_call_getxattrat_recv(struct tevent_req
*req
,
2841 struct vfs_aio_state
*aio_state
,
2842 TALLOC_CTX
*mem_ctx
,
2843 uint8_t **xattr_value
)
2845 struct smb_vfs_call_getxattrat_state
*state
= tevent_req_data(
2846 req
, struct smb_vfs_call_getxattrat_state
);
2849 if (tevent_req_is_unix_error(req
, &aio_state
->error
)) {
2850 tevent_req_received(req
);
2854 *aio_state
= state
->aio_state
;
2855 xattr_size
= state
->retval
;
2856 if (xattr_value
!= NULL
) {
2857 *xattr_value
= talloc_move(mem_ctx
, &state
->xattr_value
);
2860 tevent_req_received(req
);
2864 ssize_t
smb_vfs_call_fgetxattr(struct vfs_handle_struct
*handle
,
2865 struct files_struct
*fsp
, const char *name
,
2866 void *value
, size_t size
)
2868 VFS_FIND(fgetxattr
);
2869 return handle
->fns
->fgetxattr_fn(handle
, fsp
, name
, value
, size
);
2872 ssize_t
smb_vfs_call_listxattr(struct vfs_handle_struct
*handle
,
2873 const struct smb_filename
*smb_fname
,
2877 VFS_FIND(listxattr
);
2878 return handle
->fns
->listxattr_fn(handle
, smb_fname
, list
, size
);
2881 ssize_t
smb_vfs_call_flistxattr(struct vfs_handle_struct
*handle
,
2882 struct files_struct
*fsp
, char *list
,
2885 VFS_FIND(flistxattr
);
2886 return handle
->fns
->flistxattr_fn(handle
, fsp
, list
, size
);
2889 int smb_vfs_call_removexattr(struct vfs_handle_struct
*handle
,
2890 const struct smb_filename
*smb_fname
,
2893 VFS_FIND(removexattr
);
2894 return handle
->fns
->removexattr_fn(handle
, smb_fname
, name
);
2897 int smb_vfs_call_fremovexattr(struct vfs_handle_struct
*handle
,
2898 struct files_struct
*fsp
, const char *name
)
2900 VFS_FIND(fremovexattr
);
2901 return handle
->fns
->fremovexattr_fn(handle
, fsp
, name
);
2904 int smb_vfs_call_setxattr(struct vfs_handle_struct
*handle
,
2905 const struct smb_filename
*smb_fname
,
2912 return handle
->fns
->setxattr_fn(handle
, smb_fname
,
2913 name
, value
, size
, flags
);
2916 int smb_vfs_call_fsetxattr(struct vfs_handle_struct
*handle
,
2917 struct files_struct
*fsp
, const char *name
,
2918 const void *value
, size_t size
, int flags
)
2920 VFS_FIND(fsetxattr
);
2921 return handle
->fns
->fsetxattr_fn(handle
, fsp
, name
, value
, size
, flags
);
2924 bool smb_vfs_call_aio_force(struct vfs_handle_struct
*handle
,
2925 struct files_struct
*fsp
)
2927 VFS_FIND(aio_force
);
2928 return handle
->fns
->aio_force_fn(handle
, fsp
);
2931 NTSTATUS
smb_vfs_call_durable_cookie(struct vfs_handle_struct
*handle
,
2932 struct files_struct
*fsp
,
2933 TALLOC_CTX
*mem_ctx
,
2936 VFS_FIND(durable_cookie
);
2937 return handle
->fns
->durable_cookie_fn(handle
, fsp
, mem_ctx
, cookie
);
2940 NTSTATUS
smb_vfs_call_durable_disconnect(struct vfs_handle_struct
*handle
,
2941 struct files_struct
*fsp
,
2942 const DATA_BLOB old_cookie
,
2943 TALLOC_CTX
*mem_ctx
,
2944 DATA_BLOB
*new_cookie
)
2946 VFS_FIND(durable_disconnect
);
2947 return handle
->fns
->durable_disconnect_fn(handle
, fsp
, old_cookie
,
2948 mem_ctx
, new_cookie
);
2951 NTSTATUS
smb_vfs_call_durable_reconnect(struct vfs_handle_struct
*handle
,
2952 struct smb_request
*smb1req
,
2953 struct smbXsrv_open
*op
,
2954 const DATA_BLOB old_cookie
,
2955 TALLOC_CTX
*mem_ctx
,
2956 struct files_struct
**fsp
,
2957 DATA_BLOB
*new_cookie
)
2959 VFS_FIND(durable_reconnect
);
2960 return handle
->fns
->durable_reconnect_fn(handle
, smb1req
, op
,
2961 old_cookie
, mem_ctx
, fsp
,
2965 NTSTATUS
smb_vfs_call_readdir_attr(struct vfs_handle_struct
*handle
,
2966 const struct smb_filename
*fname
,
2967 TALLOC_CTX
*mem_ctx
,
2968 struct readdir_attr_data
**attr_data
)
2970 VFS_FIND(readdir_attr
);
2971 return handle
->fns
->readdir_attr_fn(handle
, fname
, mem_ctx
, attr_data
);