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"
35 #define DBGC_CLASS DBGC_VFS
39 struct vfs_init_function_entry
{
41 struct vfs_init_function_entry
*prev
, *next
;
42 const struct vfs_fn_pointers
*fns
;
45 /****************************************************************************
46 maintain the list of available backends
47 ****************************************************************************/
49 static struct vfs_init_function_entry
*vfs_find_backend_entry(const char *name
)
51 struct vfs_init_function_entry
*entry
= backends
;
53 DEBUG(10, ("vfs_find_backend_entry called for %s\n", name
));
56 if (strcmp(entry
->name
, name
)==0) return entry
;
63 NTSTATUS
smb_register_vfs(int version
, const char *name
,
64 const struct vfs_fn_pointers
*fns
)
66 struct vfs_init_function_entry
*entry
= backends
;
68 if ((version
!= SMB_VFS_INTERFACE_VERSION
)) {
69 DEBUG(0, ("Failed to register vfs module.\n"
70 "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
71 "current SMB_VFS_INTERFACE_VERSION is %d.\n"
72 "Please recompile against the current Samba Version!\n",
73 version
, SMB_VFS_INTERFACE_VERSION
));
74 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
77 if (!name
|| !name
[0]) {
78 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
79 return NT_STATUS_INVALID_PARAMETER
;
82 if (vfs_find_backend_entry(name
)) {
83 DEBUG(0,("VFS module %s already loaded!\n", name
));
84 return NT_STATUS_OBJECT_NAME_COLLISION
;
87 entry
= SMB_XMALLOC_P(struct vfs_init_function_entry
);
88 entry
->name
= smb_xstrdup(name
);
91 DLIST_ADD(backends
, entry
);
92 DEBUG(5, ("Successfully added vfs backend '%s'\n", name
));
96 /****************************************************************************
97 initialise default vfs hooks
98 ****************************************************************************/
100 static void vfs_init_default(connection_struct
*conn
)
102 DEBUG(3, ("Initialising default vfs hooks\n"));
103 vfs_init_custom(conn
, DEFAULT_VFS_MODULE_NAME
);
106 /****************************************************************************
107 initialise custom vfs hooks
108 ****************************************************************************/
110 bool vfs_init_custom(connection_struct
*conn
, const char *vfs_object
)
112 char *module_path
= NULL
;
113 char *module_name
= NULL
;
114 char *module_param
= NULL
, *p
;
115 vfs_handle_struct
*handle
;
116 const struct vfs_init_function_entry
*entry
;
118 if (!conn
||!vfs_object
||!vfs_object
[0]) {
119 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
120 "empty vfs_object!\n"));
128 DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object
));
130 module_path
= smb_xstrdup(vfs_object
);
132 p
= strchr_m(module_path
, ':');
137 trim_char(module_param
, ' ', ' ');
140 trim_char(module_path
, ' ', ' ');
142 module_name
= smb_xstrdup(module_path
);
144 if ((module_name
[0] == '/') &&
145 (strcmp(module_path
, DEFAULT_VFS_MODULE_NAME
) != 0)) {
148 * Extract the module name from the path. Just use the base
149 * name of the last path component.
152 SAFE_FREE(module_name
);
153 module_name
= smb_xstrdup(strrchr_m(module_path
, '/')+1);
155 p
= strchr_m(module_name
, '.');
162 /* First, try to load the module with the new module system */
163 entry
= vfs_find_backend_entry(module_name
);
167 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
170 status
= smb_load_module("vfs", module_path
);
171 if (!NT_STATUS_IS_OK(status
)) {
172 DEBUG(0, ("error probing vfs module '%s': %s\n",
173 module_path
, nt_errstr(status
)));
177 entry
= vfs_find_backend_entry(module_name
);
179 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object
));
184 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object
));
186 handle
= talloc_zero(conn
, vfs_handle_struct
);
188 DEBUG(0,("TALLOC_ZERO() failed!\n"));
192 handle
->fns
= entry
->fns
;
194 handle
->param
= talloc_strdup(conn
, module_param
);
196 DLIST_ADD(conn
->vfs_handles
, handle
);
198 SAFE_FREE(module_path
);
199 SAFE_FREE(module_name
);
203 SAFE_FREE(module_path
);
204 SAFE_FREE(module_name
);
208 /*****************************************************************
209 Allow VFS modules to extend files_struct with VFS-specific state.
210 This will be ok for small numbers of extensions, but might need to
211 be refactored if it becomes more widely used.
212 ******************************************************************/
214 #define EXT_DATA_AREA(e) ((uint8 *)(e) + sizeof(struct vfs_fsp_data))
216 void *vfs_add_fsp_extension_notype(vfs_handle_struct
*handle
,
217 files_struct
*fsp
, size_t ext_size
,
218 void (*destroy_fn
)(void *p_data
))
220 struct vfs_fsp_data
*ext
;
223 /* Prevent VFS modules adding multiple extensions. */
224 if ((ext_data
= vfs_fetch_fsp_extension(handle
, fsp
))) {
228 ext
= (struct vfs_fsp_data
*)TALLOC_ZERO(
229 handle
->conn
, sizeof(struct vfs_fsp_data
) + ext_size
);
235 ext
->next
= fsp
->vfs_extension
;
236 ext
->destroy
= destroy_fn
;
237 fsp
->vfs_extension
= ext
;
238 return EXT_DATA_AREA(ext
);
241 void vfs_remove_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
243 struct vfs_fsp_data
*curr
;
244 struct vfs_fsp_data
*prev
;
246 for (curr
= fsp
->vfs_extension
, prev
= NULL
;
248 prev
= curr
, curr
= curr
->next
) {
249 if (curr
->owner
== handle
) {
251 prev
->next
= curr
->next
;
253 fsp
->vfs_extension
= curr
->next
;
256 curr
->destroy(EXT_DATA_AREA(curr
));
264 void *vfs_memctx_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
266 struct vfs_fsp_data
*head
;
268 for (head
= fsp
->vfs_extension
; head
; head
= head
->next
) {
269 if (head
->owner
== handle
) {
277 void *vfs_fetch_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
279 struct vfs_fsp_data
*head
;
281 head
= (struct vfs_fsp_data
*)vfs_memctx_fsp_extension(handle
, fsp
);
283 return EXT_DATA_AREA(head
);
291 /*****************************************************************
293 ******************************************************************/
295 bool smbd_vfs_init(connection_struct
*conn
)
297 const char **vfs_objects
;
301 /* Normal share - initialise with disk access functions */
302 vfs_init_default(conn
);
303 vfs_objects
= lp_vfs_objects(SNUM(conn
));
305 /* Override VFS functions if 'vfs object' was not specified*/
306 if (!vfs_objects
|| !vfs_objects
[0])
309 for (i
=0; vfs_objects
[i
] ;) {
313 for (j
=i
-1; j
>= 0; j
--) {
314 if (!vfs_init_custom(conn
, vfs_objects
[j
])) {
315 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects
[j
]));
322 /*******************************************************************
323 Check if a file exists in the vfs.
324 ********************************************************************/
326 NTSTATUS
vfs_file_exist(connection_struct
*conn
, struct smb_filename
*smb_fname
)
328 /* Only return OK if stat was successful and S_ISREG */
329 if ((SMB_VFS_STAT(conn
, smb_fname
) != -1) &&
330 S_ISREG(smb_fname
->st
.st_ex_mode
)) {
334 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
337 /****************************************************************************
338 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
339 ****************************************************************************/
341 ssize_t
vfs_read_data(files_struct
*fsp
, char *buf
, size_t byte_count
)
345 while (total
< byte_count
)
347 ssize_t ret
= SMB_VFS_READ(fsp
, buf
+ total
,
350 if (ret
== 0) return total
;
359 return (ssize_t
)total
;
362 ssize_t
vfs_pread_data(files_struct
*fsp
, char *buf
,
363 size_t byte_count
, off_t offset
)
367 while (total
< byte_count
)
369 ssize_t ret
= SMB_VFS_PREAD(fsp
, buf
+ total
,
370 byte_count
- total
, offset
+ total
);
372 if (ret
== 0) return total
;
381 return (ssize_t
)total
;
384 /****************************************************************************
385 Write data to a fd on the vfs.
386 ****************************************************************************/
388 ssize_t
vfs_write_data(struct smb_request
*req
,
396 if (req
&& req
->unread_bytes
) {
397 SMB_ASSERT(req
->unread_bytes
== N
);
398 /* VFS_RECVFILE must drain the socket
399 * before returning. */
400 req
->unread_bytes
= 0;
401 return SMB_VFS_RECVFILE(req
->sconn
->sock
,
408 ret
= SMB_VFS_WRITE(fsp
, buffer
+ total
, N
- total
);
417 return (ssize_t
)total
;
420 ssize_t
vfs_pwrite_data(struct smb_request
*req
,
429 if (req
&& req
->unread_bytes
) {
430 SMB_ASSERT(req
->unread_bytes
== N
);
431 /* VFS_RECVFILE must drain the socket
432 * before returning. */
433 req
->unread_bytes
= 0;
434 return SMB_VFS_RECVFILE(req
->sconn
->sock
,
441 ret
= SMB_VFS_PWRITE(fsp
, buffer
+ total
, N
- total
,
451 return (ssize_t
)total
;
453 /****************************************************************************
454 An allocate file space call using the vfs interface.
455 Allocates space for a file from a filedescriptor.
456 Returns 0 on success, -1 on failure.
457 ****************************************************************************/
459 int vfs_allocate_file_space(files_struct
*fsp
, uint64_t len
)
462 connection_struct
*conn
= fsp
->conn
;
463 uint64_t space_avail
;
464 uint64_t bsize
,dfree
,dsize
;
468 * Actually try and commit the space on disk....
471 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
472 fsp_str_dbg(fsp
), (double)len
));
474 if (((off_t
)len
) < 0) {
475 DEBUG(0,("vfs_allocate_file_space: %s negative len "
476 "requested.\n", fsp_str_dbg(fsp
)));
481 status
= vfs_stat_fsp(fsp
);
482 if (!NT_STATUS_IS_OK(status
)) {
486 if (len
== (uint64_t)fsp
->fsp_name
->st
.st_ex_size
)
489 if (len
< (uint64_t)fsp
->fsp_name
->st
.st_ex_size
) {
490 /* Shrink - use ftruncate. */
492 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
493 "size %.0f\n", fsp_str_dbg(fsp
),
494 (double)fsp
->fsp_name
->st
.st_ex_size
));
496 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_ALLOC_SHRINK
);
498 flush_write_cache(fsp
, SIZECHANGE_FLUSH
);
499 if ((ret
= SMB_VFS_FTRUNCATE(fsp
, (off_t
)len
)) != -1) {
500 set_filelen_write_cache(fsp
, len
);
503 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_ALLOC_SHRINK
);
508 if (!lp_strict_allocate(SNUM(fsp
->conn
)))
511 /* Grow - we need to test if we have enough space. */
513 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_ALLOC_GROW
);
515 /* See if we have a syscall that will allocate beyond end-of-file
516 without changing EOF. */
517 ret
= SMB_VFS_FALLOCATE(fsp
, VFS_FALLOCATE_KEEP_SIZE
, 0, len
);
519 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_ALLOC_GROW
);
522 /* We changed the allocation size on disk, but not
523 EOF - exactly as required. We're done ! */
527 len
-= fsp
->fsp_name
->st
.st_ex_size
;
528 len
/= 1024; /* Len is now number of 1k blocks needed. */
529 space_avail
= get_dfree_info(conn
, fsp
->fsp_name
->base_name
, false,
530 &bsize
, &dfree
, &dsize
);
531 if (space_avail
== (uint64_t)-1) {
535 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
536 "needed blocks = %.0f, space avail = %.0f\n",
537 fsp_str_dbg(fsp
), (double)fsp
->fsp_name
->st
.st_ex_size
, (double)len
,
538 (double)space_avail
));
540 if (len
> space_avail
) {
548 /****************************************************************************
549 A vfs set_filelen call.
550 set the length of a file from a filedescriptor.
551 Returns 0 on success, -1 on failure.
552 ****************************************************************************/
554 int vfs_set_filelen(files_struct
*fsp
, off_t len
)
558 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_SET_FILE_LEN
);
560 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
561 fsp_str_dbg(fsp
), (double)len
));
562 flush_write_cache(fsp
, SIZECHANGE_FLUSH
);
563 if ((ret
= SMB_VFS_FTRUNCATE(fsp
, len
)) != -1) {
564 set_filelen_write_cache(fsp
, len
);
565 notify_fname(fsp
->conn
, NOTIFY_ACTION_MODIFIED
,
566 FILE_NOTIFY_CHANGE_SIZE
567 | FILE_NOTIFY_CHANGE_ATTRIBUTES
,
568 fsp
->fsp_name
->base_name
);
571 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_SET_FILE_LEN
);
576 /****************************************************************************
577 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
578 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
579 as this is also called from the default SMB_VFS_FTRUNCATE code.
580 Always extends the file size.
581 Returns 0 on success, errno on failure.
582 ****************************************************************************/
584 #define SPARSE_BUF_WRITE_SIZE (32*1024)
586 int vfs_slow_fallocate(files_struct
*fsp
, off_t offset
, off_t len
)
592 sparse_buf
= SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE
);
599 while (total
< len
) {
600 size_t curr_write_size
= MIN(SPARSE_BUF_WRITE_SIZE
, (len
- total
));
602 pwrite_ret
= SMB_VFS_PWRITE(fsp
, sparse_buf
, curr_write_size
, offset
+ total
);
603 if (pwrite_ret
== -1) {
604 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
605 "%s failed with error %s\n",
606 fsp_str_dbg(fsp
), strerror(errno
)));
615 /****************************************************************************
616 A vfs fill sparse call.
617 Writes zeros from the end of file to len, if len is greater than EOF.
618 Used only by strict_sync.
619 Returns 0 on success, -1 on failure.
620 ****************************************************************************/
622 int vfs_fill_sparse(files_struct
*fsp
, off_t len
)
629 status
= vfs_stat_fsp(fsp
);
630 if (!NT_STATUS_IS_OK(status
)) {
634 if (len
<= fsp
->fsp_name
->st
.st_ex_size
) {
639 if (S_ISFIFO(fsp
->fsp_name
->st
.st_ex_mode
)) {
644 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
645 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp
),
646 (double)fsp
->fsp_name
->st
.st_ex_size
, (double)len
,
647 (double)(len
- fsp
->fsp_name
->st
.st_ex_size
)));
649 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_FILL_SPARSE
);
651 flush_write_cache(fsp
, SIZECHANGE_FLUSH
);
653 offset
= fsp
->fsp_name
->st
.st_ex_size
;
654 num_to_write
= len
- fsp
->fsp_name
->st
.st_ex_size
;
656 /* Only do this on non-stream file handles. */
657 if (fsp
->base_fsp
== NULL
) {
658 /* for allocation try fallocate first. This can fail on some
659 * platforms e.g. when the filesystem doesn't support it and no
660 * emulation is being done by the libc (like on AIX with JFS1). In that
661 * case we do our own emulation. fallocate implementations can
662 * return ENOTSUP or EINVAL in cases like that. */
663 ret
= SMB_VFS_FALLOCATE(fsp
, VFS_FALLOCATE_EXTEND_SIZE
,
664 offset
, num_to_write
);
673 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
674 "error %d. Falling back to slow manual allocation\n", ret
));
677 ret
= vfs_slow_fallocate(fsp
, offset
, num_to_write
);
686 set_filelen_write_cache(fsp
, len
);
689 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_FILL_SPARSE
);
693 /****************************************************************************
694 Transfer some data (n bytes) between two file_struct's.
695 ****************************************************************************/
697 static ssize_t
vfs_read_fn(void *file
, void *buf
, size_t len
)
699 struct files_struct
*fsp
= (struct files_struct
*)file
;
701 return SMB_VFS_READ(fsp
, buf
, len
);
704 static ssize_t
vfs_write_fn(void *file
, const void *buf
, size_t len
)
706 struct files_struct
*fsp
= (struct files_struct
*)file
;
708 return SMB_VFS_WRITE(fsp
, buf
, len
);
711 off_t
vfs_transfer_file(files_struct
*in
, files_struct
*out
, off_t n
)
713 return transfer_file_internal((void *)in
, (void *)out
, n
,
714 vfs_read_fn
, vfs_write_fn
);
717 /*******************************************************************
718 A vfs_readdir wrapper which just returns the file name.
719 ********************************************************************/
721 const char *vfs_readdirname(connection_struct
*conn
, void *p
,
722 SMB_STRUCT_STAT
*sbuf
, char **talloced
)
724 struct dirent
*ptr
= NULL
;
732 ptr
= SMB_VFS_READDIR(conn
, (DIR *)p
, sbuf
);
744 #ifdef HAVE_BROKEN_READDIR_NAME
745 /* using /usr/ucb/cc is BAD */
749 status
= SMB_VFS_TRANSLATE_NAME(conn
, dname
, vfs_translate_to_windows
,
750 talloc_tos(), &translated
);
751 if (NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
755 *talloced
= translated
;
756 if (!NT_STATUS_IS_OK(status
)) {
762 /*******************************************************************
763 A wrapper for vfs_chdir().
764 ********************************************************************/
766 int vfs_ChDir(connection_struct
*conn
, const char *path
)
771 LastDir
= SMB_STRDUP("");
774 if (strcsequal(path
,"."))
777 if (*path
== '/' && strcsequal(LastDir
,path
))
780 DEBUG(4,("vfs_ChDir to %s\n",path
));
782 res
= SMB_VFS_CHDIR(conn
,path
);
785 LastDir
= SMB_STRDUP(path
);
790 /*******************************************************************
791 Return the absolute current directory path - given a UNIX pathname.
792 Note that this path is returned in DOS format, not UNIX
793 format. Note this can be called with conn == NULL.
794 ********************************************************************/
796 char *vfs_GetWd(TALLOC_CTX
*ctx
, connection_struct
*conn
)
798 char *current_dir
= NULL
;
800 DATA_BLOB cache_value
;
802 struct smb_filename
*smb_fname_dot
= NULL
;
803 struct smb_filename
*smb_fname_full
= NULL
;
806 if (!lp_getwd_cache()) {
810 status
= create_synthetic_smb_fname(ctx
, ".", NULL
, NULL
,
812 if (!NT_STATUS_IS_OK(status
)) {
813 errno
= map_errno_from_nt_status(status
);
817 if (SMB_VFS_STAT(conn
, smb_fname_dot
) == -1) {
819 * Known to fail for root: the directory may be NFS-mounted
820 * and exported with root_squash (so has no root access).
822 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
823 "(NFS problem ?)\n", strerror(errno
) ));
827 key
= vfs_file_id_from_sbuf(conn
, &smb_fname_dot
->st
);
829 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE
,
830 data_blob_const(&key
, sizeof(key
)),
835 SMB_ASSERT((cache_value
.length
> 0)
836 && (cache_value
.data
[cache_value
.length
-1] == '\0'));
838 status
= create_synthetic_smb_fname(ctx
, (char *)cache_value
.data
,
839 NULL
, NULL
, &smb_fname_full
);
840 if (!NT_STATUS_IS_OK(status
)) {
841 errno
= map_errno_from_nt_status(status
);
845 if ((SMB_VFS_STAT(conn
, smb_fname_full
) == 0) &&
846 (smb_fname_dot
->st
.st_ex_dev
== smb_fname_full
->st
.st_ex_dev
) &&
847 (smb_fname_dot
->st
.st_ex_ino
== smb_fname_full
->st
.st_ex_ino
) &&
848 (S_ISDIR(smb_fname_dot
->st
.st_ex_mode
))) {
852 result
= talloc_strdup(ctx
, smb_fname_full
->base_name
);
853 if (result
== NULL
) {
862 * We don't have the information to hand so rely on traditional
863 * methods. The very slow getcwd, which spawns a process on some
864 * systems, or the not quite so bad getwd.
867 current_dir
= SMB_VFS_GETWD(conn
);
868 if (current_dir
== NULL
) {
869 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
874 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot
->st
)) {
875 key
= vfs_file_id_from_sbuf(conn
, &smb_fname_dot
->st
);
877 memcache_add(smbd_memcache(), GETWD_CACHE
,
878 data_blob_const(&key
, sizeof(key
)),
879 data_blob_const(current_dir
,
880 strlen(current_dir
)+1));
883 result
= talloc_strdup(ctx
, current_dir
);
884 if (result
== NULL
) {
889 TALLOC_FREE(smb_fname_dot
);
890 TALLOC_FREE(smb_fname_full
);
891 SAFE_FREE(current_dir
);
895 /*******************************************************************
896 Reduce a file name, removing .. elements and checking that
897 it is below dir in the heirachy. This uses realpath.
898 This function must run as root, and will return names
899 and valid stat structs that can be checked on open.
900 ********************************************************************/
902 NTSTATUS
check_reduced_name_with_privilege(connection_struct
*conn
,
904 struct smb_request
*smbreq
)
907 TALLOC_CTX
*ctx
= talloc_tos();
908 const char *conn_rootdir
;
910 char *dir_name
= NULL
;
911 const char *last_component
= NULL
;
912 char *resolved_name
= NULL
;
913 char *saved_dir
= NULL
;
914 struct smb_filename
*smb_fname_cwd
= NULL
;
915 struct privilege_paths
*priv_paths
= NULL
;
918 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
923 priv_paths
= talloc_zero(smbreq
, struct privilege_paths
);
925 status
= NT_STATUS_NO_MEMORY
;
929 if (!parent_dirname(ctx
, fname
, &dir_name
, &last_component
)) {
930 status
= NT_STATUS_NO_MEMORY
;
934 priv_paths
->parent_name
.base_name
= talloc_strdup(priv_paths
, dir_name
);
935 priv_paths
->file_name
.base_name
= talloc_strdup(priv_paths
, last_component
);
937 if (priv_paths
->parent_name
.base_name
== NULL
||
938 priv_paths
->file_name
.base_name
== NULL
) {
939 status
= NT_STATUS_NO_MEMORY
;
943 if (SMB_VFS_STAT(conn
, &priv_paths
->parent_name
) != 0) {
944 status
= map_nt_error_from_unix(errno
);
947 /* Remember where we were. */
948 saved_dir
= vfs_GetWd(ctx
, conn
);
950 status
= map_nt_error_from_unix(errno
);
954 /* Go to the parent directory to lock in memory. */
955 if (vfs_ChDir(conn
, priv_paths
->parent_name
.base_name
) == -1) {
956 status
= map_nt_error_from_unix(errno
);
960 /* Get the absolute path of the parent directory. */
961 resolved_name
= SMB_VFS_REALPATH(conn
,".");
962 if (!resolved_name
) {
963 status
= map_nt_error_from_unix(errno
);
967 if (*resolved_name
!= '/') {
968 DEBUG(0,("check_reduced_name_with_privilege: realpath "
969 "doesn't return absolute paths !\n"));
970 status
= NT_STATUS_OBJECT_NAME_INVALID
;
974 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
975 priv_paths
->parent_name
.base_name
,
978 /* Now check the stat value is the same. */
979 status
= create_synthetic_smb_fname(talloc_tos(), ".",
982 if (!NT_STATUS_IS_OK(status
)) {
986 if (SMB_VFS_LSTAT(conn
, smb_fname_cwd
) != 0) {
987 status
= map_nt_error_from_unix(errno
);
991 /* Ensure we're pointing at the same place. */
992 if (!check_same_stat(&smb_fname_cwd
->st
, &priv_paths
->parent_name
.st
)) {
993 DEBUG(0,("check_reduced_name_with_privilege: "
994 "device/inode/uid/gid on directory %s changed. "
995 "Denying access !\n",
996 priv_paths
->parent_name
.base_name
));
997 status
= NT_STATUS_ACCESS_DENIED
;
1001 /* Ensure we're below the connect path. */
1003 conn_rootdir
= SMB_VFS_CONNECTPATH(conn
, fname
);
1004 if (conn_rootdir
== NULL
) {
1005 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1007 status
= NT_STATUS_ACCESS_DENIED
;
1011 rootdir_len
= strlen(conn_rootdir
);
1012 if (strncmp(conn_rootdir
, resolved_name
, rootdir_len
) != 0) {
1013 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1014 "attempt: %s is a symlink outside the "
1017 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir
));
1018 DEBUGADD(2, ("resolved_name=%s\n", resolved_name
));
1019 status
= NT_STATUS_ACCESS_DENIED
;
1023 /* Now ensure that the last component either doesn't
1024 exist, or is *NOT* a symlink. */
1026 ret
= SMB_VFS_LSTAT(conn
, &priv_paths
->file_name
);
1028 /* Errno must be ENOENT for this be ok. */
1029 if (errno
!= ENOENT
) {
1030 status
= map_nt_error_from_unix(errno
);
1031 DEBUG(2, ("check_reduced_name_with_privilege: "
1032 "LSTAT on %s failed with %s\n",
1033 priv_paths
->file_name
.base_name
,
1034 nt_errstr(status
)));
1039 if (VALID_STAT(priv_paths
->file_name
.st
) &&
1040 S_ISLNK(priv_paths
->file_name
.st
.st_ex_mode
)) {
1041 DEBUG(2, ("check_reduced_name_with_privilege: "
1042 "Last component %s is a symlink. Denying"
1044 priv_paths
->file_name
.base_name
));
1045 status
= NT_STATUS_ACCESS_DENIED
;
1049 smbreq
->priv_paths
= priv_paths
;
1050 status
= NT_STATUS_OK
;
1055 vfs_ChDir(conn
, saved_dir
);
1057 SAFE_FREE(resolved_name
);
1058 if (!NT_STATUS_IS_OK(status
)) {
1059 TALLOC_FREE(priv_paths
);
1064 /*******************************************************************
1065 Reduce a file name, removing .. elements and checking that
1066 it is below dir in the heirachy. This uses realpath.
1067 ********************************************************************/
1069 NTSTATUS
check_reduced_name(connection_struct
*conn
, const char *fname
)
1071 char *resolved_name
= NULL
;
1072 bool allow_symlinks
= true;
1073 bool allow_widelinks
= false;
1075 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname
, conn
->connectpath
));
1077 resolved_name
= SMB_VFS_REALPATH(conn
,fname
);
1079 if (!resolved_name
) {
1082 DEBUG(3,("check_reduced_name: Component not a "
1083 "directory in getting realpath for "
1085 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1088 TALLOC_CTX
*ctx
= talloc_tos();
1089 char *dir_name
= NULL
;
1090 const char *last_component
= NULL
;
1091 char *new_name
= NULL
;
1094 /* Last component didn't exist.
1095 Remove it and try and canonicalise
1096 the directory name. */
1097 if (!parent_dirname(ctx
, fname
,
1100 return NT_STATUS_NO_MEMORY
;
1103 resolved_name
= SMB_VFS_REALPATH(conn
,dir_name
);
1104 if (!resolved_name
) {
1105 NTSTATUS status
= map_nt_error_from_unix(errno
);
1107 if (errno
== ENOENT
|| errno
== ENOTDIR
) {
1108 status
= NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1111 DEBUG(3,("check_reduce_name: "
1112 "couldn't get realpath for "
1115 nt_errstr(status
)));
1118 ret
= asprintf(&new_name
, "%s/%s",
1119 resolved_name
, last_component
);
1120 SAFE_FREE(resolved_name
);
1122 return NT_STATUS_NO_MEMORY
;
1124 resolved_name
= new_name
;
1128 DEBUG(3,("check_reduced_name: couldn't get "
1129 "realpath for %s\n", fname
));
1130 return map_nt_error_from_unix(errno
);
1134 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname
,
1137 if (*resolved_name
!= '/') {
1138 DEBUG(0,("check_reduced_name: realpath doesn't return "
1139 "absolute paths !\n"));
1140 SAFE_FREE(resolved_name
);
1141 return NT_STATUS_OBJECT_NAME_INVALID
;
1144 allow_widelinks
= lp_widelinks(SNUM(conn
));
1145 allow_symlinks
= lp_symlinks(SNUM(conn
));
1147 /* Common widelinks and symlinks checks. */
1148 if (!allow_widelinks
|| !allow_symlinks
) {
1149 const char *conn_rootdir
;
1152 conn_rootdir
= SMB_VFS_CONNECTPATH(conn
, fname
);
1153 if (conn_rootdir
== NULL
) {
1154 DEBUG(2, ("check_reduced_name: Could not get "
1156 SAFE_FREE(resolved_name
);
1157 return NT_STATUS_ACCESS_DENIED
;
1160 rootdir_len
= strlen(conn_rootdir
);
1161 if (strncmp(conn_rootdir
, resolved_name
,
1162 rootdir_len
) != 0) {
1163 DEBUG(2, ("check_reduced_name: Bad access "
1164 "attempt: %s is a symlink outside the "
1165 "share path\n", fname
));
1166 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir
));
1167 DEBUGADD(2, ("resolved_name=%s\n", resolved_name
));
1168 SAFE_FREE(resolved_name
);
1169 return NT_STATUS_ACCESS_DENIED
;
1172 /* Extra checks if all symlinks are disallowed. */
1173 if (!allow_symlinks
) {
1174 /* fname can't have changed in resolved_path. */
1175 const char *p
= &resolved_name
[rootdir_len
];
1177 /* *p can be '\0' if fname was "." */
1178 if (*p
== '\0' && ISDOT(fname
)) {
1183 DEBUG(2, ("check_reduced_name: logic error (%c) "
1184 "in resolved_name: %s\n",
1187 SAFE_FREE(resolved_name
);
1188 return NT_STATUS_ACCESS_DENIED
;
1192 if (strcmp(fname
, p
)!=0) {
1193 DEBUG(2, ("check_reduced_name: Bad access "
1194 "attempt: %s is a symlink\n",
1196 SAFE_FREE(resolved_name
);
1197 return NT_STATUS_ACCESS_DENIED
;
1204 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname
,
1206 SAFE_FREE(resolved_name
);
1207 return NT_STATUS_OK
;
1211 * XXX: This is temporary and there should be no callers of this once
1212 * smb_filename is plumbed through all path based operations.
1214 int vfs_stat_smb_fname(struct connection_struct
*conn
, const char *fname
,
1215 SMB_STRUCT_STAT
*psbuf
)
1217 struct smb_filename
*smb_fname
= NULL
;
1221 status
= create_synthetic_smb_fname_split(talloc_tos(), fname
, NULL
,
1223 if (!NT_STATUS_IS_OK(status
)) {
1224 errno
= map_errno_from_nt_status(status
);
1228 if (lp_posix_pathnames()) {
1229 ret
= SMB_VFS_LSTAT(conn
, smb_fname
);
1231 ret
= SMB_VFS_STAT(conn
, smb_fname
);
1235 *psbuf
= smb_fname
->st
;
1238 TALLOC_FREE(smb_fname
);
1243 * XXX: This is temporary and there should be no callers of this once
1244 * smb_filename is plumbed through all path based operations.
1246 int vfs_lstat_smb_fname(struct connection_struct
*conn
, const char *fname
,
1247 SMB_STRUCT_STAT
*psbuf
)
1249 struct smb_filename
*smb_fname
= NULL
;
1253 status
= create_synthetic_smb_fname_split(talloc_tos(), fname
, NULL
,
1255 if (!NT_STATUS_IS_OK(status
)) {
1256 errno
= map_errno_from_nt_status(status
);
1260 ret
= SMB_VFS_LSTAT(conn
, smb_fname
);
1262 *psbuf
= smb_fname
->st
;
1265 TALLOC_FREE(smb_fname
);
1270 * Ensure LSTAT is called for POSIX paths.
1273 NTSTATUS
vfs_stat_fsp(files_struct
*fsp
)
1277 if(fsp
->fh
->fd
== -1) {
1278 if (fsp
->posix_open
) {
1279 ret
= SMB_VFS_LSTAT(fsp
->conn
, fsp
->fsp_name
);
1281 ret
= SMB_VFS_STAT(fsp
->conn
, fsp
->fsp_name
);
1284 return map_nt_error_from_unix(errno
);
1287 if(SMB_VFS_FSTAT(fsp
, &fsp
->fsp_name
->st
) != 0) {
1288 return map_nt_error_from_unix(errno
);
1291 return NT_STATUS_OK
;
1295 * Initialize num_streams and streams, then call VFS op streaminfo
1297 NTSTATUS
vfs_streaminfo(connection_struct
*conn
,
1298 struct files_struct
*fsp
,
1300 TALLOC_CTX
*mem_ctx
,
1301 unsigned int *num_streams
,
1302 struct stream_struct
**streams
)
1306 return SMB_VFS_STREAMINFO(conn
, fsp
, fname
, mem_ctx
, num_streams
, streams
);
1310 generate a file_id from a stat structure
1312 struct file_id
vfs_file_id_from_sbuf(connection_struct
*conn
, const SMB_STRUCT_STAT
*sbuf
)
1314 return SMB_VFS_FILE_ID_CREATE(conn
, sbuf
);
1317 int smb_vfs_call_connect(struct vfs_handle_struct
*handle
,
1318 const char *service
, const char *user
)
1321 return handle
->fns
->connect_fn(handle
, service
, user
);
1324 void smb_vfs_call_disconnect(struct vfs_handle_struct
*handle
)
1326 VFS_FIND(disconnect
);
1327 handle
->fns
->disconnect_fn(handle
);
1330 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct
*handle
,
1331 const char *path
, bool small_query
,
1332 uint64_t *bsize
, uint64_t *dfree
,
1335 VFS_FIND(disk_free
);
1336 return handle
->fns
->disk_free_fn(handle
, path
, small_query
, bsize
,
1340 int smb_vfs_call_get_quota(struct vfs_handle_struct
*handle
,
1341 enum SMB_QUOTA_TYPE qtype
, unid_t id
,
1344 VFS_FIND(get_quota
);
1345 return handle
->fns
->get_quota_fn(handle
, qtype
, id
, qt
);
1348 int smb_vfs_call_set_quota(struct vfs_handle_struct
*handle
,
1349 enum SMB_QUOTA_TYPE qtype
, unid_t id
,
1352 VFS_FIND(set_quota
);
1353 return handle
->fns
->set_quota_fn(handle
, qtype
, id
, qt
);
1356 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct
*handle
,
1357 struct files_struct
*fsp
,
1358 struct shadow_copy_data
*shadow_copy_data
,
1361 VFS_FIND(get_shadow_copy_data
);
1362 return handle
->fns
->get_shadow_copy_data_fn(handle
, fsp
,
1366 int smb_vfs_call_statvfs(struct vfs_handle_struct
*handle
, const char *path
,
1367 struct vfs_statvfs_struct
*statbuf
)
1370 return handle
->fns
->statvfs_fn(handle
, path
, statbuf
);
1373 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct
*handle
,
1374 enum timestamp_set_resolution
*p_ts_res
)
1376 VFS_FIND(fs_capabilities
);
1377 return handle
->fns
->fs_capabilities_fn(handle
, p_ts_res
);
1380 NTSTATUS
smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct
*handle
,
1381 struct dfs_GetDFSReferral
*r
)
1383 VFS_FIND(get_dfs_referrals
);
1384 return handle
->fns
->get_dfs_referrals_fn(handle
, r
);
1387 DIR *smb_vfs_call_opendir(struct vfs_handle_struct
*handle
,
1388 const char *fname
, const char *mask
,
1392 return handle
->fns
->opendir_fn(handle
, fname
, mask
, attributes
);
1395 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct
*handle
,
1396 struct files_struct
*fsp
,
1400 VFS_FIND(fdopendir
);
1401 return handle
->fns
->fdopendir_fn(handle
, fsp
, mask
, attributes
);
1404 struct dirent
*smb_vfs_call_readdir(struct vfs_handle_struct
*handle
,
1406 SMB_STRUCT_STAT
*sbuf
)
1409 return handle
->fns
->readdir_fn(handle
, dirp
, sbuf
);
1412 void smb_vfs_call_seekdir(struct vfs_handle_struct
*handle
,
1413 DIR *dirp
, long offset
)
1416 handle
->fns
->seekdir_fn(handle
, dirp
, offset
);
1419 long smb_vfs_call_telldir(struct vfs_handle_struct
*handle
,
1423 return handle
->fns
->telldir_fn(handle
, dirp
);
1426 void smb_vfs_call_rewind_dir(struct vfs_handle_struct
*handle
,
1429 VFS_FIND(rewind_dir
);
1430 handle
->fns
->rewind_dir_fn(handle
, dirp
);
1433 int smb_vfs_call_mkdir(struct vfs_handle_struct
*handle
, const char *path
,
1437 return handle
->fns
->mkdir_fn(handle
, path
, mode
);
1440 int smb_vfs_call_rmdir(struct vfs_handle_struct
*handle
, const char *path
)
1443 return handle
->fns
->rmdir_fn(handle
, path
);
1446 int smb_vfs_call_closedir(struct vfs_handle_struct
*handle
,
1450 return handle
->fns
->closedir_fn(handle
, dir
);
1453 void smb_vfs_call_init_search_op(struct vfs_handle_struct
*handle
,
1456 VFS_FIND(init_search_op
);
1457 handle
->fns
->init_search_op_fn(handle
, dirp
);
1460 int smb_vfs_call_open(struct vfs_handle_struct
*handle
,
1461 struct smb_filename
*smb_fname
, struct files_struct
*fsp
,
1462 int flags
, mode_t mode
)
1465 return handle
->fns
->open_fn(handle
, smb_fname
, fsp
, flags
, mode
);
1468 NTSTATUS
smb_vfs_call_create_file(struct vfs_handle_struct
*handle
,
1469 struct smb_request
*req
,
1470 uint16_t root_dir_fid
,
1471 struct smb_filename
*smb_fname
,
1472 uint32_t access_mask
,
1473 uint32_t share_access
,
1474 uint32_t create_disposition
,
1475 uint32_t create_options
,
1476 uint32_t file_attributes
,
1477 uint32_t oplock_request
,
1478 uint64_t allocation_size
,
1479 uint32_t private_flags
,
1480 struct security_descriptor
*sd
,
1481 struct ea_list
*ea_list
,
1482 files_struct
**result
,
1485 VFS_FIND(create_file
);
1486 return handle
->fns
->create_file_fn(
1487 handle
, req
, root_dir_fid
, smb_fname
, access_mask
,
1488 share_access
, create_disposition
, create_options
,
1489 file_attributes
, oplock_request
, allocation_size
,
1490 private_flags
, sd
, ea_list
,
1494 int smb_vfs_call_close(struct vfs_handle_struct
*handle
,
1495 struct files_struct
*fsp
)
1498 return handle
->fns
->close_fn(handle
, fsp
);
1501 ssize_t
smb_vfs_call_read(struct vfs_handle_struct
*handle
,
1502 struct files_struct
*fsp
, void *data
, size_t n
)
1505 return handle
->fns
->read_fn(handle
, fsp
, data
, n
);
1508 ssize_t
smb_vfs_call_pread(struct vfs_handle_struct
*handle
,
1509 struct files_struct
*fsp
, void *data
, size_t n
,
1513 return handle
->fns
->pread_fn(handle
, fsp
, data
, n
, offset
);
1516 ssize_t
smb_vfs_call_write(struct vfs_handle_struct
*handle
,
1517 struct files_struct
*fsp
, const void *data
,
1521 return handle
->fns
->write_fn(handle
, fsp
, data
, n
);
1524 ssize_t
smb_vfs_call_pwrite(struct vfs_handle_struct
*handle
,
1525 struct files_struct
*fsp
, const void *data
,
1526 size_t n
, off_t offset
)
1529 return handle
->fns
->pwrite_fn(handle
, fsp
, data
, n
, offset
);
1532 off_t
smb_vfs_call_lseek(struct vfs_handle_struct
*handle
,
1533 struct files_struct
*fsp
, off_t offset
,
1537 return handle
->fns
->lseek_fn(handle
, fsp
, offset
, whence
);
1540 ssize_t
smb_vfs_call_sendfile(struct vfs_handle_struct
*handle
, int tofd
,
1541 files_struct
*fromfsp
, const DATA_BLOB
*header
,
1542 off_t offset
, size_t count
)
1545 return handle
->fns
->sendfile_fn(handle
, tofd
, fromfsp
, header
, offset
,
1549 ssize_t
smb_vfs_call_recvfile(struct vfs_handle_struct
*handle
, int fromfd
,
1550 files_struct
*tofsp
, off_t offset
,
1554 return handle
->fns
->recvfile_fn(handle
, fromfd
, tofsp
, offset
, count
);
1557 int smb_vfs_call_rename(struct vfs_handle_struct
*handle
,
1558 const struct smb_filename
*smb_fname_src
,
1559 const struct smb_filename
*smb_fname_dst
)
1562 return handle
->fns
->rename_fn(handle
, smb_fname_src
, smb_fname_dst
);
1565 int smb_vfs_call_fsync(struct vfs_handle_struct
*handle
,
1566 struct files_struct
*fsp
)
1569 return handle
->fns
->fsync_fn(handle
, fsp
);
1572 int smb_vfs_call_stat(struct vfs_handle_struct
*handle
,
1573 struct smb_filename
*smb_fname
)
1576 return handle
->fns
->stat_fn(handle
, smb_fname
);
1579 int smb_vfs_call_fstat(struct vfs_handle_struct
*handle
,
1580 struct files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
1583 return handle
->fns
->fstat_fn(handle
, fsp
, sbuf
);
1586 int smb_vfs_call_lstat(struct vfs_handle_struct
*handle
,
1587 struct smb_filename
*smb_filename
)
1590 return handle
->fns
->lstat_fn(handle
, smb_filename
);
1593 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct
*handle
,
1594 struct files_struct
*fsp
,
1595 const SMB_STRUCT_STAT
*sbuf
)
1597 VFS_FIND(get_alloc_size
);
1598 return handle
->fns
->get_alloc_size_fn(handle
, fsp
, sbuf
);
1601 int smb_vfs_call_unlink(struct vfs_handle_struct
*handle
,
1602 const struct smb_filename
*smb_fname
)
1605 return handle
->fns
->unlink_fn(handle
, smb_fname
);
1608 int smb_vfs_call_chmod(struct vfs_handle_struct
*handle
, const char *path
,
1612 return handle
->fns
->chmod_fn(handle
, path
, mode
);
1615 int smb_vfs_call_fchmod(struct vfs_handle_struct
*handle
,
1616 struct files_struct
*fsp
, mode_t mode
)
1619 return handle
->fns
->fchmod_fn(handle
, fsp
, mode
);
1622 int smb_vfs_call_chown(struct vfs_handle_struct
*handle
, const char *path
,
1623 uid_t uid
, gid_t gid
)
1626 return handle
->fns
->chown_fn(handle
, path
, uid
, gid
);
1629 int smb_vfs_call_fchown(struct vfs_handle_struct
*handle
,
1630 struct files_struct
*fsp
, uid_t uid
, gid_t gid
)
1633 return handle
->fns
->fchown_fn(handle
, fsp
, uid
, gid
);
1636 int smb_vfs_call_lchown(struct vfs_handle_struct
*handle
, const char *path
,
1637 uid_t uid
, gid_t gid
)
1640 return handle
->fns
->lchown_fn(handle
, path
, uid
, gid
);
1643 NTSTATUS
vfs_chown_fsp(files_struct
*fsp
, uid_t uid
, gid_t gid
)
1646 bool as_root
= false;
1648 char *saved_dir
= NULL
;
1649 char *parent_dir
= NULL
;
1652 if (fsp
->fh
->fd
!= -1) {
1654 ret
= SMB_VFS_FCHOWN(fsp
, uid
, gid
);
1656 return NT_STATUS_OK
;
1658 if (ret
== -1 && errno
!= ENOSYS
) {
1659 return map_nt_error_from_unix(errno
);
1663 as_root
= (geteuid() == 0);
1667 * We are being asked to chown as root. Make
1668 * sure we chdir() into the path to pin it,
1669 * and always act using lchown to ensure we
1670 * don't deref any symbolic links.
1672 const char *final_component
= NULL
;
1673 struct smb_filename local_fname
;
1675 saved_dir
= vfs_GetWd(talloc_tos(),fsp
->conn
);
1677 status
= map_nt_error_from_unix(errno
);
1678 DEBUG(0,("vfs_chown_fsp: failed to get "
1679 "current working directory. Error was %s\n",
1684 if (!parent_dirname(talloc_tos(),
1685 fsp
->fsp_name
->base_name
,
1687 &final_component
)) {
1688 return NT_STATUS_NO_MEMORY
;
1691 /* cd into the parent dir to pin it. */
1692 ret
= vfs_ChDir(fsp
->conn
, parent_dir
);
1694 return map_nt_error_from_unix(errno
);
1697 ZERO_STRUCT(local_fname
);
1698 local_fname
.base_name
= discard_const_p(char, final_component
);
1700 /* Must use lstat here. */
1701 ret
= SMB_VFS_LSTAT(fsp
->conn
, &local_fname
);
1703 status
= map_nt_error_from_unix(errno
);
1707 /* Ensure it matches the fsp stat. */
1708 if (!check_same_stat(&local_fname
.st
, &fsp
->fsp_name
->st
)) {
1709 status
= NT_STATUS_ACCESS_DENIED
;
1712 path
= final_component
;
1714 path
= fsp
->fsp_name
->base_name
;
1717 if (fsp
->posix_open
|| as_root
) {
1718 ret
= SMB_VFS_LCHOWN(fsp
->conn
,
1722 ret
= SMB_VFS_CHOWN(fsp
->conn
,
1728 status
= NT_STATUS_OK
;
1730 status
= map_nt_error_from_unix(errno
);
1736 vfs_ChDir(fsp
->conn
,saved_dir
);
1737 TALLOC_FREE(saved_dir
);
1738 TALLOC_FREE(parent_dir
);
1743 int smb_vfs_call_chdir(struct vfs_handle_struct
*handle
, const char *path
)
1746 return handle
->fns
->chdir_fn(handle
, path
);
1749 char *smb_vfs_call_getwd(struct vfs_handle_struct
*handle
)
1752 return handle
->fns
->getwd_fn(handle
);
1755 int smb_vfs_call_ntimes(struct vfs_handle_struct
*handle
,
1756 const struct smb_filename
*smb_fname
,
1757 struct smb_file_time
*ft
)
1760 return handle
->fns
->ntimes_fn(handle
, smb_fname
, ft
);
1763 int smb_vfs_call_ftruncate(struct vfs_handle_struct
*handle
,
1764 struct files_struct
*fsp
, off_t offset
)
1766 VFS_FIND(ftruncate
);
1767 return handle
->fns
->ftruncate_fn(handle
, fsp
, offset
);
1770 int smb_vfs_call_fallocate(struct vfs_handle_struct
*handle
,
1771 struct files_struct
*fsp
,
1772 enum vfs_fallocate_mode mode
,
1776 VFS_FIND(fallocate
);
1777 return handle
->fns
->fallocate_fn(handle
, fsp
, mode
, offset
, len
);
1780 int smb_vfs_call_kernel_flock(struct vfs_handle_struct
*handle
,
1781 struct files_struct
*fsp
, uint32 share_mode
,
1782 uint32_t access_mask
)
1784 VFS_FIND(kernel_flock
);
1785 return handle
->fns
->kernel_flock_fn(handle
, fsp
, share_mode
,
1789 int smb_vfs_call_linux_setlease(struct vfs_handle_struct
*handle
,
1790 struct files_struct
*fsp
, int leasetype
)
1792 VFS_FIND(linux_setlease
);
1793 return handle
->fns
->linux_setlease_fn(handle
, fsp
, leasetype
);
1796 int smb_vfs_call_symlink(struct vfs_handle_struct
*handle
, const char *oldpath
,
1797 const char *newpath
)
1800 return handle
->fns
->symlink_fn(handle
, oldpath
, newpath
);
1803 int smb_vfs_call_readlink(struct vfs_handle_struct
*handle
,
1804 const char *path
, char *buf
, size_t bufsiz
)
1807 return handle
->fns
->readlink_fn(handle
, path
, buf
, bufsiz
);
1810 int smb_vfs_call_link(struct vfs_handle_struct
*handle
, const char *oldpath
,
1811 const char *newpath
)
1814 return handle
->fns
->link_fn(handle
, oldpath
, newpath
);
1817 int smb_vfs_call_mknod(struct vfs_handle_struct
*handle
, const char *path
,
1818 mode_t mode
, SMB_DEV_T dev
)
1821 return handle
->fns
->mknod_fn(handle
, path
, mode
, dev
);
1824 char *smb_vfs_call_realpath(struct vfs_handle_struct
*handle
, const char *path
)
1827 return handle
->fns
->realpath_fn(handle
, path
);
1830 NTSTATUS
smb_vfs_call_notify_watch(struct vfs_handle_struct
*handle
,
1831 struct sys_notify_context
*ctx
,
1834 uint32_t *subdir_filter
,
1835 void (*callback
)(struct sys_notify_context
*ctx
,
1837 struct notify_event
*ev
),
1838 void *private_data
, void *handle_p
)
1840 VFS_FIND(notify_watch
);
1841 return handle
->fns
->notify_watch_fn(handle
, ctx
, path
,
1842 filter
, subdir_filter
, callback
,
1843 private_data
, handle_p
);
1846 int smb_vfs_call_chflags(struct vfs_handle_struct
*handle
, const char *path
,
1850 return handle
->fns
->chflags_fn(handle
, path
, flags
);
1853 struct file_id
smb_vfs_call_file_id_create(struct vfs_handle_struct
*handle
,
1854 const SMB_STRUCT_STAT
*sbuf
)
1856 VFS_FIND(file_id_create
);
1857 return handle
->fns
->file_id_create_fn(handle
, sbuf
);
1860 NTSTATUS
smb_vfs_call_streaminfo(struct vfs_handle_struct
*handle
,
1861 struct files_struct
*fsp
,
1863 TALLOC_CTX
*mem_ctx
,
1864 unsigned int *num_streams
,
1865 struct stream_struct
**streams
)
1867 VFS_FIND(streaminfo
);
1868 return handle
->fns
->streaminfo_fn(handle
, fsp
, fname
, mem_ctx
,
1869 num_streams
, streams
);
1872 int smb_vfs_call_get_real_filename(struct vfs_handle_struct
*handle
,
1873 const char *path
, const char *name
,
1874 TALLOC_CTX
*mem_ctx
, char **found_name
)
1876 VFS_FIND(get_real_filename
);
1877 return handle
->fns
->get_real_filename_fn(handle
, path
, name
, mem_ctx
,
1881 const char *smb_vfs_call_connectpath(struct vfs_handle_struct
*handle
,
1882 const char *filename
)
1884 VFS_FIND(connectpath
);
1885 return handle
->fns
->connectpath_fn(handle
, filename
);
1888 bool smb_vfs_call_strict_lock(struct vfs_handle_struct
*handle
,
1889 struct files_struct
*fsp
,
1890 struct lock_struct
*plock
)
1892 VFS_FIND(strict_lock
);
1893 return handle
->fns
->strict_lock_fn(handle
, fsp
, plock
);
1896 void smb_vfs_call_strict_unlock(struct vfs_handle_struct
*handle
,
1897 struct files_struct
*fsp
,
1898 struct lock_struct
*plock
)
1900 VFS_FIND(strict_unlock
);
1901 handle
->fns
->strict_unlock_fn(handle
, fsp
, plock
);
1904 NTSTATUS
smb_vfs_call_translate_name(struct vfs_handle_struct
*handle
,
1906 enum vfs_translate_direction direction
,
1907 TALLOC_CTX
*mem_ctx
,
1910 VFS_FIND(translate_name
);
1911 return handle
->fns
->translate_name_fn(handle
, name
, direction
, mem_ctx
,
1915 NTSTATUS
smb_vfs_call_fsctl(struct vfs_handle_struct
*handle
,
1916 struct files_struct
*fsp
,
1920 const uint8_t *in_data
,
1923 uint32_t max_out_len
,
1927 return handle
->fns
->fsctl_fn(handle
, fsp
, ctx
, function
, req_flags
,
1928 in_data
, in_len
, out_data
, max_out_len
,
1932 NTSTATUS
smb_vfs_call_fget_nt_acl(struct vfs_handle_struct
*handle
,
1933 struct files_struct
*fsp
,
1934 uint32 security_info
,
1935 struct security_descriptor
**ppdesc
)
1937 VFS_FIND(fget_nt_acl
);
1938 return handle
->fns
->fget_nt_acl_fn(handle
, fsp
, security_info
,
1942 NTSTATUS
smb_vfs_call_get_nt_acl(struct vfs_handle_struct
*handle
,
1944 uint32 security_info
,
1945 struct security_descriptor
**ppdesc
)
1947 VFS_FIND(get_nt_acl
);
1948 return handle
->fns
->get_nt_acl_fn(handle
, name
, security_info
, ppdesc
);
1951 NTSTATUS
smb_vfs_call_fset_nt_acl(struct vfs_handle_struct
*handle
,
1952 struct files_struct
*fsp
,
1953 uint32 security_info_sent
,
1954 const struct security_descriptor
*psd
)
1956 VFS_FIND(fset_nt_acl
);
1957 return handle
->fns
->fset_nt_acl_fn(handle
, fsp
, security_info_sent
,
1961 int smb_vfs_call_chmod_acl(struct vfs_handle_struct
*handle
, const char *name
,
1964 VFS_FIND(chmod_acl
);
1965 return handle
->fns
->chmod_acl_fn(handle
, name
, mode
);
1968 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct
*handle
,
1969 struct files_struct
*fsp
, mode_t mode
)
1971 VFS_FIND(fchmod_acl
);
1972 return handle
->fns
->fchmod_acl_fn(handle
, fsp
, mode
);
1975 int smb_vfs_call_sys_acl_get_entry(struct vfs_handle_struct
*handle
,
1976 SMB_ACL_T theacl
, int entry_id
,
1977 SMB_ACL_ENTRY_T
*entry_p
)
1979 VFS_FIND(sys_acl_get_entry
);
1980 return handle
->fns
->sys_acl_get_entry_fn(handle
, theacl
, entry_id
,
1984 int smb_vfs_call_sys_acl_get_tag_type(struct vfs_handle_struct
*handle
,
1985 SMB_ACL_ENTRY_T entry_d
,
1986 SMB_ACL_TAG_T
*tag_type_p
)
1988 VFS_FIND(sys_acl_get_tag_type
);
1989 return handle
->fns
->sys_acl_get_tag_type_fn(handle
, entry_d
,
1993 int smb_vfs_call_sys_acl_get_permset(struct vfs_handle_struct
*handle
,
1994 SMB_ACL_ENTRY_T entry_d
,
1995 SMB_ACL_PERMSET_T
*permset_p
)
1997 VFS_FIND(sys_acl_get_permset
);
1998 return handle
->fns
->sys_acl_get_permset_fn(handle
, entry_d
, permset_p
);
2001 void * smb_vfs_call_sys_acl_get_qualifier(struct vfs_handle_struct
*handle
,
2002 SMB_ACL_ENTRY_T entry_d
)
2004 VFS_FIND(sys_acl_get_qualifier
);
2005 return handle
->fns
->sys_acl_get_qualifier_fn(handle
, entry_d
);
2008 SMB_ACL_T
smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct
*handle
,
2010 SMB_ACL_TYPE_T type
)
2012 VFS_FIND(sys_acl_get_file
);
2013 return handle
->fns
->sys_acl_get_file_fn(handle
, path_p
, type
);
2016 SMB_ACL_T
smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct
*handle
,
2017 struct files_struct
*fsp
)
2019 VFS_FIND(sys_acl_get_fd
);
2020 return handle
->fns
->sys_acl_get_fd_fn(handle
, fsp
);
2023 int smb_vfs_call_sys_acl_clear_perms(struct vfs_handle_struct
*handle
,
2024 SMB_ACL_PERMSET_T permset
)
2026 VFS_FIND(sys_acl_clear_perms
);
2027 return handle
->fns
->sys_acl_clear_perms_fn(handle
, permset
);
2030 int smb_vfs_call_sys_acl_add_perm(struct vfs_handle_struct
*handle
,
2031 SMB_ACL_PERMSET_T permset
,
2032 SMB_ACL_PERM_T perm
)
2034 VFS_FIND(sys_acl_add_perm
);
2035 return handle
->fns
->sys_acl_add_perm_fn(handle
, permset
, perm
);
2038 char * smb_vfs_call_sys_acl_to_text(struct vfs_handle_struct
*handle
,
2039 SMB_ACL_T theacl
, ssize_t
*plen
)
2041 VFS_FIND(sys_acl_to_text
);
2042 return handle
->fns
->sys_acl_to_text_fn(handle
, theacl
, plen
);
2045 SMB_ACL_T
smb_vfs_call_sys_acl_init(struct vfs_handle_struct
*handle
,
2048 VFS_FIND(sys_acl_init
);
2049 return handle
->fns
->sys_acl_init_fn(handle
, count
);
2052 int smb_vfs_call_sys_acl_create_entry(struct vfs_handle_struct
*handle
,
2053 SMB_ACL_T
*pacl
, SMB_ACL_ENTRY_T
*pentry
)
2055 VFS_FIND(sys_acl_create_entry
);
2056 return handle
->fns
->sys_acl_create_entry_fn(handle
, pacl
, pentry
);
2059 int smb_vfs_call_sys_acl_set_tag_type(struct vfs_handle_struct
*handle
,
2060 SMB_ACL_ENTRY_T entry
,
2061 SMB_ACL_TAG_T tagtype
)
2063 VFS_FIND(sys_acl_set_tag_type
);
2064 return handle
->fns
->sys_acl_set_tag_type_fn(handle
, entry
, tagtype
);
2067 int smb_vfs_call_sys_acl_set_qualifier(struct vfs_handle_struct
*handle
,
2068 SMB_ACL_ENTRY_T entry
, void *qual
)
2070 VFS_FIND(sys_acl_set_qualifier
);
2071 return handle
->fns
->sys_acl_set_qualifier_fn(handle
, entry
, qual
);
2074 int smb_vfs_call_sys_acl_set_permset(struct vfs_handle_struct
*handle
,
2075 SMB_ACL_ENTRY_T entry
,
2076 SMB_ACL_PERMSET_T permset
)
2078 VFS_FIND(sys_acl_set_permset
);
2079 return handle
->fns
->sys_acl_set_permset_fn(handle
, entry
, permset
);
2082 int smb_vfs_call_sys_acl_valid(struct vfs_handle_struct
*handle
,
2085 VFS_FIND(sys_acl_valid
);
2086 return handle
->fns
->sys_acl_valid_fn(handle
, theacl
);
2089 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct
*handle
,
2090 const char *name
, SMB_ACL_TYPE_T acltype
,
2093 VFS_FIND(sys_acl_set_file
);
2094 return handle
->fns
->sys_acl_set_file_fn(handle
, name
, acltype
, theacl
);
2097 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct
*handle
,
2098 struct files_struct
*fsp
, SMB_ACL_T theacl
)
2100 VFS_FIND(sys_acl_set_fd
);
2101 return handle
->fns
->sys_acl_set_fd_fn(handle
, fsp
, theacl
);
2104 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct
*handle
,
2107 VFS_FIND(sys_acl_delete_def_file
);
2108 return handle
->fns
->sys_acl_delete_def_file_fn(handle
, path
);
2111 int smb_vfs_call_sys_acl_get_perm(struct vfs_handle_struct
*handle
,
2112 SMB_ACL_PERMSET_T permset
,
2113 SMB_ACL_PERM_T perm
)
2115 VFS_FIND(sys_acl_get_perm
);
2116 return handle
->fns
->sys_acl_get_perm_fn(handle
, permset
, perm
);
2119 int smb_vfs_call_sys_acl_free_text(struct vfs_handle_struct
*handle
,
2122 VFS_FIND(sys_acl_free_text
);
2123 return handle
->fns
->sys_acl_free_text_fn(handle
, text
);
2126 int smb_vfs_call_sys_acl_free_acl(struct vfs_handle_struct
*handle
,
2127 SMB_ACL_T posix_acl
)
2129 VFS_FIND(sys_acl_free_acl
);
2130 return handle
->fns
->sys_acl_free_acl_fn(handle
, posix_acl
);
2133 int smb_vfs_call_sys_acl_free_qualifier(struct vfs_handle_struct
*handle
,
2134 void *qualifier
, SMB_ACL_TAG_T tagtype
)
2136 VFS_FIND(sys_acl_free_qualifier
);
2137 return handle
->fns
->sys_acl_free_qualifier_fn(handle
, qualifier
,
2141 ssize_t
smb_vfs_call_getxattr(struct vfs_handle_struct
*handle
,
2142 const char *path
, const char *name
, void *value
,
2146 return handle
->fns
->getxattr_fn(handle
, path
, name
, value
, size
);
2149 ssize_t
smb_vfs_call_fgetxattr(struct vfs_handle_struct
*handle
,
2150 struct files_struct
*fsp
, const char *name
,
2151 void *value
, size_t size
)
2153 VFS_FIND(fgetxattr
);
2154 return handle
->fns
->fgetxattr_fn(handle
, fsp
, name
, value
, size
);
2157 ssize_t
smb_vfs_call_listxattr(struct vfs_handle_struct
*handle
,
2158 const char *path
, char *list
, size_t size
)
2160 VFS_FIND(listxattr
);
2161 return handle
->fns
->listxattr_fn(handle
, path
, list
, size
);
2164 ssize_t
smb_vfs_call_flistxattr(struct vfs_handle_struct
*handle
,
2165 struct files_struct
*fsp
, char *list
,
2168 VFS_FIND(flistxattr
);
2169 return handle
->fns
->flistxattr_fn(handle
, fsp
, list
, size
);
2172 int smb_vfs_call_removexattr(struct vfs_handle_struct
*handle
,
2173 const char *path
, const char *name
)
2175 VFS_FIND(removexattr
);
2176 return handle
->fns
->removexattr_fn(handle
, path
, name
);
2179 int smb_vfs_call_fremovexattr(struct vfs_handle_struct
*handle
,
2180 struct files_struct
*fsp
, const char *name
)
2182 VFS_FIND(fremovexattr
);
2183 return handle
->fns
->fremovexattr_fn(handle
, fsp
, name
);
2186 int smb_vfs_call_setxattr(struct vfs_handle_struct
*handle
, const char *path
,
2187 const char *name
, const void *value
, size_t size
,
2191 return handle
->fns
->setxattr_fn(handle
, path
, name
, value
, size
, flags
);
2194 int smb_vfs_call_fsetxattr(struct vfs_handle_struct
*handle
,
2195 struct files_struct
*fsp
, const char *name
,
2196 const void *value
, size_t size
, int flags
)
2198 VFS_FIND(fsetxattr
);
2199 return handle
->fns
->fsetxattr_fn(handle
, fsp
, name
, value
, size
, flags
);
2202 int smb_vfs_call_aio_read(struct vfs_handle_struct
*handle
,
2203 struct files_struct
*fsp
, SMB_STRUCT_AIOCB
*aiocb
)
2206 return handle
->fns
->aio_read_fn(handle
, fsp
, aiocb
);
2209 int smb_vfs_call_aio_write(struct vfs_handle_struct
*handle
,
2210 struct files_struct
*fsp
, SMB_STRUCT_AIOCB
*aiocb
)
2212 VFS_FIND(aio_write
);
2213 return handle
->fns
->aio_write_fn(handle
, fsp
, aiocb
);
2216 ssize_t
smb_vfs_call_aio_return(struct vfs_handle_struct
*handle
,
2217 struct files_struct
*fsp
,
2218 SMB_STRUCT_AIOCB
*aiocb
)
2220 VFS_FIND(aio_return
);
2221 return handle
->fns
->aio_return_fn(handle
, fsp
, aiocb
);
2224 int smb_vfs_call_aio_cancel(struct vfs_handle_struct
*handle
,
2225 struct files_struct
*fsp
, SMB_STRUCT_AIOCB
*aiocb
)
2227 VFS_FIND(aio_cancel
);
2228 return handle
->fns
->aio_cancel_fn(handle
, fsp
, aiocb
);
2231 int smb_vfs_call_aio_error(struct vfs_handle_struct
*handle
,
2232 struct files_struct
*fsp
,
2233 SMB_STRUCT_AIOCB
*aiocb
)
2235 VFS_FIND(aio_error
);
2236 return handle
->fns
->aio_error_fn(handle
, fsp
, aiocb
);
2239 int smb_vfs_call_aio_fsync(struct vfs_handle_struct
*handle
,
2240 struct files_struct
*fsp
, int op
,
2241 SMB_STRUCT_AIOCB
*aiocb
)
2243 VFS_FIND(aio_fsync
);
2244 return handle
->fns
->aio_fsync_fn(handle
, fsp
, op
, aiocb
);
2247 int smb_vfs_call_aio_suspend(struct vfs_handle_struct
*handle
,
2248 struct files_struct
*fsp
,
2249 const SMB_STRUCT_AIOCB
* const aiocb
[], int n
,
2250 const struct timespec
*timeout
)
2252 VFS_FIND(aio_suspend
);
2253 return handle
->fns
->aio_suspend_fn(handle
, fsp
, aiocb
, n
, timeout
);
2256 bool smb_vfs_call_aio_force(struct vfs_handle_struct
*handle
,
2257 struct files_struct
*fsp
)
2259 VFS_FIND(aio_force
);
2260 return handle
->fns
->aio_force_fn(handle
, fsp
);
2263 bool smb_vfs_call_is_offline(struct vfs_handle_struct
*handle
,
2264 const struct smb_filename
*fname
,
2265 SMB_STRUCT_STAT
*sbuf
)
2267 VFS_FIND(is_offline
);
2268 return handle
->fns
->is_offline_fn(handle
, fname
, sbuf
);
2271 int smb_vfs_call_set_offline(struct vfs_handle_struct
*handle
,
2272 const struct smb_filename
*fname
)
2274 VFS_FIND(set_offline
);
2275 return handle
->fns
->set_offline_fn(handle
, fname
);