2 Unix SMB/Netbios implementation.
4 VFS initialisation and support functions
5 Copyright (C) Tim Potter 1999
6 Copyright (C) Alexander Bokovoy 2002
7 Copyright (C) James Peach 2006
8 Copyright (C) Volker Lendecke 2009
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 This work was sponsored by Optifacio Software Services, Inc.
27 #include "system/filesys.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "../lib/util/memcache.h"
31 #include "transfer_file.h"
33 #include "lib/util/tevent_unix.h"
34 #include "lib/util/tevent_ntstatus.h"
37 #define DBGC_CLASS DBGC_VFS
42 struct vfs_fsp_data
*next
;
43 struct vfs_handle_struct
*owner
;
44 void (*destroy
)(void *p_data
);
46 /* NOTE: This structure contains four pointers so that we can guarantee
47 * that the end of the structure is always both 4-byte and 8-byte aligned.
51 struct vfs_init_function_entry
{
53 struct vfs_init_function_entry
*prev
, *next
;
54 const struct vfs_fn_pointers
*fns
;
57 /****************************************************************************
58 maintain the list of available backends
59 ****************************************************************************/
61 static struct vfs_init_function_entry
*vfs_find_backend_entry(const char *name
)
63 struct vfs_init_function_entry
*entry
= backends
;
65 DEBUG(10, ("vfs_find_backend_entry called for %s\n", name
));
68 if (strcmp(entry
->name
, name
)==0) return entry
;
75 NTSTATUS
smb_register_vfs(int version
, const char *name
,
76 const struct vfs_fn_pointers
*fns
)
78 struct vfs_init_function_entry
*entry
= backends
;
80 if ((version
!= SMB_VFS_INTERFACE_VERSION
)) {
81 DEBUG(0, ("Failed to register vfs module.\n"
82 "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
83 "current SMB_VFS_INTERFACE_VERSION is %d.\n"
84 "Please recompile against the current Samba Version!\n",
85 version
, SMB_VFS_INTERFACE_VERSION
));
86 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
89 if (!name
|| !name
[0]) {
90 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
91 return NT_STATUS_INVALID_PARAMETER
;
94 if (vfs_find_backend_entry(name
)) {
95 DEBUG(0,("VFS module %s already loaded!\n", name
));
96 return NT_STATUS_OBJECT_NAME_COLLISION
;
99 entry
= SMB_XMALLOC_P(struct vfs_init_function_entry
);
100 entry
->name
= smb_xstrdup(name
);
103 DLIST_ADD(backends
, entry
);
104 DEBUG(5, ("Successfully added vfs backend '%s'\n", name
));
108 /****************************************************************************
109 initialise default vfs hooks
110 ****************************************************************************/
112 static void vfs_init_default(connection_struct
*conn
)
114 DEBUG(3, ("Initialising default vfs hooks\n"));
115 vfs_init_custom(conn
, DEFAULT_VFS_MODULE_NAME
);
118 /****************************************************************************
119 initialise custom vfs hooks
120 ****************************************************************************/
122 bool vfs_init_custom(connection_struct
*conn
, const char *vfs_object
)
124 char *module_path
= NULL
;
125 char *module_name
= NULL
;
126 char *module_param
= NULL
, *p
;
127 vfs_handle_struct
*handle
;
128 const struct vfs_init_function_entry
*entry
;
130 if (!conn
||!vfs_object
||!vfs_object
[0]) {
131 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
132 "empty vfs_object!\n"));
137 static_init_vfs(NULL
);
140 DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object
));
142 module_path
= smb_xstrdup(vfs_object
);
144 p
= strchr_m(module_path
, ':');
149 trim_char(module_param
, ' ', ' ');
152 trim_char(module_path
, ' ', ' ');
154 module_name
= smb_xstrdup(module_path
);
156 if ((module_name
[0] == '/') &&
157 (strcmp(module_path
, DEFAULT_VFS_MODULE_NAME
) != 0)) {
160 * Extract the module name from the path. Just use the base
161 * name of the last path component.
164 SAFE_FREE(module_name
);
165 module_name
= smb_xstrdup(strrchr_m(module_path
, '/')+1);
167 p
= strchr_m(module_name
, '.');
174 /* First, try to load the module with the new module system */
175 entry
= vfs_find_backend_entry(module_name
);
179 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
182 status
= smb_load_module("vfs", module_path
);
183 if (!NT_STATUS_IS_OK(status
)) {
184 DEBUG(0, ("error probing vfs module '%s': %s\n",
185 module_path
, nt_errstr(status
)));
189 entry
= vfs_find_backend_entry(module_name
);
191 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object
));
196 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object
));
198 handle
= talloc_zero(conn
, vfs_handle_struct
);
200 DEBUG(0,("TALLOC_ZERO() failed!\n"));
204 handle
->fns
= entry
->fns
;
206 handle
->param
= talloc_strdup(conn
, module_param
);
208 DLIST_ADD(conn
->vfs_handles
, handle
);
210 SAFE_FREE(module_path
);
211 SAFE_FREE(module_name
);
215 SAFE_FREE(module_path
);
216 SAFE_FREE(module_name
);
220 /*****************************************************************
221 Allow VFS modules to extend files_struct with VFS-specific state.
222 This will be ok for small numbers of extensions, but might need to
223 be refactored if it becomes more widely used.
224 ******************************************************************/
226 #define EXT_DATA_AREA(e) ((uint8_t *)(e) + sizeof(struct vfs_fsp_data))
228 void *vfs_add_fsp_extension_notype(vfs_handle_struct
*handle
,
229 files_struct
*fsp
, size_t ext_size
,
230 void (*destroy_fn
)(void *p_data
))
232 struct vfs_fsp_data
*ext
;
235 /* Prevent VFS modules adding multiple extensions. */
236 if ((ext_data
= vfs_fetch_fsp_extension(handle
, fsp
))) {
240 ext
= (struct vfs_fsp_data
*)TALLOC_ZERO(
241 handle
->conn
, sizeof(struct vfs_fsp_data
) + ext_size
);
247 ext
->next
= fsp
->vfs_extension
;
248 ext
->destroy
= destroy_fn
;
249 fsp
->vfs_extension
= ext
;
250 return EXT_DATA_AREA(ext
);
253 void vfs_remove_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
255 struct vfs_fsp_data
*curr
;
256 struct vfs_fsp_data
*prev
;
258 for (curr
= fsp
->vfs_extension
, prev
= NULL
;
260 prev
= curr
, curr
= curr
->next
) {
261 if (curr
->owner
== handle
) {
263 prev
->next
= curr
->next
;
265 fsp
->vfs_extension
= curr
->next
;
268 curr
->destroy(EXT_DATA_AREA(curr
));
276 void vfs_remove_all_fsp_extensions(files_struct
*fsp
)
278 struct vfs_fsp_data
*curr
;
279 struct vfs_fsp_data
*next
;
281 for (curr
= fsp
->vfs_extension
; curr
; curr
= next
) {
284 fsp
->vfs_extension
= next
;
287 curr
->destroy(EXT_DATA_AREA(curr
));
293 void *vfs_memctx_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
295 struct vfs_fsp_data
*head
;
297 for (head
= fsp
->vfs_extension
; head
; head
= head
->next
) {
298 if (head
->owner
== handle
) {
306 void *vfs_fetch_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
308 struct vfs_fsp_data
*head
;
310 head
= (struct vfs_fsp_data
*)vfs_memctx_fsp_extension(handle
, fsp
);
312 return EXT_DATA_AREA(head
);
321 * Ensure this module catches all VFS functions.
324 void smb_vfs_assert_all_fns(const struct vfs_fn_pointers
* fns
,
327 bool missing_fn
= false;
329 const uintptr_t *end
= (const uintptr_t *)(fns
+ 1);
331 for (idx
= 0; ((const uintptr_t *)fns
+ idx
) < end
; idx
++) {
332 if (*((const uintptr_t *)fns
+ idx
) == 0) {
333 DBG_ERR("VFS function at index %d not implemented "
334 "in module %s\n", idx
, module
);
340 smb_panic("Required VFS function not implemented in module.\n");
344 void smb_vfs_assert_all_fns(const struct vfs_fn_pointers
* fns
,
350 /*****************************************************************
352 ******************************************************************/
354 bool smbd_vfs_init(connection_struct
*conn
)
356 const char **vfs_objects
;
360 /* Normal share - initialise with disk access functions */
361 vfs_init_default(conn
);
363 /* No need to load vfs modules for printer connections */
368 vfs_objects
= lp_vfs_objects(SNUM(conn
));
370 /* Override VFS functions if 'vfs object' was not specified*/
371 if (!vfs_objects
|| !vfs_objects
[0])
374 for (i
=0; vfs_objects
[i
] ;) {
378 for (j
=i
-1; j
>= 0; j
--) {
379 if (!vfs_init_custom(conn
, vfs_objects
[j
])) {
380 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects
[j
]));
387 /*******************************************************************
388 Check if a file exists in the vfs.
389 ********************************************************************/
391 NTSTATUS
vfs_file_exist(connection_struct
*conn
, struct smb_filename
*smb_fname
)
393 /* Only return OK if stat was successful and S_ISREG */
394 if ((SMB_VFS_STAT(conn
, smb_fname
) != -1) &&
395 S_ISREG(smb_fname
->st
.st_ex_mode
)) {
399 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
402 ssize_t
vfs_pwrite_data(struct smb_request
*req
,
411 if (req
&& req
->unread_bytes
) {
412 int sockfd
= req
->xconn
->transport
.sock
;
413 SMB_ASSERT(req
->unread_bytes
== N
);
414 /* VFS_RECVFILE must drain the socket
415 * before returning. */
416 req
->unread_bytes
= 0;
418 * Leave the socket non-blocking and
419 * use SMB_VFS_RECVFILE. If it returns
420 * EAGAIN || EWOULDBLOCK temporarily set
421 * the socket blocking and retry
425 ret
= SMB_VFS_RECVFILE(sockfd
,
429 if (ret
== 0 || (ret
== -1 &&
431 errno
== EWOULDBLOCK
))) {
433 /* Ensure the socket is blocking. */
434 old_flags
= fcntl(sockfd
, F_GETFL
, 0);
435 if (set_blocking(sockfd
, true) == -1) {
438 ret
= SMB_VFS_RECVFILE(sockfd
,
442 if (fcntl(sockfd
, F_SETFL
, old_flags
) == -1) {
449 return (ssize_t
)total
;
451 /* Any other error case. */
457 return (ssize_t
)total
;
461 ret
= SMB_VFS_PWRITE(fsp
, buffer
+ total
, N
- total
,
471 return (ssize_t
)total
;
473 /****************************************************************************
474 An allocate file space call using the vfs interface.
475 Allocates space for a file from a filedescriptor.
476 Returns 0 on success, -1 on failure.
477 ****************************************************************************/
479 int vfs_allocate_file_space(files_struct
*fsp
, uint64_t len
)
482 connection_struct
*conn
= fsp
->conn
;
483 uint64_t space_avail
;
484 uint64_t bsize
,dfree
,dsize
;
488 * Actually try and commit the space on disk....
491 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
492 fsp_str_dbg(fsp
), (double)len
));
494 if (((off_t
)len
) < 0) {
495 DEBUG(0,("vfs_allocate_file_space: %s negative len "
496 "requested.\n", fsp_str_dbg(fsp
)));
501 status
= vfs_stat_fsp(fsp
);
502 if (!NT_STATUS_IS_OK(status
)) {
506 if (len
== (uint64_t)fsp
->fsp_name
->st
.st_ex_size
)
509 if (len
< (uint64_t)fsp
->fsp_name
->st
.st_ex_size
) {
510 /* Shrink - use ftruncate. */
512 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
513 "size %.0f\n", fsp_str_dbg(fsp
),
514 (double)fsp
->fsp_name
->st
.st_ex_size
));
516 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_ALLOC_SHRINK
);
518 ret
= SMB_VFS_FTRUNCATE(fsp
, (off_t
)len
);
520 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_ALLOC_SHRINK
);
525 /* Grow - we need to test if we have enough space. */
527 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_ALLOC_GROW
);
529 if (lp_strict_allocate(SNUM(fsp
->conn
))) {
530 /* See if we have a syscall that will allocate beyond
531 end-of-file without changing EOF. */
532 ret
= SMB_VFS_FALLOCATE(fsp
, VFS_FALLOCATE_FL_KEEP_SIZE
,
538 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_ALLOC_GROW
);
541 /* We changed the allocation size on disk, but not
542 EOF - exactly as required. We're done ! */
546 if (ret
== -1 && errno
== ENOSPC
) {
550 len
-= fsp
->fsp_name
->st
.st_ex_size
;
551 len
/= 1024; /* Len is now number of 1k blocks needed. */
553 get_dfree_info(conn
, fsp
->fsp_name
, &bsize
, &dfree
, &dsize
);
554 if (space_avail
== (uint64_t)-1) {
558 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
559 "needed blocks = %.0f, space avail = %.0f\n",
560 fsp_str_dbg(fsp
), (double)fsp
->fsp_name
->st
.st_ex_size
, (double)len
,
561 (double)space_avail
));
563 if (len
> space_avail
) {
571 /****************************************************************************
572 A vfs set_filelen call.
573 set the length of a file from a filedescriptor.
574 Returns 0 on success, -1 on failure.
575 ****************************************************************************/
577 int vfs_set_filelen(files_struct
*fsp
, off_t len
)
581 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_SET_FILE_LEN
);
583 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
584 fsp_str_dbg(fsp
), (double)len
));
585 if ((ret
= SMB_VFS_FTRUNCATE(fsp
, len
)) != -1) {
586 notify_fname(fsp
->conn
, NOTIFY_ACTION_MODIFIED
,
587 FILE_NOTIFY_CHANGE_SIZE
588 | FILE_NOTIFY_CHANGE_ATTRIBUTES
,
589 fsp
->fsp_name
->base_name
);
592 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_SET_FILE_LEN
);
597 /****************************************************************************
598 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
599 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
600 as this is also called from the default SMB_VFS_FTRUNCATE code.
601 Always extends the file size.
602 Returns 0 on success, -1 on failure.
603 ****************************************************************************/
605 #define SPARSE_BUF_WRITE_SIZE (32*1024)
607 int vfs_slow_fallocate(files_struct
*fsp
, off_t offset
, off_t len
)
613 sparse_buf
= SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE
);
620 while (total
< len
) {
621 size_t curr_write_size
= MIN(SPARSE_BUF_WRITE_SIZE
, (len
- total
));
623 pwrite_ret
= SMB_VFS_PWRITE(fsp
, sparse_buf
, curr_write_size
, offset
+ total
);
624 if (pwrite_ret
== -1) {
625 int saved_errno
= errno
;
626 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
627 "%s failed with error %s\n",
628 fsp_str_dbg(fsp
), strerror(saved_errno
)));
638 /****************************************************************************
639 A vfs fill sparse call.
640 Writes zeros from the end of file to len, if len is greater than EOF.
641 Used only by strict_sync.
642 Returns 0 on success, -1 on failure.
643 ****************************************************************************/
645 int vfs_fill_sparse(files_struct
*fsp
, off_t len
)
652 status
= vfs_stat_fsp(fsp
);
653 if (!NT_STATUS_IS_OK(status
)) {
657 if (len
<= fsp
->fsp_name
->st
.st_ex_size
) {
662 if (S_ISFIFO(fsp
->fsp_name
->st
.st_ex_mode
)) {
667 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
668 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp
),
669 (double)fsp
->fsp_name
->st
.st_ex_size
, (double)len
,
670 (double)(len
- fsp
->fsp_name
->st
.st_ex_size
)));
672 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_FILL_SPARSE
);
674 offset
= fsp
->fsp_name
->st
.st_ex_size
;
675 num_to_write
= len
- fsp
->fsp_name
->st
.st_ex_size
;
677 /* Only do this on non-stream file handles. */
678 if (fsp
->base_fsp
== NULL
) {
679 /* for allocation try fallocate first. This can fail on some
680 * platforms e.g. when the filesystem doesn't support it and no
681 * emulation is being done by the libc (like on AIX with JFS1). In that
682 * case we do our own emulation. fallocate implementations can
683 * return ENOTSUP or EINVAL in cases like that. */
684 ret
= SMB_VFS_FALLOCATE(fsp
, 0, offset
, num_to_write
);
685 if (ret
== -1 && errno
== ENOSPC
) {
691 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
692 "error %d. Falling back to slow manual allocation\n", ret
));
695 ret
= vfs_slow_fallocate(fsp
, offset
, num_to_write
);
699 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_FILL_SPARSE
);
703 /*******************************************************************************
704 Set a fd into blocking/nonblocking mode through VFS
705 *******************************************************************************/
707 int vfs_set_blocking(files_struct
*fsp
, bool set
)
711 #define FLAG_TO_SET O_NONBLOCK
714 #define FLAG_TO_SET O_NDELAY
716 #define FLAG_TO_SET FNDELAY
719 val
= SMB_VFS_FCNTL(fsp
, F_GETFL
, 0);
730 return SMB_VFS_FCNTL(fsp
, F_SETFL
, val
);
734 /****************************************************************************
735 Transfer some data (n bytes) between two file_struct's.
736 ****************************************************************************/
738 static ssize_t
vfs_pread_fn(void *file
, void *buf
, size_t len
, off_t offset
)
740 struct files_struct
*fsp
= (struct files_struct
*)file
;
742 return SMB_VFS_PREAD(fsp
, buf
, len
, offset
);
745 static ssize_t
vfs_pwrite_fn(void *file
, const void *buf
, size_t len
, off_t offset
)
747 struct files_struct
*fsp
= (struct files_struct
*)file
;
749 return SMB_VFS_PWRITE(fsp
, buf
, len
, offset
);
752 off_t
vfs_transfer_file(files_struct
*in
, files_struct
*out
, off_t n
)
754 return transfer_file_internal((void *)in
, (void *)out
, n
,
755 vfs_pread_fn
, vfs_pwrite_fn
);
758 /*******************************************************************
759 A vfs_readdir wrapper which just returns the file name.
760 ********************************************************************/
762 const char *vfs_readdirname(connection_struct
*conn
, void *p
,
763 SMB_STRUCT_STAT
*sbuf
, char **talloced
)
765 struct dirent
*ptr
= NULL
;
773 ptr
= SMB_VFS_READDIR(conn
, (DIR *)p
, sbuf
);
785 #ifdef HAVE_BROKEN_READDIR_NAME
786 /* using /usr/ucb/cc is BAD */
790 status
= SMB_VFS_TRANSLATE_NAME(conn
, dname
, vfs_translate_to_windows
,
791 talloc_tos(), &translated
);
792 if (NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
796 *talloced
= translated
;
797 if (!NT_STATUS_IS_OK(status
)) {
803 /*******************************************************************
804 A wrapper for vfs_chdir().
805 ********************************************************************/
807 int vfs_ChDir(connection_struct
*conn
, const struct smb_filename
*smb_fname
)
810 struct smb_filename
*cwd
= NULL
;
813 LastDir
= SMB_STRDUP("");
816 if (ISDOT(smb_fname
->base_name
)) {
820 if (*smb_fname
->base_name
== '/' &&
821 strcsequal(LastDir
,smb_fname
->base_name
)) {
825 DEBUG(4,("vfs_ChDir to %s\n", smb_fname
->base_name
));
827 ret
= SMB_VFS_CHDIR(conn
, smb_fname
);
833 * Always replace conn->cwd_fsp. We
834 * don't know if it's been modified by
835 * VFS modules in the stack.
839 cwd
= vfs_GetWd(conn
, conn
);
842 * vfs_GetWd() failed.
843 * We must be able to read cwd.
844 * Return to original directory
847 int saved_errno
= errno
;
849 if (conn
->cwd_fsp
->fsp_name
== NULL
) {
851 * Failed on the very first chdir()+getwd()
852 * for this connection. We can't
855 smb_panic("conn->cwd getwd failed\n");
860 /* Return to the previous $cwd. */
861 ret
= SMB_VFS_CHDIR(conn
, conn
->cwd_fsp
->fsp_name
);
863 smb_panic("conn->cwd getwd failed\n");
868 /* And fail the chdir(). */
872 /* vfs_GetWd() succeeded. */
873 /* Replace global cache. */
875 LastDir
= SMB_STRDUP(smb_fname
->base_name
);
878 * (Indirect) Callers of vfs_ChDir() may still hold references to the
879 * old conn->cwd_fsp->fsp_name. Move it to talloc_tos(), that way
880 * callers can use it for the lifetime of the SMB request.
882 talloc_move(talloc_tos(), &conn
->cwd_fsp
->fsp_name
);
884 conn
->cwd_fsp
->fsp_name
= talloc_move(conn
->cwd_fsp
, &cwd
);
885 conn
->cwd_fsp
->fh
->fd
= AT_FDCWD
;
887 DBG_INFO("vfs_ChDir got %s\n", fsp_str_dbg(conn
->cwd_fsp
));
892 /*******************************************************************
893 Return the absolute current directory path - given a UNIX pathname.
894 Note that this path is returned in DOS format, not UNIX
895 format. Note this can be called with conn == NULL.
896 ********************************************************************/
898 struct smb_filename
*vfs_GetWd(TALLOC_CTX
*ctx
, connection_struct
*conn
)
900 struct smb_filename
*current_dir_fname
= NULL
;
902 struct smb_filename
*smb_fname_dot
= NULL
;
903 struct smb_filename
*smb_fname_full
= NULL
;
904 struct smb_filename
*result
= NULL
;
906 if (!lp_getwd_cache()) {
910 smb_fname_dot
= synthetic_smb_fname(ctx
, ".", NULL
, NULL
, 0);
911 if (smb_fname_dot
== NULL
) {
916 if (SMB_VFS_STAT(conn
, smb_fname_dot
) == -1) {
918 * Known to fail for root: the directory may be NFS-mounted
919 * and exported with root_squash (so has no root access).
921 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
922 "(NFS problem ?)\n", strerror(errno
) ));
926 key
= vfs_file_id_from_sbuf(conn
, &smb_fname_dot
->st
);
928 smb_fname_full
= (struct smb_filename
*)memcache_lookup_talloc(
931 data_blob_const(&key
, sizeof(key
)));
933 if (smb_fname_full
== NULL
) {
937 if ((SMB_VFS_STAT(conn
, smb_fname_full
) == 0) &&
938 (smb_fname_dot
->st
.st_ex_dev
== smb_fname_full
->st
.st_ex_dev
) &&
939 (smb_fname_dot
->st
.st_ex_ino
== smb_fname_full
->st
.st_ex_ino
) &&
940 (S_ISDIR(smb_fname_dot
->st
.st_ex_mode
))) {
943 * Note: smb_fname_full is owned by smbd_memcache()
944 * so we must make a copy to return.
946 result
= cp_smb_filename(ctx
, smb_fname_full
);
947 if (result
== NULL
) {
956 * We don't have the information to hand so rely on traditional
957 * methods. The very slow getcwd, which spawns a process on some
958 * systems, or the not quite so bad getwd.
961 current_dir_fname
= SMB_VFS_GETWD(conn
, ctx
);
962 if (current_dir_fname
== NULL
) {
963 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
968 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot
->st
)) {
969 key
= vfs_file_id_from_sbuf(conn
, &smb_fname_dot
->st
);
972 * smbd_memcache() will own current_dir_fname after the
973 * memcache_add_talloc call, so we must make
974 * a copy on ctx to return.
976 result
= cp_smb_filename(ctx
, current_dir_fname
);
977 if (result
== NULL
) {
982 * Ensure the memory going into the cache
983 * doesn't have a destructor so it can be
986 talloc_set_destructor(current_dir_fname
, NULL
);
988 memcache_add_talloc(smbd_memcache(),
990 data_blob_const(&key
, sizeof(key
)),
992 /* current_dir_fname is now == NULL here. */
994 /* current_dir_fname is already allocated on ctx. */
995 result
= current_dir_fname
;
999 TALLOC_FREE(smb_fname_dot
);
1001 * Don't free current_dir_fname here. It's either been moved
1002 * to the memcache or is being returned in result.
1007 /*******************************************************************
1008 Reduce a file name, removing .. elements and checking that
1009 it is below dir in the hierarchy. This uses realpath.
1010 This function must run as root, and will return names
1011 and valid stat structs that can be checked on open.
1012 ********************************************************************/
1014 NTSTATUS
check_reduced_name_with_privilege(connection_struct
*conn
,
1015 const struct smb_filename
*smb_fname
,
1016 struct smb_request
*smbreq
)
1019 TALLOC_CTX
*ctx
= talloc_tos();
1020 const char *conn_rootdir
;
1022 char *dir_name
= NULL
;
1023 char *resolved_name
= NULL
;
1024 const char *last_component
= NULL
;
1025 struct smb_filename
*resolved_fname
= NULL
;
1026 struct smb_filename
*saved_dir_fname
= NULL
;
1027 struct smb_filename
*smb_fname_cwd
= NULL
;
1028 struct privilege_paths
*priv_paths
= NULL
;
1031 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
1032 smb_fname
->base_name
,
1033 conn
->connectpath
));
1036 priv_paths
= talloc_zero(smbreq
, struct privilege_paths
);
1038 status
= NT_STATUS_NO_MEMORY
;
1042 if (!parent_dirname(ctx
, smb_fname
->base_name
,
1043 &dir_name
, &last_component
)) {
1044 status
= NT_STATUS_NO_MEMORY
;
1048 priv_paths
->parent_name
.base_name
= talloc_strdup(priv_paths
, dir_name
);
1049 priv_paths
->file_name
.base_name
= talloc_strdup(priv_paths
, last_component
);
1051 if (priv_paths
->parent_name
.base_name
== NULL
||
1052 priv_paths
->file_name
.base_name
== NULL
) {
1053 status
= NT_STATUS_NO_MEMORY
;
1057 if (SMB_VFS_STAT(conn
, &priv_paths
->parent_name
) != 0) {
1058 status
= map_nt_error_from_unix(errno
);
1061 /* Remember where we were. */
1062 saved_dir_fname
= vfs_GetWd(ctx
, conn
);
1063 if (!saved_dir_fname
) {
1064 status
= map_nt_error_from_unix(errno
);
1068 if (vfs_ChDir(conn
, &priv_paths
->parent_name
) == -1) {
1069 status
= map_nt_error_from_unix(errno
);
1073 smb_fname_cwd
= synthetic_smb_fname(talloc_tos(), ".", NULL
, NULL
, 0);
1074 if (smb_fname_cwd
== NULL
) {
1075 status
= NT_STATUS_NO_MEMORY
;
1079 /* Get the absolute path of the parent directory. */
1080 resolved_fname
= SMB_VFS_REALPATH(conn
, ctx
, smb_fname_cwd
);
1081 if (resolved_fname
== NULL
) {
1082 status
= map_nt_error_from_unix(errno
);
1085 resolved_name
= resolved_fname
->base_name
;
1087 if (*resolved_name
!= '/') {
1088 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1089 "doesn't return absolute paths !\n"));
1090 status
= NT_STATUS_OBJECT_NAME_INVALID
;
1094 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1095 priv_paths
->parent_name
.base_name
,
1098 /* Now check the stat value is the same. */
1099 if (SMB_VFS_LSTAT(conn
, smb_fname_cwd
) != 0) {
1100 status
= map_nt_error_from_unix(errno
);
1104 /* Ensure we're pointing at the same place. */
1105 if (!check_same_stat(&smb_fname_cwd
->st
, &priv_paths
->parent_name
.st
)) {
1106 DEBUG(0,("check_reduced_name_with_privilege: "
1107 "device/inode/uid/gid on directory %s changed. "
1108 "Denying access !\n",
1109 priv_paths
->parent_name
.base_name
));
1110 status
= NT_STATUS_ACCESS_DENIED
;
1114 /* Ensure we're below the connect path. */
1116 conn_rootdir
= SMB_VFS_CONNECTPATH(conn
, smb_fname
);
1117 if (conn_rootdir
== NULL
) {
1118 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1120 status
= NT_STATUS_ACCESS_DENIED
;
1124 rootdir_len
= strlen(conn_rootdir
);
1127 * In the case of rootdir_len == 1, we know that conn_rootdir is
1128 * "/", and we also know that resolved_name starts with a slash.
1129 * So, in this corner case, resolved_name is automatically a
1130 * sub-directory of the conn_rootdir. Thus we can skip the string
1131 * comparison and the next character checks (which are even
1132 * wrong in this case).
1134 if (rootdir_len
!= 1) {
1137 matched
= (strncmp(conn_rootdir
, resolved_name
,
1140 if (!matched
|| (resolved_name
[rootdir_len
] != '/' &&
1141 resolved_name
[rootdir_len
] != '\0')) {
1142 DEBUG(2, ("check_reduced_name_with_privilege: Bad "
1143 "access attempt: %s is a symlink outside the "
1146 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir
));
1147 DEBUGADD(2, ("resolved_name=%s\n", resolved_name
));
1148 status
= NT_STATUS_ACCESS_DENIED
;
1153 /* Now ensure that the last component either doesn't
1154 exist, or is *NOT* a symlink. */
1156 ret
= SMB_VFS_LSTAT(conn
, &priv_paths
->file_name
);
1158 /* Errno must be ENOENT for this be ok. */
1159 if (errno
!= ENOENT
) {
1160 status
= map_nt_error_from_unix(errno
);
1161 DEBUG(2, ("check_reduced_name_with_privilege: "
1162 "LSTAT on %s failed with %s\n",
1163 priv_paths
->file_name
.base_name
,
1164 nt_errstr(status
)));
1169 if (VALID_STAT(priv_paths
->file_name
.st
) &&
1170 S_ISLNK(priv_paths
->file_name
.st
.st_ex_mode
)) {
1171 DEBUG(2, ("check_reduced_name_with_privilege: "
1172 "Last component %s is a symlink. Denying"
1174 priv_paths
->file_name
.base_name
));
1175 status
= NT_STATUS_ACCESS_DENIED
;
1179 smbreq
->priv_paths
= priv_paths
;
1180 status
= NT_STATUS_OK
;
1184 if (saved_dir_fname
!= NULL
) {
1185 vfs_ChDir(conn
, saved_dir_fname
);
1186 TALLOC_FREE(saved_dir_fname
);
1188 TALLOC_FREE(resolved_fname
);
1189 if (!NT_STATUS_IS_OK(status
)) {
1190 TALLOC_FREE(priv_paths
);
1192 TALLOC_FREE(dir_name
);
1196 /*******************************************************************
1197 Reduce a file name, removing .. elements and checking that
1198 it is below dir in the hierarchy. This uses realpath.
1200 If cwd_name == NULL then fname is a client given path relative
1201 to the root path of the share.
1203 If cwd_name != NULL then fname is a client given path relative
1204 to cwd_name. cwd_name is relative to the root path of the share.
1205 ********************************************************************/
1207 NTSTATUS
check_reduced_name(connection_struct
*conn
,
1208 const struct smb_filename
*cwd_fname
,
1209 const struct smb_filename
*smb_fname
)
1211 TALLOC_CTX
*ctx
= talloc_tos();
1212 const char *cwd_name
= cwd_fname
? cwd_fname
->base_name
: NULL
;
1213 const char *fname
= smb_fname
->base_name
;
1214 struct smb_filename
*resolved_fname
;
1215 char *resolved_name
= NULL
;
1216 char *new_fname
= NULL
;
1217 bool allow_symlinks
= true;
1218 bool allow_widelinks
= false;
1220 DBG_DEBUG("check_reduced_name [%s] [%s]\n", fname
, conn
->connectpath
);
1222 resolved_fname
= SMB_VFS_REALPATH(conn
, ctx
, smb_fname
);
1224 if (resolved_fname
== NULL
) {
1227 DEBUG(3,("check_reduced_name: Component not a "
1228 "directory in getting realpath for "
1230 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1233 char *dir_name
= NULL
;
1234 struct smb_filename dir_fname
= {0};
1235 const char *last_component
= NULL
;
1237 /* Last component didn't exist.
1238 Remove it and try and canonicalise
1239 the directory name. */
1240 if (!parent_dirname(ctx
, fname
,
1243 return NT_STATUS_NO_MEMORY
;
1246 dir_fname
= (struct smb_filename
)
1247 { .base_name
= dir_name
};
1248 resolved_fname
= SMB_VFS_REALPATH(conn
,
1251 if (resolved_fname
== NULL
) {
1252 NTSTATUS status
= map_nt_error_from_unix(errno
);
1254 if (errno
== ENOENT
|| errno
== ENOTDIR
) {
1255 status
= NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1258 DEBUG(3,("check_reduce_name: "
1259 "couldn't get realpath for "
1262 nt_errstr(status
)));
1265 resolved_name
= talloc_asprintf(ctx
,
1267 resolved_fname
->base_name
,
1269 if (resolved_name
== NULL
) {
1270 return NT_STATUS_NO_MEMORY
;
1275 DEBUG(3,("check_reduced_name: couldn't get "
1276 "realpath for %s\n", fname
));
1277 return map_nt_error_from_unix(errno
);
1280 resolved_name
= resolved_fname
->base_name
;
1283 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname
,
1286 if (*resolved_name
!= '/') {
1287 DEBUG(0,("check_reduced_name: realpath doesn't return "
1288 "absolute paths !\n"));
1289 TALLOC_FREE(resolved_fname
);
1290 return NT_STATUS_OBJECT_NAME_INVALID
;
1293 allow_widelinks
= lp_widelinks(SNUM(conn
));
1294 allow_symlinks
= lp_follow_symlinks(SNUM(conn
));
1296 /* Common widelinks and symlinks checks. */
1297 if (!allow_widelinks
|| !allow_symlinks
) {
1298 const char *conn_rootdir
;
1301 conn_rootdir
= SMB_VFS_CONNECTPATH(conn
, smb_fname
);
1302 if (conn_rootdir
== NULL
) {
1303 DEBUG(2, ("check_reduced_name: Could not get "
1305 TALLOC_FREE(resolved_fname
);
1306 return NT_STATUS_ACCESS_DENIED
;
1309 rootdir_len
= strlen(conn_rootdir
);
1312 * In the case of rootdir_len == 1, we know that
1313 * conn_rootdir is "/", and we also know that
1314 * resolved_name starts with a slash. So, in this
1315 * corner case, resolved_name is automatically a
1316 * sub-directory of the conn_rootdir. Thus we can skip
1317 * the string comparison and the next character checks
1318 * (which are even wrong in this case).
1320 if (rootdir_len
!= 1) {
1323 matched
= (strncmp(conn_rootdir
, resolved_name
,
1325 if (!matched
|| (resolved_name
[rootdir_len
] != '/' &&
1326 resolved_name
[rootdir_len
] != '\0')) {
1327 DEBUG(2, ("check_reduced_name: Bad access "
1328 "attempt: %s is a symlink outside the "
1329 "share path\n", fname
));
1330 DEBUGADD(2, ("conn_rootdir =%s\n",
1332 DEBUGADD(2, ("resolved_name=%s\n",
1334 TALLOC_FREE(resolved_fname
);
1335 return NT_STATUS_ACCESS_DENIED
;
1339 /* Extra checks if all symlinks are disallowed. */
1340 if (!allow_symlinks
) {
1341 /* fname can't have changed in resolved_path. */
1342 const char *p
= &resolved_name
[rootdir_len
];
1345 * UNIX filesystem semantics, names consisting
1346 * only of "." or ".." CANNOT be symlinks.
1348 if (ISDOT(fname
) || ISDOTDOT(fname
)) {
1353 DEBUG(2, ("check_reduced_name: logic error (%c) "
1354 "in resolved_name: %s\n",
1357 TALLOC_FREE(resolved_fname
);
1358 return NT_STATUS_ACCESS_DENIED
;
1364 * If cwd_name is present and not ".",
1365 * then fname is relative to that, not
1366 * the root of the share. Make sure the
1367 * path we check is the one the client
1368 * sent (cwd_name+fname).
1370 if (cwd_name
!= NULL
&& !ISDOT(cwd_name
)) {
1371 new_fname
= talloc_asprintf(ctx
,
1375 if (new_fname
== NULL
) {
1376 TALLOC_FREE(resolved_fname
);
1377 return NT_STATUS_NO_MEMORY
;
1382 if (strcmp(fname
, p
)!=0) {
1383 DEBUG(2, ("check_reduced_name: Bad access "
1384 "attempt: %s is a symlink to %s\n",
1386 TALLOC_FREE(resolved_fname
);
1387 TALLOC_FREE(new_fname
);
1388 return NT_STATUS_ACCESS_DENIED
;
1395 DBG_INFO("%s reduced to %s\n", fname
, resolved_name
);
1396 TALLOC_FREE(resolved_fname
);
1397 TALLOC_FREE(new_fname
);
1398 return NT_STATUS_OK
;
1402 * XXX: This is temporary and there should be no callers of this once
1403 * smb_filename is plumbed through all path based operations.
1405 * Called when we know stream name parsing has already been done.
1407 int vfs_stat_smb_basename(struct connection_struct
*conn
,
1408 const struct smb_filename
*smb_fname_in
,
1409 SMB_STRUCT_STAT
*psbuf
)
1411 struct smb_filename smb_fname
= {
1412 .base_name
= discard_const_p(char, smb_fname_in
->base_name
),
1413 .flags
= smb_fname_in
->flags
1417 if (smb_fname
.flags
& SMB_FILENAME_POSIX_PATH
) {
1418 ret
= SMB_VFS_LSTAT(conn
, &smb_fname
);
1420 ret
= SMB_VFS_STAT(conn
, &smb_fname
);
1424 *psbuf
= smb_fname
.st
;
1430 * Ensure LSTAT is called for POSIX paths.
1433 NTSTATUS
vfs_stat_fsp(files_struct
*fsp
)
1436 struct stat_ex saved_stat
= fsp
->fsp_name
->st
;
1438 if(fsp
->fh
->fd
== -1) {
1439 if (fsp
->posix_flags
& FSP_POSIX_FLAGS_OPEN
) {
1440 ret
= SMB_VFS_LSTAT(fsp
->conn
, fsp
->fsp_name
);
1442 ret
= SMB_VFS_STAT(fsp
->conn
, fsp
->fsp_name
);
1445 ret
= SMB_VFS_FSTAT(fsp
, &fsp
->fsp_name
->st
);
1448 return map_nt_error_from_unix(errno
);
1450 update_stat_ex_from_saved_stat(&fsp
->fsp_name
->st
, &saved_stat
);
1451 return NT_STATUS_OK
;
1454 void init_smb_file_time(struct smb_file_time
*ft
)
1456 *ft
= (struct smb_file_time
) {
1457 .atime
= make_omit_timespec(),
1458 .ctime
= make_omit_timespec(),
1459 .mtime
= make_omit_timespec(),
1460 .create_time
= make_omit_timespec()
1465 * Initialize num_streams and streams, then call VFS op streaminfo
1467 NTSTATUS
vfs_streaminfo(connection_struct
*conn
,
1468 struct files_struct
*fsp
,
1469 const struct smb_filename
*smb_fname
,
1470 TALLOC_CTX
*mem_ctx
,
1471 unsigned int *num_streams
,
1472 struct stream_struct
**streams
)
1476 return SMB_VFS_STREAMINFO(conn
,
1485 generate a file_id from a stat structure
1487 struct file_id
vfs_file_id_from_sbuf(connection_struct
*conn
, const SMB_STRUCT_STAT
*sbuf
)
1489 return SMB_VFS_FILE_ID_CREATE(conn
, sbuf
);
1492 int smb_vfs_call_connect(struct vfs_handle_struct
*handle
,
1493 const char *service
, const char *user
)
1496 return handle
->fns
->connect_fn(handle
, service
, user
);
1499 void smb_vfs_call_disconnect(struct vfs_handle_struct
*handle
)
1501 VFS_FIND(disconnect
);
1502 handle
->fns
->disconnect_fn(handle
);
1505 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct
*handle
,
1506 const struct smb_filename
*smb_fname
,
1511 VFS_FIND(disk_free
);
1512 return handle
->fns
->disk_free_fn(handle
, smb_fname
,
1513 bsize
, dfree
, dsize
);
1516 int smb_vfs_call_get_quota(struct vfs_handle_struct
*handle
,
1517 const struct smb_filename
*smb_fname
,
1518 enum SMB_QUOTA_TYPE qtype
,
1522 VFS_FIND(get_quota
);
1523 return handle
->fns
->get_quota_fn(handle
, smb_fname
, qtype
, id
, qt
);
1526 int smb_vfs_call_set_quota(struct vfs_handle_struct
*handle
,
1527 enum SMB_QUOTA_TYPE qtype
, unid_t id
,
1530 VFS_FIND(set_quota
);
1531 return handle
->fns
->set_quota_fn(handle
, qtype
, id
, qt
);
1534 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct
*handle
,
1535 struct files_struct
*fsp
,
1536 struct shadow_copy_data
*shadow_copy_data
,
1539 VFS_FIND(get_shadow_copy_data
);
1540 return handle
->fns
->get_shadow_copy_data_fn(handle
, fsp
,
1544 int smb_vfs_call_statvfs(struct vfs_handle_struct
*handle
,
1545 const struct smb_filename
*smb_fname
,
1546 struct vfs_statvfs_struct
*statbuf
)
1549 return handle
->fns
->statvfs_fn(handle
, smb_fname
, statbuf
);
1552 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct
*handle
,
1553 enum timestamp_set_resolution
*p_ts_res
)
1555 VFS_FIND(fs_capabilities
);
1556 return handle
->fns
->fs_capabilities_fn(handle
, p_ts_res
);
1559 NTSTATUS
smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct
*handle
,
1560 struct dfs_GetDFSReferral
*r
)
1562 VFS_FIND(get_dfs_referrals
);
1563 return handle
->fns
->get_dfs_referrals_fn(handle
, r
);
1566 NTSTATUS
smb_vfs_call_create_dfs_pathat(struct vfs_handle_struct
*handle
,
1567 struct files_struct
*dirfsp
,
1568 const struct smb_filename
*smb_fname
,
1569 const struct referral
*reflist
,
1570 size_t referral_count
)
1572 VFS_FIND(create_dfs_pathat
);
1573 return handle
->fns
->create_dfs_pathat_fn(handle
,
1580 NTSTATUS
smb_vfs_call_read_dfs_pathat(struct vfs_handle_struct
*handle
,
1581 TALLOC_CTX
*mem_ctx
,
1582 struct files_struct
*dirfsp
,
1583 const struct smb_filename
*smb_fname
,
1584 struct referral
**ppreflist
,
1585 size_t *preferral_count
)
1587 VFS_FIND(read_dfs_pathat
);
1588 return handle
->fns
->read_dfs_pathat_fn(handle
,
1596 DIR *smb_vfs_call_opendir(struct vfs_handle_struct
*handle
,
1597 const struct smb_filename
*smb_fname
,
1599 uint32_t attributes
)
1602 return handle
->fns
->opendir_fn(handle
, smb_fname
, mask
, attributes
);
1605 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct
*handle
,
1606 struct files_struct
*fsp
,
1608 uint32_t attributes
)
1610 VFS_FIND(fdopendir
);
1611 return handle
->fns
->fdopendir_fn(handle
, fsp
, mask
, attributes
);
1614 struct dirent
*smb_vfs_call_readdir(struct vfs_handle_struct
*handle
,
1616 SMB_STRUCT_STAT
*sbuf
)
1619 return handle
->fns
->readdir_fn(handle
, dirp
, sbuf
);
1622 void smb_vfs_call_seekdir(struct vfs_handle_struct
*handle
,
1623 DIR *dirp
, long offset
)
1626 handle
->fns
->seekdir_fn(handle
, dirp
, offset
);
1629 long smb_vfs_call_telldir(struct vfs_handle_struct
*handle
,
1633 return handle
->fns
->telldir_fn(handle
, dirp
);
1636 void smb_vfs_call_rewind_dir(struct vfs_handle_struct
*handle
,
1639 VFS_FIND(rewind_dir
);
1640 handle
->fns
->rewind_dir_fn(handle
, dirp
);
1643 int smb_vfs_call_mkdirat(struct vfs_handle_struct
*handle
,
1644 struct files_struct
*dirfsp
,
1645 const struct smb_filename
*smb_fname
,
1649 return handle
->fns
->mkdirat_fn(handle
,
1655 int smb_vfs_call_closedir(struct vfs_handle_struct
*handle
,
1659 return handle
->fns
->closedir_fn(handle
, dir
);
1662 int smb_vfs_call_open(struct vfs_handle_struct
*handle
,
1663 struct smb_filename
*smb_fname
, struct files_struct
*fsp
,
1664 int flags
, mode_t mode
)
1667 return handle
->fns
->open_fn(handle
, smb_fname
, fsp
, flags
, mode
);
1670 NTSTATUS
smb_vfs_call_create_file(struct vfs_handle_struct
*handle
,
1671 struct smb_request
*req
,
1672 uint16_t root_dir_fid
,
1673 struct smb_filename
*smb_fname
,
1674 uint32_t access_mask
,
1675 uint32_t share_access
,
1676 uint32_t create_disposition
,
1677 uint32_t create_options
,
1678 uint32_t file_attributes
,
1679 uint32_t oplock_request
,
1680 const struct smb2_lease
*lease
,
1681 uint64_t allocation_size
,
1682 uint32_t private_flags
,
1683 struct security_descriptor
*sd
,
1684 struct ea_list
*ea_list
,
1685 files_struct
**result
,
1687 const struct smb2_create_blobs
*in_context_blobs
,
1688 struct smb2_create_blobs
*out_context_blobs
)
1690 VFS_FIND(create_file
);
1691 return handle
->fns
->create_file_fn(
1692 handle
, req
, root_dir_fid
, smb_fname
, access_mask
,
1693 share_access
, create_disposition
, create_options
,
1694 file_attributes
, oplock_request
, lease
, allocation_size
,
1695 private_flags
, sd
, ea_list
,
1696 result
, pinfo
, in_context_blobs
, out_context_blobs
);
1699 int smb_vfs_call_close(struct vfs_handle_struct
*handle
,
1700 struct files_struct
*fsp
)
1703 return handle
->fns
->close_fn(handle
, fsp
);
1706 ssize_t
smb_vfs_call_pread(struct vfs_handle_struct
*handle
,
1707 struct files_struct
*fsp
, void *data
, size_t n
,
1711 return handle
->fns
->pread_fn(handle
, fsp
, data
, n
, offset
);
1714 struct smb_vfs_call_pread_state
{
1715 ssize_t (*recv_fn
)(struct tevent_req
*req
, struct vfs_aio_state
*vfs_aio_state
);
1717 struct vfs_aio_state vfs_aio_state
;
1720 static void smb_vfs_call_pread_done(struct tevent_req
*subreq
);
1722 struct tevent_req
*smb_vfs_call_pread_send(struct vfs_handle_struct
*handle
,
1723 TALLOC_CTX
*mem_ctx
,
1724 struct tevent_context
*ev
,
1725 struct files_struct
*fsp
,
1727 size_t n
, off_t offset
)
1729 struct tevent_req
*req
, *subreq
;
1730 struct smb_vfs_call_pread_state
*state
;
1732 req
= tevent_req_create(mem_ctx
, &state
,
1733 struct smb_vfs_call_pread_state
);
1737 VFS_FIND(pread_send
);
1738 state
->recv_fn
= handle
->fns
->pread_recv_fn
;
1740 subreq
= handle
->fns
->pread_send_fn(handle
, state
, ev
, fsp
, data
, n
,
1742 if (tevent_req_nomem(subreq
, req
)) {
1743 return tevent_req_post(req
, ev
);
1745 tevent_req_set_callback(subreq
, smb_vfs_call_pread_done
, req
);
1749 static void smb_vfs_call_pread_done(struct tevent_req
*subreq
)
1751 struct tevent_req
*req
= tevent_req_callback_data(
1752 subreq
, struct tevent_req
);
1753 struct smb_vfs_call_pread_state
*state
= tevent_req_data(
1754 req
, struct smb_vfs_call_pread_state
);
1756 state
->retval
= state
->recv_fn(subreq
, &state
->vfs_aio_state
);
1757 TALLOC_FREE(subreq
);
1758 if (state
->retval
== -1) {
1759 tevent_req_error(req
, state
->vfs_aio_state
.error
);
1762 tevent_req_done(req
);
1765 ssize_t
SMB_VFS_PREAD_RECV(struct tevent_req
*req
,
1766 struct vfs_aio_state
*vfs_aio_state
)
1768 struct smb_vfs_call_pread_state
*state
= tevent_req_data(
1769 req
, struct smb_vfs_call_pread_state
);
1772 if (tevent_req_is_unix_error(req
, &vfs_aio_state
->error
)) {
1773 tevent_req_received(req
);
1776 *vfs_aio_state
= state
->vfs_aio_state
;
1777 retval
= state
->retval
;
1778 tevent_req_received(req
);
1782 ssize_t
smb_vfs_call_pwrite(struct vfs_handle_struct
*handle
,
1783 struct files_struct
*fsp
, const void *data
,
1784 size_t n
, off_t offset
)
1787 return handle
->fns
->pwrite_fn(handle
, fsp
, data
, n
, offset
);
1790 struct smb_vfs_call_pwrite_state
{
1791 ssize_t (*recv_fn
)(struct tevent_req
*req
, struct vfs_aio_state
*vfs_aio_state
);
1793 struct vfs_aio_state vfs_aio_state
;
1796 static void smb_vfs_call_pwrite_done(struct tevent_req
*subreq
);
1798 struct tevent_req
*smb_vfs_call_pwrite_send(struct vfs_handle_struct
*handle
,
1799 TALLOC_CTX
*mem_ctx
,
1800 struct tevent_context
*ev
,
1801 struct files_struct
*fsp
,
1803 size_t n
, off_t offset
)
1805 struct tevent_req
*req
, *subreq
;
1806 struct smb_vfs_call_pwrite_state
*state
;
1808 req
= tevent_req_create(mem_ctx
, &state
,
1809 struct smb_vfs_call_pwrite_state
);
1813 VFS_FIND(pwrite_send
);
1814 state
->recv_fn
= handle
->fns
->pwrite_recv_fn
;
1816 subreq
= handle
->fns
->pwrite_send_fn(handle
, state
, ev
, fsp
, data
, n
,
1818 if (tevent_req_nomem(subreq
, req
)) {
1819 return tevent_req_post(req
, ev
);
1821 tevent_req_set_callback(subreq
, smb_vfs_call_pwrite_done
, req
);
1825 static void smb_vfs_call_pwrite_done(struct tevent_req
*subreq
)
1827 struct tevent_req
*req
= tevent_req_callback_data(
1828 subreq
, struct tevent_req
);
1829 struct smb_vfs_call_pwrite_state
*state
= tevent_req_data(
1830 req
, struct smb_vfs_call_pwrite_state
);
1832 state
->retval
= state
->recv_fn(subreq
, &state
->vfs_aio_state
);
1833 TALLOC_FREE(subreq
);
1834 if (state
->retval
== -1) {
1835 tevent_req_error(req
, state
->vfs_aio_state
.error
);
1838 tevent_req_done(req
);
1841 ssize_t
SMB_VFS_PWRITE_RECV(struct tevent_req
*req
,
1842 struct vfs_aio_state
*vfs_aio_state
)
1844 struct smb_vfs_call_pwrite_state
*state
= tevent_req_data(
1845 req
, struct smb_vfs_call_pwrite_state
);
1848 if (tevent_req_is_unix_error(req
, &vfs_aio_state
->error
)) {
1849 tevent_req_received(req
);
1852 *vfs_aio_state
= state
->vfs_aio_state
;
1853 retval
= state
->retval
;
1854 tevent_req_received(req
);
1858 off_t
smb_vfs_call_lseek(struct vfs_handle_struct
*handle
,
1859 struct files_struct
*fsp
, off_t offset
,
1863 return handle
->fns
->lseek_fn(handle
, fsp
, offset
, whence
);
1866 ssize_t
smb_vfs_call_sendfile(struct vfs_handle_struct
*handle
, int tofd
,
1867 files_struct
*fromfsp
, const DATA_BLOB
*header
,
1868 off_t offset
, size_t count
)
1871 return handle
->fns
->sendfile_fn(handle
, tofd
, fromfsp
, header
, offset
,
1875 ssize_t
smb_vfs_call_recvfile(struct vfs_handle_struct
*handle
, int fromfd
,
1876 files_struct
*tofsp
, off_t offset
,
1880 return handle
->fns
->recvfile_fn(handle
, fromfd
, tofsp
, offset
, count
);
1883 int smb_vfs_call_renameat(struct vfs_handle_struct
*handle
,
1884 files_struct
*srcfsp
,
1885 const struct smb_filename
*smb_fname_src
,
1886 files_struct
*dstfsp
,
1887 const struct smb_filename
*smb_fname_dst
)
1890 return handle
->fns
->renameat_fn(handle
,
1897 struct smb_vfs_call_fsync_state
{
1898 int (*recv_fn
)(struct tevent_req
*req
, struct vfs_aio_state
*vfs_aio_state
);
1900 struct vfs_aio_state vfs_aio_state
;
1903 static void smb_vfs_call_fsync_done(struct tevent_req
*subreq
);
1905 struct tevent_req
*smb_vfs_call_fsync_send(struct vfs_handle_struct
*handle
,
1906 TALLOC_CTX
*mem_ctx
,
1907 struct tevent_context
*ev
,
1908 struct files_struct
*fsp
)
1910 struct tevent_req
*req
, *subreq
;
1911 struct smb_vfs_call_fsync_state
*state
;
1913 req
= tevent_req_create(mem_ctx
, &state
,
1914 struct smb_vfs_call_fsync_state
);
1918 VFS_FIND(fsync_send
);
1919 state
->recv_fn
= handle
->fns
->fsync_recv_fn
;
1921 subreq
= handle
->fns
->fsync_send_fn(handle
, state
, ev
, fsp
);
1922 if (tevent_req_nomem(subreq
, req
)) {
1923 return tevent_req_post(req
, ev
);
1925 tevent_req_set_callback(subreq
, smb_vfs_call_fsync_done
, req
);
1929 static void smb_vfs_call_fsync_done(struct tevent_req
*subreq
)
1931 struct tevent_req
*req
= tevent_req_callback_data(
1932 subreq
, struct tevent_req
);
1933 struct smb_vfs_call_fsync_state
*state
= tevent_req_data(
1934 req
, struct smb_vfs_call_fsync_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 int SMB_VFS_FSYNC_RECV(struct tevent_req
*req
, struct vfs_aio_state
*vfs_aio_state
)
1947 struct smb_vfs_call_fsync_state
*state
= tevent_req_data(
1948 req
, struct smb_vfs_call_fsync_state
);
1951 if (tevent_req_is_unix_error(req
, &vfs_aio_state
->error
)) {
1952 tevent_req_received(req
);
1955 *vfs_aio_state
= state
->vfs_aio_state
;
1956 retval
= state
->retval
;
1957 tevent_req_received(req
);
1962 * Synchronous version of fsync, built from backend
1963 * async VFS primitives. Uses a temporary sub-event
1964 * context (NOT NESTED).
1967 int smb_vfs_fsync_sync(files_struct
*fsp
)
1969 TALLOC_CTX
*frame
= talloc_stackframe();
1970 struct tevent_req
*req
= NULL
;
1971 struct vfs_aio_state aio_state
= { 0 };
1974 struct tevent_context
*ev
= samba_tevent_context_init(frame
);
1980 req
= SMB_VFS_FSYNC_SEND(talloc_tos(), ev
, fsp
);
1985 ok
= tevent_req_poll(req
, ev
);
1990 ret
= SMB_VFS_FSYNC_RECV(req
, &aio_state
);
1995 if (aio_state
.error
!= 0) {
1996 errno
= aio_state
.error
;
2001 int smb_vfs_call_stat(struct vfs_handle_struct
*handle
,
2002 struct smb_filename
*smb_fname
)
2005 return handle
->fns
->stat_fn(handle
, smb_fname
);
2008 int smb_vfs_call_fstat(struct vfs_handle_struct
*handle
,
2009 struct files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
2012 return handle
->fns
->fstat_fn(handle
, fsp
, sbuf
);
2015 int smb_vfs_call_lstat(struct vfs_handle_struct
*handle
,
2016 struct smb_filename
*smb_filename
)
2019 return handle
->fns
->lstat_fn(handle
, smb_filename
);
2022 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct
*handle
,
2023 struct files_struct
*fsp
,
2024 const SMB_STRUCT_STAT
*sbuf
)
2026 VFS_FIND(get_alloc_size
);
2027 return handle
->fns
->get_alloc_size_fn(handle
, fsp
, sbuf
);
2030 int smb_vfs_call_unlinkat(struct vfs_handle_struct
*handle
,
2031 struct files_struct
*dirfsp
,
2032 const struct smb_filename
*smb_fname
,
2036 return handle
->fns
->unlinkat_fn(handle
,
2042 int smb_vfs_call_chmod(struct vfs_handle_struct
*handle
,
2043 const struct smb_filename
*smb_fname
,
2047 return handle
->fns
->chmod_fn(handle
, smb_fname
, mode
);
2050 int smb_vfs_call_fchmod(struct vfs_handle_struct
*handle
,
2051 struct files_struct
*fsp
, mode_t mode
)
2054 return handle
->fns
->fchmod_fn(handle
, fsp
, mode
);
2057 int smb_vfs_call_fchown(struct vfs_handle_struct
*handle
,
2058 struct files_struct
*fsp
, uid_t uid
, gid_t gid
)
2061 return handle
->fns
->fchown_fn(handle
, fsp
, uid
, gid
);
2064 int smb_vfs_call_lchown(struct vfs_handle_struct
*handle
,
2065 const struct smb_filename
*smb_fname
,
2070 return handle
->fns
->lchown_fn(handle
, smb_fname
, uid
, gid
);
2073 int smb_vfs_call_chdir(struct vfs_handle_struct
*handle
,
2074 const struct smb_filename
*smb_fname
)
2077 return handle
->fns
->chdir_fn(handle
, smb_fname
);
2080 struct smb_filename
*smb_vfs_call_getwd(struct vfs_handle_struct
*handle
,
2084 return handle
->fns
->getwd_fn(handle
, ctx
);
2087 int smb_vfs_call_ntimes(struct vfs_handle_struct
*handle
,
2088 const struct smb_filename
*smb_fname
,
2089 struct smb_file_time
*ft
)
2092 return handle
->fns
->ntimes_fn(handle
, smb_fname
, ft
);
2095 int smb_vfs_call_ftruncate(struct vfs_handle_struct
*handle
,
2096 struct files_struct
*fsp
, off_t offset
)
2098 VFS_FIND(ftruncate
);
2099 return handle
->fns
->ftruncate_fn(handle
, fsp
, offset
);
2102 int smb_vfs_call_fallocate(struct vfs_handle_struct
*handle
,
2103 struct files_struct
*fsp
,
2108 VFS_FIND(fallocate
);
2109 return handle
->fns
->fallocate_fn(handle
, fsp
, mode
, offset
, len
);
2112 int smb_vfs_call_kernel_flock(struct vfs_handle_struct
*handle
,
2113 struct files_struct
*fsp
, uint32_t share_mode
,
2114 uint32_t access_mask
)
2116 VFS_FIND(kernel_flock
);
2117 return handle
->fns
->kernel_flock_fn(handle
, fsp
, share_mode
,
2121 int smb_vfs_call_fcntl(struct vfs_handle_struct
*handle
,
2122 struct files_struct
*fsp
, int cmd
, ...)
2129 va_start(cmd_arg
, cmd
);
2130 result
= handle
->fns
->fcntl_fn(handle
, fsp
, cmd
, cmd_arg
);
2136 int smb_vfs_call_linux_setlease(struct vfs_handle_struct
*handle
,
2137 struct files_struct
*fsp
, int leasetype
)
2139 VFS_FIND(linux_setlease
);
2140 return handle
->fns
->linux_setlease_fn(handle
, fsp
, leasetype
);
2143 int smb_vfs_call_symlinkat(struct vfs_handle_struct
*handle
,
2144 const char *link_target
,
2145 struct files_struct
*dirfsp
,
2146 const struct smb_filename
*new_smb_fname
)
2148 VFS_FIND(symlinkat
);
2149 return handle
->fns
->symlinkat_fn(handle
,
2155 int smb_vfs_call_readlinkat(struct vfs_handle_struct
*handle
,
2156 files_struct
*dirfsp
,
2157 const struct smb_filename
*smb_fname
,
2161 VFS_FIND(readlinkat
);
2162 return handle
->fns
->readlinkat_fn(handle
,
2169 int smb_vfs_call_linkat(struct vfs_handle_struct
*handle
,
2170 struct files_struct
*srcfsp
,
2171 const struct smb_filename
*old_smb_fname
,
2172 struct files_struct
*dstfsp
,
2173 const struct smb_filename
*new_smb_fname
,
2177 return handle
->fns
->linkat_fn(handle
,
2185 int smb_vfs_call_mknodat(struct vfs_handle_struct
*handle
,
2186 struct files_struct
*dirfsp
,
2187 const struct smb_filename
*smb_fname
,
2192 return handle
->fns
->mknodat_fn(handle
,
2199 struct smb_filename
*smb_vfs_call_realpath(struct vfs_handle_struct
*handle
,
2201 const struct smb_filename
*smb_fname
)
2204 return handle
->fns
->realpath_fn(handle
, ctx
, smb_fname
);
2207 int smb_vfs_call_chflags(struct vfs_handle_struct
*handle
,
2208 const struct smb_filename
*smb_fname
,
2212 return handle
->fns
->chflags_fn(handle
, smb_fname
, flags
);
2215 struct file_id
smb_vfs_call_file_id_create(struct vfs_handle_struct
*handle
,
2216 const SMB_STRUCT_STAT
*sbuf
)
2218 VFS_FIND(file_id_create
);
2219 return handle
->fns
->file_id_create_fn(handle
, sbuf
);
2222 uint64_t smb_vfs_call_fs_file_id(struct vfs_handle_struct
*handle
,
2223 const SMB_STRUCT_STAT
*sbuf
)
2225 VFS_FIND(fs_file_id
);
2226 return handle
->fns
->fs_file_id_fn(handle
, sbuf
);
2229 NTSTATUS
smb_vfs_call_streaminfo(struct vfs_handle_struct
*handle
,
2230 struct files_struct
*fsp
,
2231 const struct smb_filename
*smb_fname
,
2232 TALLOC_CTX
*mem_ctx
,
2233 unsigned int *num_streams
,
2234 struct stream_struct
**streams
)
2236 VFS_FIND(streaminfo
);
2237 return handle
->fns
->streaminfo_fn(handle
, fsp
, smb_fname
, mem_ctx
,
2238 num_streams
, streams
);
2241 int smb_vfs_call_get_real_filename(struct vfs_handle_struct
*handle
,
2242 const char *path
, const char *name
,
2243 TALLOC_CTX
*mem_ctx
, char **found_name
)
2245 VFS_FIND(get_real_filename
);
2246 return handle
->fns
->get_real_filename_fn(handle
, path
, name
, mem_ctx
,
2250 const char *smb_vfs_call_connectpath(struct vfs_handle_struct
*handle
,
2251 const struct smb_filename
*smb_fname
)
2253 VFS_FIND(connectpath
);
2254 return handle
->fns
->connectpath_fn(handle
, smb_fname
);
2257 bool smb_vfs_call_strict_lock_check(struct vfs_handle_struct
*handle
,
2258 struct files_struct
*fsp
,
2259 struct lock_struct
*plock
)
2261 VFS_FIND(strict_lock_check
);
2262 return handle
->fns
->strict_lock_check_fn(handle
, fsp
, plock
);
2265 NTSTATUS
smb_vfs_call_translate_name(struct vfs_handle_struct
*handle
,
2267 enum vfs_translate_direction direction
,
2268 TALLOC_CTX
*mem_ctx
,
2271 VFS_FIND(translate_name
);
2272 return handle
->fns
->translate_name_fn(handle
, name
, direction
, mem_ctx
,
2276 NTSTATUS
smb_vfs_call_fsctl(struct vfs_handle_struct
*handle
,
2277 struct files_struct
*fsp
,
2281 const uint8_t *in_data
,
2284 uint32_t max_out_len
,
2288 return handle
->fns
->fsctl_fn(handle
, fsp
, ctx
, function
, req_flags
,
2289 in_data
, in_len
, out_data
, max_out_len
,
2293 NTSTATUS
smb_vfs_call_get_dos_attributes(struct vfs_handle_struct
*handle
,
2294 struct smb_filename
*smb_fname
,
2297 VFS_FIND(get_dos_attributes
);
2298 return handle
->fns
->get_dos_attributes_fn(handle
, smb_fname
, dosmode
);
2301 NTSTATUS
smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct
*handle
,
2302 struct files_struct
*fsp
,
2305 VFS_FIND(fget_dos_attributes
);
2306 return handle
->fns
->fget_dos_attributes_fn(handle
, fsp
, dosmode
);
2309 NTSTATUS
smb_vfs_call_set_dos_attributes(struct vfs_handle_struct
*handle
,
2310 const struct smb_filename
*smb_fname
,
2313 VFS_FIND(set_dos_attributes
);
2314 return handle
->fns
->set_dos_attributes_fn(handle
, smb_fname
, dosmode
);
2317 NTSTATUS
smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct
*handle
,
2318 struct files_struct
*fsp
,
2321 VFS_FIND(set_dos_attributes
);
2322 return handle
->fns
->fset_dos_attributes_fn(handle
, fsp
, dosmode
);
2325 struct tevent_req
*smb_vfs_call_offload_read_send(TALLOC_CTX
*mem_ctx
,
2326 struct tevent_context
*ev
,
2327 struct vfs_handle_struct
*handle
,
2328 struct files_struct
*fsp
,
2334 VFS_FIND(offload_read_send
);
2335 return handle
->fns
->offload_read_send_fn(mem_ctx
, ev
, handle
,
2337 ttl
, offset
, to_copy
);
2340 NTSTATUS
smb_vfs_call_offload_read_recv(struct tevent_req
*req
,
2341 struct vfs_handle_struct
*handle
,
2342 TALLOC_CTX
*mem_ctx
,
2343 DATA_BLOB
*token_blob
)
2345 VFS_FIND(offload_read_recv
);
2346 return handle
->fns
->offload_read_recv_fn(req
, handle
, mem_ctx
, token_blob
);
2349 struct tevent_req
*smb_vfs_call_offload_write_send(struct vfs_handle_struct
*handle
,
2350 TALLOC_CTX
*mem_ctx
,
2351 struct tevent_context
*ev
,
2354 off_t transfer_offset
,
2355 struct files_struct
*dest_fsp
,
2359 VFS_FIND(offload_write_send
);
2360 return handle
->fns
->offload_write_send_fn(handle
, mem_ctx
, ev
, fsctl
,
2361 token
, transfer_offset
,
2362 dest_fsp
, dest_off
, num
);
2365 NTSTATUS
smb_vfs_call_offload_write_recv(struct vfs_handle_struct
*handle
,
2366 struct tevent_req
*req
,
2369 VFS_FIND(offload_write_recv
);
2370 return handle
->fns
->offload_write_recv_fn(handle
, req
, copied
);
2373 struct smb_vfs_call_get_dos_attributes_state
{
2374 files_struct
*dir_fsp
;
2375 NTSTATUS (*recv_fn
)(struct tevent_req
*req
,
2376 struct vfs_aio_state
*aio_state
,
2378 struct vfs_aio_state aio_state
;
2379 uint32_t dos_attributes
;
2382 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req
*subreq
);
2384 struct tevent_req
*smb_vfs_call_get_dos_attributes_send(
2385 TALLOC_CTX
*mem_ctx
,
2386 struct tevent_context
*ev
,
2387 struct vfs_handle_struct
*handle
,
2388 files_struct
*dir_fsp
,
2389 struct smb_filename
*smb_fname
)
2391 struct tevent_req
*req
= NULL
;
2392 struct smb_vfs_call_get_dos_attributes_state
*state
= NULL
;
2393 struct tevent_req
*subreq
= NULL
;
2395 req
= tevent_req_create(mem_ctx
, &state
,
2396 struct smb_vfs_call_get_dos_attributes_state
);
2401 VFS_FIND(get_dos_attributes_send
);
2403 *state
= (struct smb_vfs_call_get_dos_attributes_state
) {
2405 .recv_fn
= handle
->fns
->get_dos_attributes_recv_fn
,
2408 subreq
= handle
->fns
->get_dos_attributes_send_fn(mem_ctx
,
2413 if (tevent_req_nomem(subreq
, req
)) {
2414 return tevent_req_post(req
, ev
);
2416 tevent_req_defer_callback(req
, ev
);
2418 tevent_req_set_callback(subreq
,
2419 smb_vfs_call_get_dos_attributes_done
,
2425 static void smb_vfs_call_get_dos_attributes_done(struct tevent_req
*subreq
)
2427 struct tevent_req
*req
=
2428 tevent_req_callback_data(subreq
,
2430 struct smb_vfs_call_get_dos_attributes_state
*state
=
2431 tevent_req_data(req
,
2432 struct smb_vfs_call_get_dos_attributes_state
);
2437 * Make sure we run as the user again
2439 ok
= change_to_user_and_service_by_fsp(state
->dir_fsp
);
2442 status
= state
->recv_fn(subreq
,
2444 &state
->dos_attributes
);
2445 TALLOC_FREE(subreq
);
2446 if (tevent_req_nterror(req
, status
)) {
2450 tevent_req_done(req
);
2453 NTSTATUS
smb_vfs_call_get_dos_attributes_recv(
2454 struct tevent_req
*req
,
2455 struct vfs_aio_state
*aio_state
,
2456 uint32_t *dos_attributes
)
2458 struct smb_vfs_call_get_dos_attributes_state
*state
=
2459 tevent_req_data(req
,
2460 struct smb_vfs_call_get_dos_attributes_state
);
2463 if (tevent_req_is_nterror(req
, &status
)) {
2464 tevent_req_received(req
);
2468 *aio_state
= state
->aio_state
;
2469 *dos_attributes
= state
->dos_attributes
;
2470 tevent_req_received(req
);
2471 return NT_STATUS_OK
;
2474 NTSTATUS
smb_vfs_call_get_compression(vfs_handle_struct
*handle
,
2475 TALLOC_CTX
*mem_ctx
,
2476 struct files_struct
*fsp
,
2477 struct smb_filename
*smb_fname
,
2478 uint16_t *_compression_fmt
)
2480 VFS_FIND(get_compression
);
2481 return handle
->fns
->get_compression_fn(handle
, mem_ctx
, fsp
, smb_fname
,
2485 NTSTATUS
smb_vfs_call_set_compression(vfs_handle_struct
*handle
,
2486 TALLOC_CTX
*mem_ctx
,
2487 struct files_struct
*fsp
,
2488 uint16_t compression_fmt
)
2490 VFS_FIND(set_compression
);
2491 return handle
->fns
->set_compression_fn(handle
, mem_ctx
, fsp
,
2495 NTSTATUS
smb_vfs_call_snap_check_path(vfs_handle_struct
*handle
,
2496 TALLOC_CTX
*mem_ctx
,
2497 const char *service_path
,
2500 VFS_FIND(snap_check_path
);
2501 return handle
->fns
->snap_check_path_fn(handle
, mem_ctx
, service_path
,
2505 NTSTATUS
smb_vfs_call_snap_create(struct vfs_handle_struct
*handle
,
2506 TALLOC_CTX
*mem_ctx
,
2507 const char *base_volume
,
2513 VFS_FIND(snap_create
);
2514 return handle
->fns
->snap_create_fn(handle
, mem_ctx
, base_volume
, tstamp
,
2515 rw
, base_path
, snap_path
);
2518 NTSTATUS
smb_vfs_call_snap_delete(struct vfs_handle_struct
*handle
,
2519 TALLOC_CTX
*mem_ctx
,
2523 VFS_FIND(snap_delete
);
2524 return handle
->fns
->snap_delete_fn(handle
, mem_ctx
, base_path
,
2528 NTSTATUS
smb_vfs_call_fget_nt_acl(struct vfs_handle_struct
*handle
,
2529 struct files_struct
*fsp
,
2530 uint32_t security_info
,
2531 TALLOC_CTX
*mem_ctx
,
2532 struct security_descriptor
**ppdesc
)
2534 VFS_FIND(fget_nt_acl
);
2535 return handle
->fns
->fget_nt_acl_fn(handle
, fsp
, security_info
,
2539 NTSTATUS
smb_vfs_call_get_nt_acl(struct vfs_handle_struct
*handle
,
2540 const struct smb_filename
*smb_fname
,
2541 uint32_t security_info
,
2542 TALLOC_CTX
*mem_ctx
,
2543 struct security_descriptor
**ppdesc
)
2545 VFS_FIND(get_nt_acl
);
2546 return handle
->fns
->get_nt_acl_fn(handle
,
2553 NTSTATUS
smb_vfs_call_fset_nt_acl(struct vfs_handle_struct
*handle
,
2554 struct files_struct
*fsp
,
2555 uint32_t security_info_sent
,
2556 const struct security_descriptor
*psd
)
2558 VFS_FIND(fset_nt_acl
);
2559 return handle
->fns
->fset_nt_acl_fn(handle
, fsp
, security_info_sent
,
2563 NTSTATUS
smb_vfs_call_audit_file(struct vfs_handle_struct
*handle
,
2564 struct smb_filename
*file
,
2565 struct security_acl
*sacl
,
2566 uint32_t access_requested
,
2567 uint32_t access_denied
)
2569 VFS_FIND(audit_file
);
2570 return handle
->fns
->audit_file_fn(handle
,
2577 SMB_ACL_T
smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct
*handle
,
2578 const struct smb_filename
*smb_fname
,
2579 SMB_ACL_TYPE_T type
,
2580 TALLOC_CTX
*mem_ctx
)
2582 VFS_FIND(sys_acl_get_file
);
2583 return handle
->fns
->sys_acl_get_file_fn(handle
, smb_fname
, type
, mem_ctx
);
2586 SMB_ACL_T
smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct
*handle
,
2587 struct files_struct
*fsp
,
2588 TALLOC_CTX
*mem_ctx
)
2590 VFS_FIND(sys_acl_get_fd
);
2591 return handle
->fns
->sys_acl_get_fd_fn(handle
, fsp
, mem_ctx
);
2594 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct
*handle
,
2595 const struct smb_filename
*smb_fname
,
2596 TALLOC_CTX
*mem_ctx
,
2597 char **blob_description
,
2600 VFS_FIND(sys_acl_blob_get_file
);
2601 return handle
->fns
->sys_acl_blob_get_file_fn(handle
, smb_fname
,
2602 mem_ctx
, blob_description
, blob
);
2605 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct
*handle
,
2606 struct files_struct
*fsp
,
2607 TALLOC_CTX
*mem_ctx
,
2608 char **blob_description
,
2611 VFS_FIND(sys_acl_blob_get_fd
);
2612 return handle
->fns
->sys_acl_blob_get_fd_fn(handle
, fsp
, mem_ctx
, blob_description
, blob
);
2615 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct
*handle
,
2616 const struct smb_filename
*smb_fname
,
2617 SMB_ACL_TYPE_T acltype
,
2620 VFS_FIND(sys_acl_set_file
);
2621 return handle
->fns
->sys_acl_set_file_fn(handle
, smb_fname
,
2625 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct
*handle
,
2626 struct files_struct
*fsp
, SMB_ACL_T theacl
)
2628 VFS_FIND(sys_acl_set_fd
);
2629 return handle
->fns
->sys_acl_set_fd_fn(handle
, fsp
, theacl
);
2632 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct
*handle
,
2633 const struct smb_filename
*smb_fname
)
2635 VFS_FIND(sys_acl_delete_def_file
);
2636 return handle
->fns
->sys_acl_delete_def_file_fn(handle
, smb_fname
);
2639 ssize_t
smb_vfs_call_getxattr(struct vfs_handle_struct
*handle
,
2640 const struct smb_filename
*smb_fname
,
2646 return handle
->fns
->getxattr_fn(handle
, smb_fname
, name
, value
, size
);
2650 struct smb_vfs_call_getxattrat_state
{
2651 files_struct
*dir_fsp
;
2652 ssize_t (*recv_fn
)(struct tevent_req
*req
,
2653 struct vfs_aio_state
*aio_state
,
2654 TALLOC_CTX
*mem_ctx
,
2655 uint8_t **xattr_value
);
2657 uint8_t *xattr_value
;
2658 struct vfs_aio_state aio_state
;
2661 static void smb_vfs_call_getxattrat_done(struct tevent_req
*subreq
);
2663 struct tevent_req
*smb_vfs_call_getxattrat_send(
2664 TALLOC_CTX
*mem_ctx
,
2665 struct tevent_context
*ev
,
2666 struct vfs_handle_struct
*handle
,
2667 files_struct
*dir_fsp
,
2668 const struct smb_filename
*smb_fname
,
2669 const char *xattr_name
,
2672 struct tevent_req
*req
= NULL
;
2673 struct smb_vfs_call_getxattrat_state
*state
= NULL
;
2674 struct tevent_req
*subreq
= NULL
;
2676 req
= tevent_req_create(mem_ctx
, &state
,
2677 struct smb_vfs_call_getxattrat_state
);
2682 VFS_FIND(getxattrat_send
);
2684 *state
= (struct smb_vfs_call_getxattrat_state
) {
2686 .recv_fn
= handle
->fns
->getxattrat_recv_fn
,
2689 subreq
= handle
->fns
->getxattrat_send_fn(mem_ctx
,
2696 if (tevent_req_nomem(subreq
, req
)) {
2697 return tevent_req_post(req
, ev
);
2699 tevent_req_defer_callback(req
, ev
);
2701 tevent_req_set_callback(subreq
, smb_vfs_call_getxattrat_done
, req
);
2705 static void smb_vfs_call_getxattrat_done(struct tevent_req
*subreq
)
2707 struct tevent_req
*req
= tevent_req_callback_data(
2708 subreq
, struct tevent_req
);
2709 struct smb_vfs_call_getxattrat_state
*state
= tevent_req_data(
2710 req
, struct smb_vfs_call_getxattrat_state
);
2714 * Make sure we run as the user again
2716 ok
= change_to_user_and_service_by_fsp(state
->dir_fsp
);
2719 state
->retval
= state
->recv_fn(subreq
,
2722 &state
->xattr_value
);
2723 TALLOC_FREE(subreq
);
2724 if (state
->retval
== -1) {
2725 tevent_req_error(req
, state
->aio_state
.error
);
2729 tevent_req_done(req
);
2732 ssize_t
smb_vfs_call_getxattrat_recv(struct tevent_req
*req
,
2733 struct vfs_aio_state
*aio_state
,
2734 TALLOC_CTX
*mem_ctx
,
2735 uint8_t **xattr_value
)
2737 struct smb_vfs_call_getxattrat_state
*state
= tevent_req_data(
2738 req
, struct smb_vfs_call_getxattrat_state
);
2741 if (tevent_req_is_unix_error(req
, &aio_state
->error
)) {
2742 tevent_req_received(req
);
2746 *aio_state
= state
->aio_state
;
2747 xattr_size
= state
->retval
;
2748 if (xattr_value
!= NULL
) {
2749 *xattr_value
= talloc_move(mem_ctx
, &state
->xattr_value
);
2752 tevent_req_received(req
);
2756 ssize_t
smb_vfs_call_fgetxattr(struct vfs_handle_struct
*handle
,
2757 struct files_struct
*fsp
, const char *name
,
2758 void *value
, size_t size
)
2760 VFS_FIND(fgetxattr
);
2761 return handle
->fns
->fgetxattr_fn(handle
, fsp
, name
, value
, size
);
2764 ssize_t
smb_vfs_call_listxattr(struct vfs_handle_struct
*handle
,
2765 const struct smb_filename
*smb_fname
,
2769 VFS_FIND(listxattr
);
2770 return handle
->fns
->listxattr_fn(handle
, smb_fname
, list
, size
);
2773 ssize_t
smb_vfs_call_flistxattr(struct vfs_handle_struct
*handle
,
2774 struct files_struct
*fsp
, char *list
,
2777 VFS_FIND(flistxattr
);
2778 return handle
->fns
->flistxattr_fn(handle
, fsp
, list
, size
);
2781 int smb_vfs_call_removexattr(struct vfs_handle_struct
*handle
,
2782 const struct smb_filename
*smb_fname
,
2785 VFS_FIND(removexattr
);
2786 return handle
->fns
->removexattr_fn(handle
, smb_fname
, name
);
2789 int smb_vfs_call_fremovexattr(struct vfs_handle_struct
*handle
,
2790 struct files_struct
*fsp
, const char *name
)
2792 VFS_FIND(fremovexattr
);
2793 return handle
->fns
->fremovexattr_fn(handle
, fsp
, name
);
2796 int smb_vfs_call_setxattr(struct vfs_handle_struct
*handle
,
2797 const struct smb_filename
*smb_fname
,
2804 return handle
->fns
->setxattr_fn(handle
, smb_fname
,
2805 name
, value
, size
, flags
);
2808 int smb_vfs_call_fsetxattr(struct vfs_handle_struct
*handle
,
2809 struct files_struct
*fsp
, const char *name
,
2810 const void *value
, size_t size
, int flags
)
2812 VFS_FIND(fsetxattr
);
2813 return handle
->fns
->fsetxattr_fn(handle
, fsp
, name
, value
, size
, flags
);
2816 bool smb_vfs_call_aio_force(struct vfs_handle_struct
*handle
,
2817 struct files_struct
*fsp
)
2819 VFS_FIND(aio_force
);
2820 return handle
->fns
->aio_force_fn(handle
, fsp
);
2823 NTSTATUS
smb_vfs_call_durable_cookie(struct vfs_handle_struct
*handle
,
2824 struct files_struct
*fsp
,
2825 TALLOC_CTX
*mem_ctx
,
2828 VFS_FIND(durable_cookie
);
2829 return handle
->fns
->durable_cookie_fn(handle
, fsp
, mem_ctx
, cookie
);
2832 NTSTATUS
smb_vfs_call_durable_disconnect(struct vfs_handle_struct
*handle
,
2833 struct files_struct
*fsp
,
2834 const DATA_BLOB old_cookie
,
2835 TALLOC_CTX
*mem_ctx
,
2836 DATA_BLOB
*new_cookie
)
2838 VFS_FIND(durable_disconnect
);
2839 return handle
->fns
->durable_disconnect_fn(handle
, fsp
, old_cookie
,
2840 mem_ctx
, new_cookie
);
2843 NTSTATUS
smb_vfs_call_durable_reconnect(struct vfs_handle_struct
*handle
,
2844 struct smb_request
*smb1req
,
2845 struct smbXsrv_open
*op
,
2846 const DATA_BLOB old_cookie
,
2847 TALLOC_CTX
*mem_ctx
,
2848 struct files_struct
**fsp
,
2849 DATA_BLOB
*new_cookie
)
2851 VFS_FIND(durable_reconnect
);
2852 return handle
->fns
->durable_reconnect_fn(handle
, smb1req
, op
,
2853 old_cookie
, mem_ctx
, fsp
,
2857 NTSTATUS
smb_vfs_call_readdir_attr(struct vfs_handle_struct
*handle
,
2858 const struct smb_filename
*fname
,
2859 TALLOC_CTX
*mem_ctx
,
2860 struct readdir_attr_data
**attr_data
)
2862 VFS_FIND(readdir_attr
);
2863 return handle
->fns
->readdir_attr_fn(handle
, fname
, mem_ctx
, attr_data
);