2 Unix SMB/Netbios implementation.
4 VFS initialisation and support functions
5 Copyright (C) Tim Potter 1999
6 Copyright (C) Alexander Bokovoy 2002
7 Copyright (C) James Peach 2006
8 Copyright (C) Volker Lendecke 2009
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 This work was sponsored by Optifacio Software Services, Inc.
27 #include "system/filesys.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
31 #include "transfer_file.h"
33 #include "lib/util/tevent_unix.h"
36 #define DBGC_CLASS DBGC_VFS
41 struct vfs_fsp_data
*next
;
42 struct vfs_handle_struct
*owner
;
43 void (*destroy
)(void *p_data
);
45 /* NOTE: This structure contains four pointers so that we can guarantee
46 * that the end of the structure is always both 4-byte and 8-byte aligned.
50 struct vfs_init_function_entry
{
52 struct vfs_init_function_entry
*prev
, *next
;
53 const struct vfs_fn_pointers
*fns
;
56 /****************************************************************************
57 maintain the list of available backends
58 ****************************************************************************/
60 static struct vfs_init_function_entry
*vfs_find_backend_entry(const char *name
)
62 struct vfs_init_function_entry
*entry
= backends
;
64 DEBUG(10, ("vfs_find_backend_entry called for %s\n", name
));
67 if (strcmp(entry
->name
, name
)==0) return entry
;
74 NTSTATUS
smb_register_vfs(int version
, const char *name
,
75 const struct vfs_fn_pointers
*fns
)
77 struct vfs_init_function_entry
*entry
= backends
;
79 if ((version
!= SMB_VFS_INTERFACE_VERSION
)) {
80 DEBUG(0, ("Failed to register vfs module.\n"
81 "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
82 "current SMB_VFS_INTERFACE_VERSION is %d.\n"
83 "Please recompile against the current Samba Version!\n",
84 version
, SMB_VFS_INTERFACE_VERSION
));
85 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
88 if (!name
|| !name
[0]) {
89 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
90 return NT_STATUS_INVALID_PARAMETER
;
93 if (vfs_find_backend_entry(name
)) {
94 DEBUG(0,("VFS module %s already loaded!\n", name
));
95 return NT_STATUS_OBJECT_NAME_COLLISION
;
98 entry
= SMB_XMALLOC_P(struct vfs_init_function_entry
);
99 entry
->name
= smb_xstrdup(name
);
102 DLIST_ADD(backends
, entry
);
103 DEBUG(5, ("Successfully added vfs backend '%s'\n", name
));
107 /****************************************************************************
108 initialise default vfs hooks
109 ****************************************************************************/
111 static void vfs_init_default(connection_struct
*conn
)
113 DEBUG(3, ("Initialising default vfs hooks\n"));
114 vfs_init_custom(conn
, DEFAULT_VFS_MODULE_NAME
);
117 /****************************************************************************
118 initialise custom vfs hooks
119 ****************************************************************************/
121 bool vfs_init_custom(connection_struct
*conn
, const char *vfs_object
)
123 char *module_path
= NULL
;
124 char *module_name
= NULL
;
125 char *module_param
= NULL
, *p
;
126 vfs_handle_struct
*handle
;
127 const struct vfs_init_function_entry
*entry
;
129 if (!conn
||!vfs_object
||!vfs_object
[0]) {
130 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
131 "empty vfs_object!\n"));
139 DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object
));
141 module_path
= smb_xstrdup(vfs_object
);
143 p
= strchr_m(module_path
, ':');
148 trim_char(module_param
, ' ', ' ');
151 trim_char(module_path
, ' ', ' ');
153 module_name
= smb_xstrdup(module_path
);
155 if ((module_name
[0] == '/') &&
156 (strcmp(module_path
, DEFAULT_VFS_MODULE_NAME
) != 0)) {
159 * Extract the module name from the path. Just use the base
160 * name of the last path component.
163 SAFE_FREE(module_name
);
164 module_name
= smb_xstrdup(strrchr_m(module_path
, '/')+1);
166 p
= strchr_m(module_name
, '.');
173 /* First, try to load the module with the new module system */
174 entry
= vfs_find_backend_entry(module_name
);
178 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
181 status
= smb_load_module("vfs", module_path
);
182 if (!NT_STATUS_IS_OK(status
)) {
183 DEBUG(0, ("error probing vfs module '%s': %s\n",
184 module_path
, nt_errstr(status
)));
188 entry
= vfs_find_backend_entry(module_name
);
190 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object
));
195 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object
));
197 handle
= talloc_zero(conn
, vfs_handle_struct
);
199 DEBUG(0,("TALLOC_ZERO() failed!\n"));
203 handle
->fns
= entry
->fns
;
205 handle
->param
= talloc_strdup(conn
, module_param
);
207 DLIST_ADD(conn
->vfs_handles
, handle
);
209 SAFE_FREE(module_path
);
210 SAFE_FREE(module_name
);
214 SAFE_FREE(module_path
);
215 SAFE_FREE(module_name
);
219 /*****************************************************************
220 Allow VFS modules to extend files_struct with VFS-specific state.
221 This will be ok for small numbers of extensions, but might need to
222 be refactored if it becomes more widely used.
223 ******************************************************************/
225 #define EXT_DATA_AREA(e) ((uint8 *)(e) + sizeof(struct vfs_fsp_data))
227 void *vfs_add_fsp_extension_notype(vfs_handle_struct
*handle
,
228 files_struct
*fsp
, size_t ext_size
,
229 void (*destroy_fn
)(void *p_data
))
231 struct vfs_fsp_data
*ext
;
234 /* Prevent VFS modules adding multiple extensions. */
235 if ((ext_data
= vfs_fetch_fsp_extension(handle
, fsp
))) {
239 ext
= (struct vfs_fsp_data
*)TALLOC_ZERO(
240 handle
->conn
, sizeof(struct vfs_fsp_data
) + ext_size
);
246 ext
->next
= fsp
->vfs_extension
;
247 ext
->destroy
= destroy_fn
;
248 fsp
->vfs_extension
= ext
;
249 return EXT_DATA_AREA(ext
);
252 void vfs_remove_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
254 struct vfs_fsp_data
*curr
;
255 struct vfs_fsp_data
*prev
;
257 for (curr
= fsp
->vfs_extension
, prev
= NULL
;
259 prev
= curr
, curr
= curr
->next
) {
260 if (curr
->owner
== handle
) {
262 prev
->next
= curr
->next
;
264 fsp
->vfs_extension
= curr
->next
;
267 curr
->destroy(EXT_DATA_AREA(curr
));
275 void vfs_remove_all_fsp_extensions(files_struct
*fsp
)
277 struct vfs_fsp_data
*curr
;
278 struct vfs_fsp_data
*next
;
280 for (curr
= fsp
->vfs_extension
; curr
; curr
= next
) {
283 fsp
->vfs_extension
= next
;
286 curr
->destroy(EXT_DATA_AREA(curr
));
292 void *vfs_memctx_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
294 struct vfs_fsp_data
*head
;
296 for (head
= fsp
->vfs_extension
; head
; head
= head
->next
) {
297 if (head
->owner
== handle
) {
305 void *vfs_fetch_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
307 struct vfs_fsp_data
*head
;
309 head
= (struct vfs_fsp_data
*)vfs_memctx_fsp_extension(handle
, fsp
);
311 return EXT_DATA_AREA(head
);
319 /*****************************************************************
321 ******************************************************************/
323 bool smbd_vfs_init(connection_struct
*conn
)
325 const char **vfs_objects
;
329 /* Normal share - initialise with disk access functions */
330 vfs_init_default(conn
);
332 /* No need to load vfs modules for printer connections */
337 vfs_objects
= lp_vfs_objects(SNUM(conn
));
339 /* Override VFS functions if 'vfs object' was not specified*/
340 if (!vfs_objects
|| !vfs_objects
[0])
343 for (i
=0; vfs_objects
[i
] ;) {
347 for (j
=i
-1; j
>= 0; j
--) {
348 if (!vfs_init_custom(conn
, vfs_objects
[j
])) {
349 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects
[j
]));
356 /*******************************************************************
357 Check if a file exists in the vfs.
358 ********************************************************************/
360 NTSTATUS
vfs_file_exist(connection_struct
*conn
, struct smb_filename
*smb_fname
)
362 /* Only return OK if stat was successful and S_ISREG */
363 if ((SMB_VFS_STAT(conn
, smb_fname
) != -1) &&
364 S_ISREG(smb_fname
->st
.st_ex_mode
)) {
368 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
371 /****************************************************************************
372 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
373 ****************************************************************************/
375 ssize_t
vfs_read_data(files_struct
*fsp
, char *buf
, size_t byte_count
)
379 while (total
< byte_count
)
381 ssize_t ret
= SMB_VFS_READ(fsp
, buf
+ total
,
384 if (ret
== 0) return total
;
393 return (ssize_t
)total
;
396 ssize_t
vfs_pread_data(files_struct
*fsp
, char *buf
,
397 size_t byte_count
, off_t offset
)
401 while (total
< byte_count
)
403 ssize_t ret
= SMB_VFS_PREAD(fsp
, buf
+ total
,
404 byte_count
- total
, offset
+ total
);
406 if (ret
== 0) return total
;
415 return (ssize_t
)total
;
418 /****************************************************************************
419 Write data to a fd on the vfs.
420 ****************************************************************************/
422 ssize_t
vfs_write_data(struct smb_request
*req
,
430 if (req
&& req
->unread_bytes
) {
431 SMB_ASSERT(req
->unread_bytes
== N
);
432 /* VFS_RECVFILE must drain the socket
433 * before returning. */
434 req
->unread_bytes
= 0;
435 return SMB_VFS_RECVFILE(req
->sconn
->sock
,
442 ret
= SMB_VFS_WRITE(fsp
, buffer
+ total
, N
- total
);
451 return (ssize_t
)total
;
454 ssize_t
vfs_pwrite_data(struct smb_request
*req
,
463 if (req
&& req
->unread_bytes
) {
464 SMB_ASSERT(req
->unread_bytes
== N
);
465 /* VFS_RECVFILE must drain the socket
466 * before returning. */
467 req
->unread_bytes
= 0;
468 return SMB_VFS_RECVFILE(req
->sconn
->sock
,
475 ret
= SMB_VFS_PWRITE(fsp
, buffer
+ total
, N
- total
,
485 return (ssize_t
)total
;
487 /****************************************************************************
488 An allocate file space call using the vfs interface.
489 Allocates space for a file from a filedescriptor.
490 Returns 0 on success, -1 on failure.
491 ****************************************************************************/
493 int vfs_allocate_file_space(files_struct
*fsp
, uint64_t len
)
496 connection_struct
*conn
= fsp
->conn
;
497 uint64_t space_avail
;
498 uint64_t bsize
,dfree
,dsize
;
502 * Actually try and commit the space on disk....
505 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
506 fsp_str_dbg(fsp
), (double)len
));
508 if (((off_t
)len
) < 0) {
509 DEBUG(0,("vfs_allocate_file_space: %s negative len "
510 "requested.\n", fsp_str_dbg(fsp
)));
515 status
= vfs_stat_fsp(fsp
);
516 if (!NT_STATUS_IS_OK(status
)) {
520 if (len
== (uint64_t)fsp
->fsp_name
->st
.st_ex_size
)
523 if (len
< (uint64_t)fsp
->fsp_name
->st
.st_ex_size
) {
524 /* Shrink - use ftruncate. */
526 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
527 "size %.0f\n", fsp_str_dbg(fsp
),
528 (double)fsp
->fsp_name
->st
.st_ex_size
));
530 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_ALLOC_SHRINK
);
532 flush_write_cache(fsp
, SIZECHANGE_FLUSH
);
533 if ((ret
= SMB_VFS_FTRUNCATE(fsp
, (off_t
)len
)) != -1) {
534 set_filelen_write_cache(fsp
, len
);
537 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_ALLOC_SHRINK
);
542 if (!lp_strict_allocate(SNUM(fsp
->conn
)))
545 /* Grow - we need to test if we have enough space. */
547 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_ALLOC_GROW
);
549 /* See if we have a syscall that will allocate beyond end-of-file
550 without changing EOF. */
551 ret
= SMB_VFS_FALLOCATE(fsp
, VFS_FALLOCATE_KEEP_SIZE
, 0, len
);
553 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_ALLOC_GROW
);
556 /* We changed the allocation size on disk, but not
557 EOF - exactly as required. We're done ! */
561 len
-= fsp
->fsp_name
->st
.st_ex_size
;
562 len
/= 1024; /* Len is now number of 1k blocks needed. */
563 space_avail
= get_dfree_info(conn
, fsp
->fsp_name
->base_name
, false,
564 &bsize
, &dfree
, &dsize
);
565 if (space_avail
== (uint64_t)-1) {
569 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
570 "needed blocks = %.0f, space avail = %.0f\n",
571 fsp_str_dbg(fsp
), (double)fsp
->fsp_name
->st
.st_ex_size
, (double)len
,
572 (double)space_avail
));
574 if (len
> space_avail
) {
582 /****************************************************************************
583 A vfs set_filelen call.
584 set the length of a file from a filedescriptor.
585 Returns 0 on success, -1 on failure.
586 ****************************************************************************/
588 int vfs_set_filelen(files_struct
*fsp
, off_t len
)
592 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_SET_FILE_LEN
);
594 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
595 fsp_str_dbg(fsp
), (double)len
));
596 flush_write_cache(fsp
, SIZECHANGE_FLUSH
);
597 if ((ret
= SMB_VFS_FTRUNCATE(fsp
, len
)) != -1) {
598 set_filelen_write_cache(fsp
, len
);
599 notify_fname(fsp
->conn
, NOTIFY_ACTION_MODIFIED
,
600 FILE_NOTIFY_CHANGE_SIZE
601 | FILE_NOTIFY_CHANGE_ATTRIBUTES
,
602 fsp
->fsp_name
->base_name
);
605 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_SET_FILE_LEN
);
610 /****************************************************************************
611 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
612 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
613 as this is also called from the default SMB_VFS_FTRUNCATE code.
614 Always extends the file size.
615 Returns 0 on success, errno on failure.
616 ****************************************************************************/
618 #define SPARSE_BUF_WRITE_SIZE (32*1024)
620 int vfs_slow_fallocate(files_struct
*fsp
, off_t offset
, off_t len
)
626 sparse_buf
= SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE
);
633 while (total
< len
) {
634 size_t curr_write_size
= MIN(SPARSE_BUF_WRITE_SIZE
, (len
- total
));
636 pwrite_ret
= SMB_VFS_PWRITE(fsp
, sparse_buf
, curr_write_size
, offset
+ total
);
637 if (pwrite_ret
== -1) {
638 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
639 "%s failed with error %s\n",
640 fsp_str_dbg(fsp
), strerror(errno
)));
649 /****************************************************************************
650 A vfs fill sparse call.
651 Writes zeros from the end of file to len, if len is greater than EOF.
652 Used only by strict_sync.
653 Returns 0 on success, -1 on failure.
654 ****************************************************************************/
656 int vfs_fill_sparse(files_struct
*fsp
, off_t len
)
663 status
= vfs_stat_fsp(fsp
);
664 if (!NT_STATUS_IS_OK(status
)) {
668 if (len
<= fsp
->fsp_name
->st
.st_ex_size
) {
673 if (S_ISFIFO(fsp
->fsp_name
->st
.st_ex_mode
)) {
678 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
679 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp
),
680 (double)fsp
->fsp_name
->st
.st_ex_size
, (double)len
,
681 (double)(len
- fsp
->fsp_name
->st
.st_ex_size
)));
683 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_FILL_SPARSE
);
685 flush_write_cache(fsp
, SIZECHANGE_FLUSH
);
687 offset
= fsp
->fsp_name
->st
.st_ex_size
;
688 num_to_write
= len
- fsp
->fsp_name
->st
.st_ex_size
;
690 /* Only do this on non-stream file handles. */
691 if (fsp
->base_fsp
== NULL
) {
692 /* for allocation try fallocate first. This can fail on some
693 * platforms e.g. when the filesystem doesn't support it and no
694 * emulation is being done by the libc (like on AIX with JFS1). In that
695 * case we do our own emulation. fallocate implementations can
696 * return ENOTSUP or EINVAL in cases like that. */
697 ret
= SMB_VFS_FALLOCATE(fsp
, VFS_FALLOCATE_EXTEND_SIZE
,
698 offset
, num_to_write
);
707 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
708 "error %d. Falling back to slow manual allocation\n", ret
));
711 ret
= vfs_slow_fallocate(fsp
, offset
, num_to_write
);
720 set_filelen_write_cache(fsp
, len
);
723 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_FILL_SPARSE
);
727 /****************************************************************************
728 Transfer some data (n bytes) between two file_struct's.
729 ****************************************************************************/
731 static ssize_t
vfs_read_fn(void *file
, void *buf
, size_t len
)
733 struct files_struct
*fsp
= (struct files_struct
*)file
;
735 return SMB_VFS_READ(fsp
, buf
, len
);
738 static ssize_t
vfs_write_fn(void *file
, const void *buf
, size_t len
)
740 struct files_struct
*fsp
= (struct files_struct
*)file
;
742 return SMB_VFS_WRITE(fsp
, buf
, len
);
745 off_t
vfs_transfer_file(files_struct
*in
, files_struct
*out
, off_t n
)
747 return transfer_file_internal((void *)in
, (void *)out
, n
,
748 vfs_read_fn
, vfs_write_fn
);
751 /*******************************************************************
752 A vfs_readdir wrapper which just returns the file name.
753 ********************************************************************/
755 const char *vfs_readdirname(connection_struct
*conn
, void *p
,
756 SMB_STRUCT_STAT
*sbuf
, char **talloced
)
758 struct dirent
*ptr
= NULL
;
766 ptr
= SMB_VFS_READDIR(conn
, (DIR *)p
, sbuf
);
778 #ifdef HAVE_BROKEN_READDIR_NAME
779 /* using /usr/ucb/cc is BAD */
783 status
= SMB_VFS_TRANSLATE_NAME(conn
, dname
, vfs_translate_to_windows
,
784 talloc_tos(), &translated
);
785 if (NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
789 *talloced
= translated
;
790 if (!NT_STATUS_IS_OK(status
)) {
796 /*******************************************************************
797 A wrapper for vfs_chdir().
798 ********************************************************************/
800 int vfs_ChDir(connection_struct
*conn
, const char *path
)
805 LastDir
= SMB_STRDUP("");
808 if (strcsequal(path
,".")) {
812 if (*path
== '/' && strcsequal(LastDir
,path
)) {
816 DEBUG(4,("vfs_ChDir to %s\n",path
));
818 ret
= SMB_VFS_CHDIR(conn
,path
);
822 LastDir
= SMB_STRDUP(path
);
825 TALLOC_FREE(conn
->cwd
);
826 conn
->cwd
= vfs_GetWd(conn
, conn
);
827 DEBUG(4,("vfs_ChDir got %s\n",conn
->cwd
));
832 /*******************************************************************
833 Return the absolute current directory path - given a UNIX pathname.
834 Note that this path is returned in DOS format, not UNIX
835 format. Note this can be called with conn == NULL.
836 ********************************************************************/
838 char *vfs_GetWd(TALLOC_CTX
*ctx
, connection_struct
*conn
)
840 char *current_dir
= NULL
;
842 DATA_BLOB cache_value
;
844 struct smb_filename
*smb_fname_dot
= NULL
;
845 struct smb_filename
*smb_fname_full
= NULL
;
847 if (!lp_getwd_cache()) {
851 smb_fname_dot
= synthetic_smb_fname(ctx
, ".", NULL
, NULL
);
852 if (smb_fname_dot
== NULL
) {
857 if (SMB_VFS_STAT(conn
, smb_fname_dot
) == -1) {
859 * Known to fail for root: the directory may be NFS-mounted
860 * and exported with root_squash (so has no root access).
862 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
863 "(NFS problem ?)\n", strerror(errno
) ));
867 key
= vfs_file_id_from_sbuf(conn
, &smb_fname_dot
->st
);
869 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE
,
870 data_blob_const(&key
, sizeof(key
)),
875 SMB_ASSERT((cache_value
.length
> 0)
876 && (cache_value
.data
[cache_value
.length
-1] == '\0'));
878 smb_fname_full
= synthetic_smb_fname(ctx
, (char *)cache_value
.data
,
880 if (smb_fname_full
== NULL
) {
885 if ((SMB_VFS_STAT(conn
, smb_fname_full
) == 0) &&
886 (smb_fname_dot
->st
.st_ex_dev
== smb_fname_full
->st
.st_ex_dev
) &&
887 (smb_fname_dot
->st
.st_ex_ino
== smb_fname_full
->st
.st_ex_ino
) &&
888 (S_ISDIR(smb_fname_dot
->st
.st_ex_mode
))) {
892 result
= talloc_strdup(ctx
, smb_fname_full
->base_name
);
893 if (result
== NULL
) {
902 * We don't have the information to hand so rely on traditional
903 * methods. The very slow getcwd, which spawns a process on some
904 * systems, or the not quite so bad getwd.
907 current_dir
= SMB_VFS_GETWD(conn
);
908 if (current_dir
== NULL
) {
909 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
914 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot
->st
)) {
915 key
= vfs_file_id_from_sbuf(conn
, &smb_fname_dot
->st
);
917 memcache_add(smbd_memcache(), GETWD_CACHE
,
918 data_blob_const(&key
, sizeof(key
)),
919 data_blob_const(current_dir
,
920 strlen(current_dir
)+1));
923 result
= talloc_strdup(ctx
, current_dir
);
924 if (result
== NULL
) {
929 TALLOC_FREE(smb_fname_dot
);
930 TALLOC_FREE(smb_fname_full
);
931 SAFE_FREE(current_dir
);
935 /*******************************************************************
936 Reduce a file name, removing .. elements and checking that
937 it is below dir in the heirachy. This uses realpath.
938 This function must run as root, and will return names
939 and valid stat structs that can be checked on open.
940 ********************************************************************/
942 NTSTATUS
check_reduced_name_with_privilege(connection_struct
*conn
,
944 struct smb_request
*smbreq
)
947 TALLOC_CTX
*ctx
= talloc_tos();
948 const char *conn_rootdir
;
950 char *dir_name
= NULL
;
951 const char *last_component
= NULL
;
952 char *resolved_name
= NULL
;
953 char *saved_dir
= NULL
;
954 struct smb_filename
*smb_fname_cwd
= NULL
;
955 struct privilege_paths
*priv_paths
= NULL
;
958 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
963 priv_paths
= talloc_zero(smbreq
, struct privilege_paths
);
965 status
= NT_STATUS_NO_MEMORY
;
969 if (!parent_dirname(ctx
, fname
, &dir_name
, &last_component
)) {
970 status
= NT_STATUS_NO_MEMORY
;
974 priv_paths
->parent_name
.base_name
= talloc_strdup(priv_paths
, dir_name
);
975 priv_paths
->file_name
.base_name
= talloc_strdup(priv_paths
, last_component
);
977 if (priv_paths
->parent_name
.base_name
== NULL
||
978 priv_paths
->file_name
.base_name
== NULL
) {
979 status
= NT_STATUS_NO_MEMORY
;
983 if (SMB_VFS_STAT(conn
, &priv_paths
->parent_name
) != 0) {
984 status
= map_nt_error_from_unix(errno
);
987 /* Remember where we were. */
988 saved_dir
= vfs_GetWd(ctx
, conn
);
990 status
= map_nt_error_from_unix(errno
);
994 /* Go to the parent directory to lock in memory. */
995 if (vfs_ChDir(conn
, priv_paths
->parent_name
.base_name
) == -1) {
996 status
= map_nt_error_from_unix(errno
);
1000 /* Get the absolute path of the parent directory. */
1001 resolved_name
= SMB_VFS_REALPATH(conn
,".");
1002 if (!resolved_name
) {
1003 status
= map_nt_error_from_unix(errno
);
1007 if (*resolved_name
!= '/') {
1008 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1009 "doesn't return absolute paths !\n"));
1010 status
= NT_STATUS_OBJECT_NAME_INVALID
;
1014 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1015 priv_paths
->parent_name
.base_name
,
1018 /* Now check the stat value is the same. */
1019 smb_fname_cwd
= synthetic_smb_fname(talloc_tos(), ".", NULL
, NULL
);
1020 if (smb_fname_cwd
== NULL
) {
1021 status
= NT_STATUS_NO_MEMORY
;
1025 if (SMB_VFS_LSTAT(conn
, smb_fname_cwd
) != 0) {
1026 status
= map_nt_error_from_unix(errno
);
1030 /* Ensure we're pointing at the same place. */
1031 if (!check_same_stat(&smb_fname_cwd
->st
, &priv_paths
->parent_name
.st
)) {
1032 DEBUG(0,("check_reduced_name_with_privilege: "
1033 "device/inode/uid/gid on directory %s changed. "
1034 "Denying access !\n",
1035 priv_paths
->parent_name
.base_name
));
1036 status
= NT_STATUS_ACCESS_DENIED
;
1040 /* Ensure we're below the connect path. */
1042 conn_rootdir
= SMB_VFS_CONNECTPATH(conn
, fname
);
1043 if (conn_rootdir
== NULL
) {
1044 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1046 status
= NT_STATUS_ACCESS_DENIED
;
1050 rootdir_len
= strlen(conn_rootdir
);
1051 if (strncmp(conn_rootdir
, resolved_name
, rootdir_len
) != 0) {
1052 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1053 "attempt: %s is a symlink outside the "
1056 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir
));
1057 DEBUGADD(2, ("resolved_name=%s\n", resolved_name
));
1058 status
= NT_STATUS_ACCESS_DENIED
;
1062 /* Now ensure that the last component either doesn't
1063 exist, or is *NOT* a symlink. */
1065 ret
= SMB_VFS_LSTAT(conn
, &priv_paths
->file_name
);
1067 /* Errno must be ENOENT for this be ok. */
1068 if (errno
!= ENOENT
) {
1069 status
= map_nt_error_from_unix(errno
);
1070 DEBUG(2, ("check_reduced_name_with_privilege: "
1071 "LSTAT on %s failed with %s\n",
1072 priv_paths
->file_name
.base_name
,
1073 nt_errstr(status
)));
1078 if (VALID_STAT(priv_paths
->file_name
.st
) &&
1079 S_ISLNK(priv_paths
->file_name
.st
.st_ex_mode
)) {
1080 DEBUG(2, ("check_reduced_name_with_privilege: "
1081 "Last component %s is a symlink. Denying"
1083 priv_paths
->file_name
.base_name
));
1084 status
= NT_STATUS_ACCESS_DENIED
;
1088 smbreq
->priv_paths
= priv_paths
;
1089 status
= NT_STATUS_OK
;
1094 vfs_ChDir(conn
, saved_dir
);
1096 SAFE_FREE(resolved_name
);
1097 if (!NT_STATUS_IS_OK(status
)) {
1098 TALLOC_FREE(priv_paths
);
1100 TALLOC_FREE(dir_name
);
1104 /*******************************************************************
1105 Reduce a file name, removing .. elements and checking that
1106 it is below dir in the heirachy. This uses realpath.
1107 ********************************************************************/
1109 NTSTATUS
check_reduced_name(connection_struct
*conn
, const char *fname
)
1111 char *resolved_name
= NULL
;
1112 bool allow_symlinks
= true;
1113 bool allow_widelinks
= false;
1115 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname
, conn
->connectpath
));
1117 resolved_name
= SMB_VFS_REALPATH(conn
,fname
);
1119 if (!resolved_name
) {
1122 DEBUG(3,("check_reduced_name: Component not a "
1123 "directory in getting realpath for "
1125 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1128 TALLOC_CTX
*ctx
= talloc_tos();
1129 char *dir_name
= NULL
;
1130 const char *last_component
= NULL
;
1131 char *new_name
= NULL
;
1134 /* Last component didn't exist.
1135 Remove it and try and canonicalise
1136 the directory name. */
1137 if (!parent_dirname(ctx
, fname
,
1140 return NT_STATUS_NO_MEMORY
;
1143 resolved_name
= SMB_VFS_REALPATH(conn
,dir_name
);
1144 if (!resolved_name
) {
1145 NTSTATUS status
= map_nt_error_from_unix(errno
);
1147 if (errno
== ENOENT
|| errno
== ENOTDIR
) {
1148 status
= NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1151 DEBUG(3,("check_reduce_name: "
1152 "couldn't get realpath for "
1155 nt_errstr(status
)));
1158 ret
= asprintf(&new_name
, "%s/%s",
1159 resolved_name
, last_component
);
1160 SAFE_FREE(resolved_name
);
1162 return NT_STATUS_NO_MEMORY
;
1164 resolved_name
= new_name
;
1168 DEBUG(3,("check_reduced_name: couldn't get "
1169 "realpath for %s\n", fname
));
1170 return map_nt_error_from_unix(errno
);
1174 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname
,
1177 if (*resolved_name
!= '/') {
1178 DEBUG(0,("check_reduced_name: realpath doesn't return "
1179 "absolute paths !\n"));
1180 SAFE_FREE(resolved_name
);
1181 return NT_STATUS_OBJECT_NAME_INVALID
;
1184 allow_widelinks
= lp_widelinks(SNUM(conn
));
1185 allow_symlinks
= lp_symlinks(SNUM(conn
));
1187 /* Common widelinks and symlinks checks. */
1188 if (!allow_widelinks
|| !allow_symlinks
) {
1189 const char *conn_rootdir
;
1192 conn_rootdir
= SMB_VFS_CONNECTPATH(conn
, fname
);
1193 if (conn_rootdir
== NULL
) {
1194 DEBUG(2, ("check_reduced_name: Could not get "
1196 SAFE_FREE(resolved_name
);
1197 return NT_STATUS_ACCESS_DENIED
;
1200 rootdir_len
= strlen(conn_rootdir
);
1201 if (strncmp(conn_rootdir
, resolved_name
,
1202 rootdir_len
) != 0) {
1203 DEBUG(2, ("check_reduced_name: Bad access "
1204 "attempt: %s is a symlink outside the "
1205 "share path\n", fname
));
1206 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir
));
1207 DEBUGADD(2, ("resolved_name=%s\n", resolved_name
));
1208 SAFE_FREE(resolved_name
);
1209 return NT_STATUS_ACCESS_DENIED
;
1212 /* Extra checks if all symlinks are disallowed. */
1213 if (!allow_symlinks
) {
1214 /* fname can't have changed in resolved_path. */
1215 const char *p
= &resolved_name
[rootdir_len
];
1217 /* *p can be '\0' if fname was "." */
1218 if (*p
== '\0' && ISDOT(fname
)) {
1223 DEBUG(2, ("check_reduced_name: logic error (%c) "
1224 "in resolved_name: %s\n",
1227 SAFE_FREE(resolved_name
);
1228 return NT_STATUS_ACCESS_DENIED
;
1232 if (strcmp(fname
, p
)!=0) {
1233 DEBUG(2, ("check_reduced_name: Bad access "
1234 "attempt: %s is a symlink to %s\n",
1236 SAFE_FREE(resolved_name
);
1237 return NT_STATUS_ACCESS_DENIED
;
1244 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname
,
1246 SAFE_FREE(resolved_name
);
1247 return NT_STATUS_OK
;
1251 * XXX: This is temporary and there should be no callers of this once
1252 * smb_filename is plumbed through all path based operations.
1254 int vfs_stat_smb_fname(struct connection_struct
*conn
, const char *fname
,
1255 SMB_STRUCT_STAT
*psbuf
)
1257 struct smb_filename
*smb_fname
;
1260 smb_fname
= synthetic_smb_fname_split(talloc_tos(), fname
, NULL
);
1261 if (smb_fname
== NULL
) {
1266 if (lp_posix_pathnames()) {
1267 ret
= SMB_VFS_LSTAT(conn
, smb_fname
);
1269 ret
= SMB_VFS_STAT(conn
, smb_fname
);
1273 *psbuf
= smb_fname
->st
;
1276 TALLOC_FREE(smb_fname
);
1281 * XXX: This is temporary and there should be no callers of this once
1282 * smb_filename is plumbed through all path based operations.
1284 int vfs_lstat_smb_fname(struct connection_struct
*conn
, const char *fname
,
1285 SMB_STRUCT_STAT
*psbuf
)
1287 struct smb_filename
*smb_fname
;
1290 smb_fname
= synthetic_smb_fname_split(talloc_tos(), fname
, NULL
);
1291 if (smb_fname
== NULL
) {
1296 ret
= SMB_VFS_LSTAT(conn
, smb_fname
);
1298 *psbuf
= smb_fname
->st
;
1301 TALLOC_FREE(smb_fname
);
1306 * Ensure LSTAT is called for POSIX paths.
1309 NTSTATUS
vfs_stat_fsp(files_struct
*fsp
)
1313 if(fsp
->fh
->fd
== -1) {
1314 if (fsp
->posix_open
) {
1315 ret
= SMB_VFS_LSTAT(fsp
->conn
, fsp
->fsp_name
);
1317 ret
= SMB_VFS_STAT(fsp
->conn
, fsp
->fsp_name
);
1320 return map_nt_error_from_unix(errno
);
1323 if(SMB_VFS_FSTAT(fsp
, &fsp
->fsp_name
->st
) != 0) {
1324 return map_nt_error_from_unix(errno
);
1327 return NT_STATUS_OK
;
1331 * Initialize num_streams and streams, then call VFS op streaminfo
1333 NTSTATUS
vfs_streaminfo(connection_struct
*conn
,
1334 struct files_struct
*fsp
,
1336 TALLOC_CTX
*mem_ctx
,
1337 unsigned int *num_streams
,
1338 struct stream_struct
**streams
)
1342 return SMB_VFS_STREAMINFO(conn
, fsp
, fname
, mem_ctx
, num_streams
, streams
);
1346 generate a file_id from a stat structure
1348 struct file_id
vfs_file_id_from_sbuf(connection_struct
*conn
, const SMB_STRUCT_STAT
*sbuf
)
1350 return SMB_VFS_FILE_ID_CREATE(conn
, sbuf
);
1353 int smb_vfs_call_connect(struct vfs_handle_struct
*handle
,
1354 const char *service
, const char *user
)
1357 return handle
->fns
->connect_fn(handle
, service
, user
);
1360 void smb_vfs_call_disconnect(struct vfs_handle_struct
*handle
)
1362 VFS_FIND(disconnect
);
1363 handle
->fns
->disconnect_fn(handle
);
1366 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct
*handle
,
1367 const char *path
, bool small_query
,
1368 uint64_t *bsize
, uint64_t *dfree
,
1371 VFS_FIND(disk_free
);
1372 return handle
->fns
->disk_free_fn(handle
, path
, small_query
, bsize
,
1376 int smb_vfs_call_get_quota(struct vfs_handle_struct
*handle
,
1377 enum SMB_QUOTA_TYPE qtype
, unid_t id
,
1380 VFS_FIND(get_quota
);
1381 return handle
->fns
->get_quota_fn(handle
, qtype
, id
, qt
);
1384 int smb_vfs_call_set_quota(struct vfs_handle_struct
*handle
,
1385 enum SMB_QUOTA_TYPE qtype
, unid_t id
,
1388 VFS_FIND(set_quota
);
1389 return handle
->fns
->set_quota_fn(handle
, qtype
, id
, qt
);
1392 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct
*handle
,
1393 struct files_struct
*fsp
,
1394 struct shadow_copy_data
*shadow_copy_data
,
1397 VFS_FIND(get_shadow_copy_data
);
1398 return handle
->fns
->get_shadow_copy_data_fn(handle
, fsp
,
1402 int smb_vfs_call_statvfs(struct vfs_handle_struct
*handle
, const char *path
,
1403 struct vfs_statvfs_struct
*statbuf
)
1406 return handle
->fns
->statvfs_fn(handle
, path
, statbuf
);
1409 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct
*handle
,
1410 enum timestamp_set_resolution
*p_ts_res
)
1412 VFS_FIND(fs_capabilities
);
1413 return handle
->fns
->fs_capabilities_fn(handle
, p_ts_res
);
1416 NTSTATUS
smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct
*handle
,
1417 struct dfs_GetDFSReferral
*r
)
1419 VFS_FIND(get_dfs_referrals
);
1420 return handle
->fns
->get_dfs_referrals_fn(handle
, r
);
1423 DIR *smb_vfs_call_opendir(struct vfs_handle_struct
*handle
,
1424 const char *fname
, const char *mask
,
1428 return handle
->fns
->opendir_fn(handle
, fname
, mask
, attributes
);
1431 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct
*handle
,
1432 struct files_struct
*fsp
,
1436 VFS_FIND(fdopendir
);
1437 return handle
->fns
->fdopendir_fn(handle
, fsp
, mask
, attributes
);
1440 struct dirent
*smb_vfs_call_readdir(struct vfs_handle_struct
*handle
,
1442 SMB_STRUCT_STAT
*sbuf
)
1445 return handle
->fns
->readdir_fn(handle
, dirp
, sbuf
);
1448 void smb_vfs_call_seekdir(struct vfs_handle_struct
*handle
,
1449 DIR *dirp
, long offset
)
1452 handle
->fns
->seekdir_fn(handle
, dirp
, offset
);
1455 long smb_vfs_call_telldir(struct vfs_handle_struct
*handle
,
1459 return handle
->fns
->telldir_fn(handle
, dirp
);
1462 void smb_vfs_call_rewind_dir(struct vfs_handle_struct
*handle
,
1465 VFS_FIND(rewind_dir
);
1466 handle
->fns
->rewind_dir_fn(handle
, dirp
);
1469 int smb_vfs_call_mkdir(struct vfs_handle_struct
*handle
, const char *path
,
1473 return handle
->fns
->mkdir_fn(handle
, path
, mode
);
1476 int smb_vfs_call_rmdir(struct vfs_handle_struct
*handle
, const char *path
)
1479 return handle
->fns
->rmdir_fn(handle
, path
);
1482 int smb_vfs_call_closedir(struct vfs_handle_struct
*handle
,
1486 return handle
->fns
->closedir_fn(handle
, dir
);
1489 void smb_vfs_call_init_search_op(struct vfs_handle_struct
*handle
,
1492 VFS_FIND(init_search_op
);
1493 handle
->fns
->init_search_op_fn(handle
, dirp
);
1496 int smb_vfs_call_open(struct vfs_handle_struct
*handle
,
1497 struct smb_filename
*smb_fname
, struct files_struct
*fsp
,
1498 int flags
, mode_t mode
)
1501 return handle
->fns
->open_fn(handle
, smb_fname
, fsp
, flags
, mode
);
1504 NTSTATUS
smb_vfs_call_create_file(struct vfs_handle_struct
*handle
,
1505 struct smb_request
*req
,
1506 uint16_t root_dir_fid
,
1507 struct smb_filename
*smb_fname
,
1508 uint32_t access_mask
,
1509 uint32_t share_access
,
1510 uint32_t create_disposition
,
1511 uint32_t create_options
,
1512 uint32_t file_attributes
,
1513 uint32_t oplock_request
,
1514 uint64_t allocation_size
,
1515 uint32_t private_flags
,
1516 struct security_descriptor
*sd
,
1517 struct ea_list
*ea_list
,
1518 files_struct
**result
,
1521 VFS_FIND(create_file
);
1522 return handle
->fns
->create_file_fn(
1523 handle
, req
, root_dir_fid
, smb_fname
, access_mask
,
1524 share_access
, create_disposition
, create_options
,
1525 file_attributes
, oplock_request
, allocation_size
,
1526 private_flags
, sd
, ea_list
,
1530 int smb_vfs_call_close(struct vfs_handle_struct
*handle
,
1531 struct files_struct
*fsp
)
1534 return handle
->fns
->close_fn(handle
, fsp
);
1537 ssize_t
smb_vfs_call_read(struct vfs_handle_struct
*handle
,
1538 struct files_struct
*fsp
, void *data
, size_t n
)
1541 return handle
->fns
->read_fn(handle
, fsp
, data
, n
);
1544 ssize_t
smb_vfs_call_pread(struct vfs_handle_struct
*handle
,
1545 struct files_struct
*fsp
, void *data
, size_t n
,
1549 return handle
->fns
->pread_fn(handle
, fsp
, data
, n
, offset
);
1552 struct smb_vfs_call_pread_state
{
1553 ssize_t (*recv_fn
)(struct tevent_req
*req
, int *err
);
1557 static void smb_vfs_call_pread_done(struct tevent_req
*subreq
);
1559 struct tevent_req
*smb_vfs_call_pread_send(struct vfs_handle_struct
*handle
,
1560 TALLOC_CTX
*mem_ctx
,
1561 struct tevent_context
*ev
,
1562 struct files_struct
*fsp
,
1564 size_t n
, off_t offset
)
1566 struct tevent_req
*req
, *subreq
;
1567 struct smb_vfs_call_pread_state
*state
;
1569 req
= tevent_req_create(mem_ctx
, &state
,
1570 struct smb_vfs_call_pread_state
);
1574 VFS_FIND(pread_send
);
1575 state
->recv_fn
= handle
->fns
->pread_recv_fn
;
1577 subreq
= handle
->fns
->pread_send_fn(handle
, state
, ev
, fsp
, data
, n
,
1579 if (tevent_req_nomem(subreq
, req
)) {
1580 return tevent_req_post(req
, ev
);
1582 tevent_req_set_callback(subreq
, smb_vfs_call_pread_done
, req
);
1586 static void smb_vfs_call_pread_done(struct tevent_req
*subreq
)
1588 struct tevent_req
*req
= tevent_req_callback_data(
1589 subreq
, struct tevent_req
);
1590 struct smb_vfs_call_pread_state
*state
= tevent_req_data(
1591 req
, struct smb_vfs_call_pread_state
);
1594 state
->retval
= state
->recv_fn(subreq
, &err
);
1595 TALLOC_FREE(subreq
);
1596 if (state
->retval
== -1) {
1597 tevent_req_error(req
, err
);
1600 tevent_req_done(req
);
1603 ssize_t
SMB_VFS_PREAD_RECV(struct tevent_req
*req
, int *perrno
)
1605 struct smb_vfs_call_pread_state
*state
= tevent_req_data(
1606 req
, struct smb_vfs_call_pread_state
);
1609 if (tevent_req_is_unix_error(req
, &err
)) {
1613 return state
->retval
;
1616 ssize_t
smb_vfs_call_write(struct vfs_handle_struct
*handle
,
1617 struct files_struct
*fsp
, const void *data
,
1621 return handle
->fns
->write_fn(handle
, fsp
, data
, n
);
1624 ssize_t
smb_vfs_call_pwrite(struct vfs_handle_struct
*handle
,
1625 struct files_struct
*fsp
, const void *data
,
1626 size_t n
, off_t offset
)
1629 return handle
->fns
->pwrite_fn(handle
, fsp
, data
, n
, offset
);
1632 struct smb_vfs_call_pwrite_state
{
1633 ssize_t (*recv_fn
)(struct tevent_req
*req
, int *err
);
1637 static void smb_vfs_call_pwrite_done(struct tevent_req
*subreq
);
1639 struct tevent_req
*smb_vfs_call_pwrite_send(struct vfs_handle_struct
*handle
,
1640 TALLOC_CTX
*mem_ctx
,
1641 struct tevent_context
*ev
,
1642 struct files_struct
*fsp
,
1644 size_t n
, off_t offset
)
1646 struct tevent_req
*req
, *subreq
;
1647 struct smb_vfs_call_pwrite_state
*state
;
1649 req
= tevent_req_create(mem_ctx
, &state
,
1650 struct smb_vfs_call_pwrite_state
);
1654 VFS_FIND(pwrite_send
);
1655 state
->recv_fn
= handle
->fns
->pwrite_recv_fn
;
1657 subreq
= handle
->fns
->pwrite_send_fn(handle
, state
, ev
, fsp
, data
, n
,
1659 if (tevent_req_nomem(subreq
, req
)) {
1660 return tevent_req_post(req
, ev
);
1662 tevent_req_set_callback(subreq
, smb_vfs_call_pwrite_done
, req
);
1666 static void smb_vfs_call_pwrite_done(struct tevent_req
*subreq
)
1668 struct tevent_req
*req
= tevent_req_callback_data(
1669 subreq
, struct tevent_req
);
1670 struct smb_vfs_call_pwrite_state
*state
= tevent_req_data(
1671 req
, struct smb_vfs_call_pwrite_state
);
1674 state
->retval
= state
->recv_fn(subreq
, &err
);
1675 TALLOC_FREE(subreq
);
1676 if (state
->retval
== -1) {
1677 tevent_req_error(req
, err
);
1680 tevent_req_done(req
);
1683 ssize_t
SMB_VFS_PWRITE_RECV(struct tevent_req
*req
, int *perrno
)
1685 struct smb_vfs_call_pwrite_state
*state
= tevent_req_data(
1686 req
, struct smb_vfs_call_pwrite_state
);
1689 if (tevent_req_is_unix_error(req
, &err
)) {
1693 return state
->retval
;
1696 off_t
smb_vfs_call_lseek(struct vfs_handle_struct
*handle
,
1697 struct files_struct
*fsp
, off_t offset
,
1701 return handle
->fns
->lseek_fn(handle
, fsp
, offset
, whence
);
1704 ssize_t
smb_vfs_call_sendfile(struct vfs_handle_struct
*handle
, int tofd
,
1705 files_struct
*fromfsp
, const DATA_BLOB
*header
,
1706 off_t offset
, size_t count
)
1709 return handle
->fns
->sendfile_fn(handle
, tofd
, fromfsp
, header
, offset
,
1713 ssize_t
smb_vfs_call_recvfile(struct vfs_handle_struct
*handle
, int fromfd
,
1714 files_struct
*tofsp
, off_t offset
,
1718 return handle
->fns
->recvfile_fn(handle
, fromfd
, tofsp
, offset
, count
);
1721 int smb_vfs_call_rename(struct vfs_handle_struct
*handle
,
1722 const struct smb_filename
*smb_fname_src
,
1723 const struct smb_filename
*smb_fname_dst
)
1726 return handle
->fns
->rename_fn(handle
, smb_fname_src
, smb_fname_dst
);
1729 int smb_vfs_call_fsync(struct vfs_handle_struct
*handle
,
1730 struct files_struct
*fsp
)
1733 return handle
->fns
->fsync_fn(handle
, fsp
);
1736 struct smb_vfs_call_fsync_state
{
1737 int (*recv_fn
)(struct tevent_req
*req
, int *err
);
1741 static void smb_vfs_call_fsync_done(struct tevent_req
*subreq
);
1743 struct tevent_req
*smb_vfs_call_fsync_send(struct vfs_handle_struct
*handle
,
1744 TALLOC_CTX
*mem_ctx
,
1745 struct tevent_context
*ev
,
1746 struct files_struct
*fsp
)
1748 struct tevent_req
*req
, *subreq
;
1749 struct smb_vfs_call_fsync_state
*state
;
1751 req
= tevent_req_create(mem_ctx
, &state
,
1752 struct smb_vfs_call_fsync_state
);
1756 VFS_FIND(fsync_send
);
1757 state
->recv_fn
= handle
->fns
->fsync_recv_fn
;
1759 subreq
= handle
->fns
->fsync_send_fn(handle
, state
, ev
, fsp
);
1760 if (tevent_req_nomem(subreq
, req
)) {
1761 return tevent_req_post(req
, ev
);
1763 tevent_req_set_callback(subreq
, smb_vfs_call_fsync_done
, req
);
1767 static void smb_vfs_call_fsync_done(struct tevent_req
*subreq
)
1769 struct tevent_req
*req
= tevent_req_callback_data(
1770 subreq
, struct tevent_req
);
1771 struct smb_vfs_call_fsync_state
*state
= tevent_req_data(
1772 req
, struct smb_vfs_call_fsync_state
);
1775 state
->retval
= state
->recv_fn(subreq
, &err
);
1776 TALLOC_FREE(subreq
);
1777 if (state
->retval
== -1) {
1778 tevent_req_error(req
, err
);
1781 tevent_req_done(req
);
1784 int SMB_VFS_FSYNC_RECV(struct tevent_req
*req
, int *perrno
)
1786 struct smb_vfs_call_fsync_state
*state
= tevent_req_data(
1787 req
, struct smb_vfs_call_fsync_state
);
1790 if (tevent_req_is_unix_error(req
, &err
)) {
1794 return state
->retval
;
1798 int smb_vfs_call_stat(struct vfs_handle_struct
*handle
,
1799 struct smb_filename
*smb_fname
)
1802 return handle
->fns
->stat_fn(handle
, smb_fname
);
1805 int smb_vfs_call_fstat(struct vfs_handle_struct
*handle
,
1806 struct files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
1809 return handle
->fns
->fstat_fn(handle
, fsp
, sbuf
);
1812 int smb_vfs_call_lstat(struct vfs_handle_struct
*handle
,
1813 struct smb_filename
*smb_filename
)
1816 return handle
->fns
->lstat_fn(handle
, smb_filename
);
1819 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct
*handle
,
1820 struct files_struct
*fsp
,
1821 const SMB_STRUCT_STAT
*sbuf
)
1823 VFS_FIND(get_alloc_size
);
1824 return handle
->fns
->get_alloc_size_fn(handle
, fsp
, sbuf
);
1827 int smb_vfs_call_unlink(struct vfs_handle_struct
*handle
,
1828 const struct smb_filename
*smb_fname
)
1831 return handle
->fns
->unlink_fn(handle
, smb_fname
);
1834 int smb_vfs_call_chmod(struct vfs_handle_struct
*handle
, const char *path
,
1838 return handle
->fns
->chmod_fn(handle
, path
, mode
);
1841 int smb_vfs_call_fchmod(struct vfs_handle_struct
*handle
,
1842 struct files_struct
*fsp
, mode_t mode
)
1845 return handle
->fns
->fchmod_fn(handle
, fsp
, mode
);
1848 int smb_vfs_call_chown(struct vfs_handle_struct
*handle
, const char *path
,
1849 uid_t uid
, gid_t gid
)
1852 return handle
->fns
->chown_fn(handle
, path
, uid
, gid
);
1855 int smb_vfs_call_fchown(struct vfs_handle_struct
*handle
,
1856 struct files_struct
*fsp
, uid_t uid
, gid_t gid
)
1859 return handle
->fns
->fchown_fn(handle
, fsp
, uid
, gid
);
1862 int smb_vfs_call_lchown(struct vfs_handle_struct
*handle
, const char *path
,
1863 uid_t uid
, gid_t gid
)
1866 return handle
->fns
->lchown_fn(handle
, path
, uid
, gid
);
1869 NTSTATUS
vfs_chown_fsp(files_struct
*fsp
, uid_t uid
, gid_t gid
)
1872 bool as_root
= false;
1874 char *saved_dir
= NULL
;
1875 char *parent_dir
= NULL
;
1878 if (fsp
->fh
->fd
!= -1) {
1880 ret
= SMB_VFS_FCHOWN(fsp
, uid
, gid
);
1882 return NT_STATUS_OK
;
1884 if (ret
== -1 && errno
!= ENOSYS
) {
1885 return map_nt_error_from_unix(errno
);
1889 as_root
= (geteuid() == 0);
1893 * We are being asked to chown as root. Make
1894 * sure we chdir() into the path to pin it,
1895 * and always act using lchown to ensure we
1896 * don't deref any symbolic links.
1898 const char *final_component
= NULL
;
1899 struct smb_filename local_fname
;
1901 saved_dir
= vfs_GetWd(talloc_tos(),fsp
->conn
);
1903 status
= map_nt_error_from_unix(errno
);
1904 DEBUG(0,("vfs_chown_fsp: failed to get "
1905 "current working directory. Error was %s\n",
1910 if (!parent_dirname(talloc_tos(),
1911 fsp
->fsp_name
->base_name
,
1913 &final_component
)) {
1914 return NT_STATUS_NO_MEMORY
;
1917 /* cd into the parent dir to pin it. */
1918 ret
= vfs_ChDir(fsp
->conn
, parent_dir
);
1920 return map_nt_error_from_unix(errno
);
1923 ZERO_STRUCT(local_fname
);
1924 local_fname
.base_name
= discard_const_p(char, final_component
);
1926 /* Must use lstat here. */
1927 ret
= SMB_VFS_LSTAT(fsp
->conn
, &local_fname
);
1929 status
= map_nt_error_from_unix(errno
);
1933 /* Ensure it matches the fsp stat. */
1934 if (!check_same_stat(&local_fname
.st
, &fsp
->fsp_name
->st
)) {
1935 status
= NT_STATUS_ACCESS_DENIED
;
1938 path
= final_component
;
1940 path
= fsp
->fsp_name
->base_name
;
1943 if (fsp
->posix_open
|| as_root
) {
1944 ret
= SMB_VFS_LCHOWN(fsp
->conn
,
1948 ret
= SMB_VFS_CHOWN(fsp
->conn
,
1954 status
= NT_STATUS_OK
;
1956 status
= map_nt_error_from_unix(errno
);
1962 vfs_ChDir(fsp
->conn
,saved_dir
);
1963 TALLOC_FREE(saved_dir
);
1964 TALLOC_FREE(parent_dir
);
1969 int smb_vfs_call_chdir(struct vfs_handle_struct
*handle
, const char *path
)
1972 return handle
->fns
->chdir_fn(handle
, path
);
1975 char *smb_vfs_call_getwd(struct vfs_handle_struct
*handle
)
1978 return handle
->fns
->getwd_fn(handle
);
1981 int smb_vfs_call_ntimes(struct vfs_handle_struct
*handle
,
1982 const struct smb_filename
*smb_fname
,
1983 struct smb_file_time
*ft
)
1986 return handle
->fns
->ntimes_fn(handle
, smb_fname
, ft
);
1989 int smb_vfs_call_ftruncate(struct vfs_handle_struct
*handle
,
1990 struct files_struct
*fsp
, off_t offset
)
1992 VFS_FIND(ftruncate
);
1993 return handle
->fns
->ftruncate_fn(handle
, fsp
, offset
);
1996 int smb_vfs_call_fallocate(struct vfs_handle_struct
*handle
,
1997 struct files_struct
*fsp
,
1998 enum vfs_fallocate_mode mode
,
2002 VFS_FIND(fallocate
);
2003 return handle
->fns
->fallocate_fn(handle
, fsp
, mode
, offset
, len
);
2006 int smb_vfs_call_kernel_flock(struct vfs_handle_struct
*handle
,
2007 struct files_struct
*fsp
, uint32 share_mode
,
2008 uint32_t access_mask
)
2010 VFS_FIND(kernel_flock
);
2011 return handle
->fns
->kernel_flock_fn(handle
, fsp
, share_mode
,
2015 int smb_vfs_call_linux_setlease(struct vfs_handle_struct
*handle
,
2016 struct files_struct
*fsp
, int leasetype
)
2018 VFS_FIND(linux_setlease
);
2019 return handle
->fns
->linux_setlease_fn(handle
, fsp
, leasetype
);
2022 int smb_vfs_call_symlink(struct vfs_handle_struct
*handle
, const char *oldpath
,
2023 const char *newpath
)
2026 return handle
->fns
->symlink_fn(handle
, oldpath
, newpath
);
2029 int smb_vfs_call_readlink(struct vfs_handle_struct
*handle
,
2030 const char *path
, char *buf
, size_t bufsiz
)
2033 return handle
->fns
->readlink_fn(handle
, path
, buf
, bufsiz
);
2036 int smb_vfs_call_link(struct vfs_handle_struct
*handle
, const char *oldpath
,
2037 const char *newpath
)
2040 return handle
->fns
->link_fn(handle
, oldpath
, newpath
);
2043 int smb_vfs_call_mknod(struct vfs_handle_struct
*handle
, const char *path
,
2044 mode_t mode
, SMB_DEV_T dev
)
2047 return handle
->fns
->mknod_fn(handle
, path
, mode
, dev
);
2050 char *smb_vfs_call_realpath(struct vfs_handle_struct
*handle
, const char *path
)
2053 return handle
->fns
->realpath_fn(handle
, path
);
2056 NTSTATUS
smb_vfs_call_notify_watch(struct vfs_handle_struct
*handle
,
2057 struct sys_notify_context
*ctx
,
2060 uint32_t *subdir_filter
,
2061 void (*callback
)(struct sys_notify_context
*ctx
,
2063 struct notify_event
*ev
),
2064 void *private_data
, void *handle_p
)
2066 VFS_FIND(notify_watch
);
2067 return handle
->fns
->notify_watch_fn(handle
, ctx
, path
,
2068 filter
, subdir_filter
, callback
,
2069 private_data
, handle_p
);
2072 int smb_vfs_call_chflags(struct vfs_handle_struct
*handle
, const char *path
,
2076 return handle
->fns
->chflags_fn(handle
, path
, flags
);
2079 struct file_id
smb_vfs_call_file_id_create(struct vfs_handle_struct
*handle
,
2080 const SMB_STRUCT_STAT
*sbuf
)
2082 VFS_FIND(file_id_create
);
2083 return handle
->fns
->file_id_create_fn(handle
, sbuf
);
2086 NTSTATUS
smb_vfs_call_streaminfo(struct vfs_handle_struct
*handle
,
2087 struct files_struct
*fsp
,
2089 TALLOC_CTX
*mem_ctx
,
2090 unsigned int *num_streams
,
2091 struct stream_struct
**streams
)
2093 VFS_FIND(streaminfo
);
2094 return handle
->fns
->streaminfo_fn(handle
, fsp
, fname
, mem_ctx
,
2095 num_streams
, streams
);
2098 int smb_vfs_call_get_real_filename(struct vfs_handle_struct
*handle
,
2099 const char *path
, const char *name
,
2100 TALLOC_CTX
*mem_ctx
, char **found_name
)
2102 VFS_FIND(get_real_filename
);
2103 return handle
->fns
->get_real_filename_fn(handle
, path
, name
, mem_ctx
,
2107 const char *smb_vfs_call_connectpath(struct vfs_handle_struct
*handle
,
2108 const char *filename
)
2110 VFS_FIND(connectpath
);
2111 return handle
->fns
->connectpath_fn(handle
, filename
);
2114 bool smb_vfs_call_strict_lock(struct vfs_handle_struct
*handle
,
2115 struct files_struct
*fsp
,
2116 struct lock_struct
*plock
)
2118 VFS_FIND(strict_lock
);
2119 return handle
->fns
->strict_lock_fn(handle
, fsp
, plock
);
2122 void smb_vfs_call_strict_unlock(struct vfs_handle_struct
*handle
,
2123 struct files_struct
*fsp
,
2124 struct lock_struct
*plock
)
2126 VFS_FIND(strict_unlock
);
2127 handle
->fns
->strict_unlock_fn(handle
, fsp
, plock
);
2130 NTSTATUS
smb_vfs_call_translate_name(struct vfs_handle_struct
*handle
,
2132 enum vfs_translate_direction direction
,
2133 TALLOC_CTX
*mem_ctx
,
2136 VFS_FIND(translate_name
);
2137 return handle
->fns
->translate_name_fn(handle
, name
, direction
, mem_ctx
,
2141 NTSTATUS
smb_vfs_call_fsctl(struct vfs_handle_struct
*handle
,
2142 struct files_struct
*fsp
,
2146 const uint8_t *in_data
,
2149 uint32_t max_out_len
,
2153 return handle
->fns
->fsctl_fn(handle
, fsp
, ctx
, function
, req_flags
,
2154 in_data
, in_len
, out_data
, max_out_len
,
2158 struct tevent_req
*smb_vfs_call_copy_chunk_send(struct vfs_handle_struct
*handle
,
2159 TALLOC_CTX
*mem_ctx
,
2160 struct tevent_context
*ev
,
2161 struct files_struct
*src_fsp
,
2163 struct files_struct
*dest_fsp
,
2167 VFS_FIND(copy_chunk_send
);
2168 return handle
->fns
->copy_chunk_send_fn(handle
, mem_ctx
, ev
, src_fsp
,
2169 src_off
, dest_fsp
, dest_off
, num
);
2172 NTSTATUS
smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct
*handle
,
2173 struct tevent_req
*req
,
2176 VFS_FIND(copy_chunk_recv
);
2177 return handle
->fns
->copy_chunk_recv_fn(handle
, req
, copied
);
2180 NTSTATUS
smb_vfs_call_fget_nt_acl(struct vfs_handle_struct
*handle
,
2181 struct files_struct
*fsp
,
2182 uint32 security_info
,
2183 TALLOC_CTX
*mem_ctx
,
2184 struct security_descriptor
**ppdesc
)
2186 VFS_FIND(fget_nt_acl
);
2187 return handle
->fns
->fget_nt_acl_fn(handle
, fsp
, security_info
,
2191 NTSTATUS
smb_vfs_call_get_nt_acl(struct vfs_handle_struct
*handle
,
2193 uint32 security_info
,
2194 TALLOC_CTX
*mem_ctx
,
2195 struct security_descriptor
**ppdesc
)
2197 VFS_FIND(get_nt_acl
);
2198 return handle
->fns
->get_nt_acl_fn(handle
, name
, security_info
, mem_ctx
, ppdesc
);
2201 NTSTATUS
smb_vfs_call_fset_nt_acl(struct vfs_handle_struct
*handle
,
2202 struct files_struct
*fsp
,
2203 uint32 security_info_sent
,
2204 const struct security_descriptor
*psd
)
2206 VFS_FIND(fset_nt_acl
);
2207 return handle
->fns
->fset_nt_acl_fn(handle
, fsp
, security_info_sent
,
2211 NTSTATUS
smb_vfs_call_audit_file(struct vfs_handle_struct
*handle
,
2212 struct smb_filename
*file
,
2213 struct security_acl
*sacl
,
2214 uint32_t access_requested
,
2215 uint32_t access_denied
)
2217 VFS_FIND(audit_file
);
2218 return handle
->fns
->audit_file_fn(handle
,
2225 int smb_vfs_call_chmod_acl(struct vfs_handle_struct
*handle
, const char *name
,
2228 VFS_FIND(chmod_acl
);
2229 return handle
->fns
->chmod_acl_fn(handle
, name
, mode
);
2232 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct
*handle
,
2233 struct files_struct
*fsp
, mode_t mode
)
2235 VFS_FIND(fchmod_acl
);
2236 return handle
->fns
->fchmod_acl_fn(handle
, fsp
, mode
);
2239 SMB_ACL_T
smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct
*handle
,
2241 SMB_ACL_TYPE_T type
,
2242 TALLOC_CTX
*mem_ctx
)
2244 VFS_FIND(sys_acl_get_file
);
2245 return handle
->fns
->sys_acl_get_file_fn(handle
, path_p
, type
, mem_ctx
);
2248 SMB_ACL_T
smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct
*handle
,
2249 struct files_struct
*fsp
,
2250 TALLOC_CTX
*mem_ctx
)
2252 VFS_FIND(sys_acl_get_fd
);
2253 return handle
->fns
->sys_acl_get_fd_fn(handle
, fsp
, mem_ctx
);
2256 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct
*handle
,
2258 TALLOC_CTX
*mem_ctx
,
2259 char **blob_description
,
2262 VFS_FIND(sys_acl_blob_get_file
);
2263 return handle
->fns
->sys_acl_blob_get_file_fn(handle
, path_p
, mem_ctx
, blob_description
, blob
);
2266 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct
*handle
,
2267 struct files_struct
*fsp
,
2268 TALLOC_CTX
*mem_ctx
,
2269 char **blob_description
,
2272 VFS_FIND(sys_acl_blob_get_fd
);
2273 return handle
->fns
->sys_acl_blob_get_fd_fn(handle
, fsp
, mem_ctx
, blob_description
, blob
);
2276 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct
*handle
,
2277 const char *name
, SMB_ACL_TYPE_T acltype
,
2280 VFS_FIND(sys_acl_set_file
);
2281 return handle
->fns
->sys_acl_set_file_fn(handle
, name
, acltype
, theacl
);
2284 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct
*handle
,
2285 struct files_struct
*fsp
, SMB_ACL_T theacl
)
2287 VFS_FIND(sys_acl_set_fd
);
2288 return handle
->fns
->sys_acl_set_fd_fn(handle
, fsp
, theacl
);
2291 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct
*handle
,
2294 VFS_FIND(sys_acl_delete_def_file
);
2295 return handle
->fns
->sys_acl_delete_def_file_fn(handle
, path
);
2298 ssize_t
smb_vfs_call_getxattr(struct vfs_handle_struct
*handle
,
2299 const char *path
, const char *name
, void *value
,
2303 return handle
->fns
->getxattr_fn(handle
, path
, name
, value
, size
);
2306 ssize_t
smb_vfs_call_fgetxattr(struct vfs_handle_struct
*handle
,
2307 struct files_struct
*fsp
, const char *name
,
2308 void *value
, size_t size
)
2310 VFS_FIND(fgetxattr
);
2311 return handle
->fns
->fgetxattr_fn(handle
, fsp
, name
, value
, size
);
2314 ssize_t
smb_vfs_call_listxattr(struct vfs_handle_struct
*handle
,
2315 const char *path
, char *list
, size_t size
)
2317 VFS_FIND(listxattr
);
2318 return handle
->fns
->listxattr_fn(handle
, path
, list
, size
);
2321 ssize_t
smb_vfs_call_flistxattr(struct vfs_handle_struct
*handle
,
2322 struct files_struct
*fsp
, char *list
,
2325 VFS_FIND(flistxattr
);
2326 return handle
->fns
->flistxattr_fn(handle
, fsp
, list
, size
);
2329 int smb_vfs_call_removexattr(struct vfs_handle_struct
*handle
,
2330 const char *path
, const char *name
)
2332 VFS_FIND(removexattr
);
2333 return handle
->fns
->removexattr_fn(handle
, path
, name
);
2336 int smb_vfs_call_fremovexattr(struct vfs_handle_struct
*handle
,
2337 struct files_struct
*fsp
, const char *name
)
2339 VFS_FIND(fremovexattr
);
2340 return handle
->fns
->fremovexattr_fn(handle
, fsp
, name
);
2343 int smb_vfs_call_setxattr(struct vfs_handle_struct
*handle
, const char *path
,
2344 const char *name
, const void *value
, size_t size
,
2348 return handle
->fns
->setxattr_fn(handle
, path
, name
, value
, size
, flags
);
2351 int smb_vfs_call_fsetxattr(struct vfs_handle_struct
*handle
,
2352 struct files_struct
*fsp
, const char *name
,
2353 const void *value
, size_t size
, int flags
)
2355 VFS_FIND(fsetxattr
);
2356 return handle
->fns
->fsetxattr_fn(handle
, fsp
, name
, value
, size
, flags
);
2359 bool smb_vfs_call_aio_force(struct vfs_handle_struct
*handle
,
2360 struct files_struct
*fsp
)
2362 VFS_FIND(aio_force
);
2363 return handle
->fns
->aio_force_fn(handle
, fsp
);
2366 bool smb_vfs_call_is_offline(struct vfs_handle_struct
*handle
,
2367 const struct smb_filename
*fname
,
2368 SMB_STRUCT_STAT
*sbuf
)
2370 VFS_FIND(is_offline
);
2371 return handle
->fns
->is_offline_fn(handle
, fname
, sbuf
);
2374 int smb_vfs_call_set_offline(struct vfs_handle_struct
*handle
,
2375 const struct smb_filename
*fname
)
2377 VFS_FIND(set_offline
);
2378 return handle
->fns
->set_offline_fn(handle
, fname
);
2381 NTSTATUS
smb_vfs_call_durable_cookie(struct vfs_handle_struct
*handle
,
2382 struct files_struct
*fsp
,
2383 TALLOC_CTX
*mem_ctx
,
2386 VFS_FIND(durable_cookie
);
2387 return handle
->fns
->durable_cookie_fn(handle
, fsp
, mem_ctx
, cookie
);
2390 NTSTATUS
smb_vfs_call_durable_disconnect(struct vfs_handle_struct
*handle
,
2391 struct files_struct
*fsp
,
2392 const DATA_BLOB old_cookie
,
2393 TALLOC_CTX
*mem_ctx
,
2394 DATA_BLOB
*new_cookie
)
2396 VFS_FIND(durable_disconnect
);
2397 return handle
->fns
->durable_disconnect_fn(handle
, fsp
, old_cookie
,
2398 mem_ctx
, new_cookie
);
2401 NTSTATUS
smb_vfs_call_durable_reconnect(struct vfs_handle_struct
*handle
,
2402 struct smb_request
*smb1req
,
2403 struct smbXsrv_open
*op
,
2404 const DATA_BLOB old_cookie
,
2405 TALLOC_CTX
*mem_ctx
,
2406 struct files_struct
**fsp
,
2407 DATA_BLOB
*new_cookie
)
2409 VFS_FIND(durable_reconnect
);
2410 return handle
->fns
->durable_reconnect_fn(handle
, smb1req
, op
,
2411 old_cookie
, mem_ctx
, fsp
,