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
40 struct vfs_fsp_data
*next
;
41 struct vfs_handle_struct
*owner
;
42 void (*destroy
)(void *p_data
);
44 /* NOTE: This structure contains four pointers so that we can guarantee
45 * that the end of the structure is always both 4-byte and 8-byte aligned.
49 struct vfs_init_function_entry
{
51 struct vfs_init_function_entry
*prev
, *next
;
52 const struct vfs_fn_pointers
*fns
;
55 /****************************************************************************
56 maintain the list of available backends
57 ****************************************************************************/
59 static struct vfs_init_function_entry
*vfs_find_backend_entry(const char *name
)
61 struct vfs_init_function_entry
*entry
= backends
;
63 DEBUG(10, ("vfs_find_backend_entry called for %s\n", name
));
66 if (strcmp(entry
->name
, name
)==0) return entry
;
73 NTSTATUS
smb_register_vfs(int version
, const char *name
,
74 const struct vfs_fn_pointers
*fns
)
76 struct vfs_init_function_entry
*entry
= backends
;
78 if ((version
!= SMB_VFS_INTERFACE_VERSION
)) {
79 DEBUG(0, ("Failed to register vfs module.\n"
80 "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
81 "current SMB_VFS_INTERFACE_VERSION is %d.\n"
82 "Please recompile against the current Samba Version!\n",
83 version
, SMB_VFS_INTERFACE_VERSION
));
84 return NT_STATUS_OBJECT_TYPE_MISMATCH
;
87 if (!name
|| !name
[0]) {
88 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
89 return NT_STATUS_INVALID_PARAMETER
;
92 if (vfs_find_backend_entry(name
)) {
93 DEBUG(0,("VFS module %s already loaded!\n", name
));
94 return NT_STATUS_OBJECT_NAME_COLLISION
;
97 entry
= SMB_XMALLOC_P(struct vfs_init_function_entry
);
98 entry
->name
= smb_xstrdup(name
);
101 DLIST_ADD(backends
, entry
);
102 DEBUG(5, ("Successfully added vfs backend '%s'\n", name
));
106 /****************************************************************************
107 initialise default vfs hooks
108 ****************************************************************************/
110 static void vfs_init_default(connection_struct
*conn
)
112 DEBUG(3, ("Initialising default vfs hooks\n"));
113 vfs_init_custom(conn
, DEFAULT_VFS_MODULE_NAME
);
116 /****************************************************************************
117 initialise custom vfs hooks
118 ****************************************************************************/
120 bool vfs_init_custom(connection_struct
*conn
, const char *vfs_object
)
122 char *module_path
= NULL
;
123 char *module_name
= NULL
;
124 char *module_param
= NULL
, *p
;
125 vfs_handle_struct
*handle
;
126 const struct vfs_init_function_entry
*entry
;
128 if (!conn
||!vfs_object
||!vfs_object
[0]) {
129 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
130 "empty vfs_object!\n"));
138 DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object
));
140 module_path
= smb_xstrdup(vfs_object
);
142 p
= strchr_m(module_path
, ':');
147 trim_char(module_param
, ' ', ' ');
150 trim_char(module_path
, ' ', ' ');
152 module_name
= smb_xstrdup(module_path
);
154 if ((module_name
[0] == '/') &&
155 (strcmp(module_path
, DEFAULT_VFS_MODULE_NAME
) != 0)) {
158 * Extract the module name from the path. Just use the base
159 * name of the last path component.
162 SAFE_FREE(module_name
);
163 module_name
= smb_xstrdup(strrchr_m(module_path
, '/')+1);
165 p
= strchr_m(module_name
, '.');
172 /* First, try to load the module with the new module system */
173 entry
= vfs_find_backend_entry(module_name
);
177 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
180 status
= smb_load_module("vfs", module_path
);
181 if (!NT_STATUS_IS_OK(status
)) {
182 DEBUG(0, ("error probing vfs module '%s': %s\n",
183 module_path
, nt_errstr(status
)));
187 entry
= vfs_find_backend_entry(module_name
);
189 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object
));
194 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object
));
196 handle
= talloc_zero(conn
, vfs_handle_struct
);
198 DEBUG(0,("TALLOC_ZERO() failed!\n"));
202 handle
->fns
= entry
->fns
;
204 handle
->param
= talloc_strdup(conn
, module_param
);
206 DLIST_ADD(conn
->vfs_handles
, handle
);
208 SAFE_FREE(module_path
);
209 SAFE_FREE(module_name
);
213 SAFE_FREE(module_path
);
214 SAFE_FREE(module_name
);
218 /*****************************************************************
219 Allow VFS modules to extend files_struct with VFS-specific state.
220 This will be ok for small numbers of extensions, but might need to
221 be refactored if it becomes more widely used.
222 ******************************************************************/
224 #define EXT_DATA_AREA(e) ((uint8 *)(e) + sizeof(struct vfs_fsp_data))
226 void *vfs_add_fsp_extension_notype(vfs_handle_struct
*handle
,
227 files_struct
*fsp
, size_t ext_size
,
228 void (*destroy_fn
)(void *p_data
))
230 struct vfs_fsp_data
*ext
;
233 /* Prevent VFS modules adding multiple extensions. */
234 if ((ext_data
= vfs_fetch_fsp_extension(handle
, fsp
))) {
238 ext
= (struct vfs_fsp_data
*)TALLOC_ZERO(
239 handle
->conn
, sizeof(struct vfs_fsp_data
) + ext_size
);
245 ext
->next
= fsp
->vfs_extension
;
246 ext
->destroy
= destroy_fn
;
247 fsp
->vfs_extension
= ext
;
248 return EXT_DATA_AREA(ext
);
251 void vfs_remove_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
253 struct vfs_fsp_data
*curr
;
254 struct vfs_fsp_data
*prev
;
256 for (curr
= fsp
->vfs_extension
, prev
= NULL
;
258 prev
= curr
, curr
= curr
->next
) {
259 if (curr
->owner
== handle
) {
261 prev
->next
= curr
->next
;
263 fsp
->vfs_extension
= curr
->next
;
266 curr
->destroy(EXT_DATA_AREA(curr
));
274 void vfs_remove_all_fsp_extensions(files_struct
*fsp
)
276 struct vfs_fsp_data
*curr
;
277 struct vfs_fsp_data
*next
;
279 for (curr
= fsp
->vfs_extension
; curr
; curr
= next
) {
282 fsp
->vfs_extension
= next
;
285 curr
->destroy(EXT_DATA_AREA(curr
));
291 void *vfs_memctx_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
293 struct vfs_fsp_data
*head
;
295 for (head
= fsp
->vfs_extension
; head
; head
= head
->next
) {
296 if (head
->owner
== handle
) {
304 void *vfs_fetch_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
306 struct vfs_fsp_data
*head
;
308 head
= (struct vfs_fsp_data
*)vfs_memctx_fsp_extension(handle
, fsp
);
310 return EXT_DATA_AREA(head
);
318 /*****************************************************************
320 ******************************************************************/
322 bool smbd_vfs_init(connection_struct
*conn
)
324 const char **vfs_objects
;
328 /* Normal share - initialise with disk access functions */
329 vfs_init_default(conn
);
330 vfs_objects
= lp_vfs_objects(SNUM(conn
));
332 /* Override VFS functions if 'vfs object' was not specified*/
333 if (!vfs_objects
|| !vfs_objects
[0])
336 for (i
=0; vfs_objects
[i
] ;) {
340 for (j
=i
-1; j
>= 0; j
--) {
341 if (!vfs_init_custom(conn
, vfs_objects
[j
])) {
342 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects
[j
]));
349 /*******************************************************************
350 Check if a file exists in the vfs.
351 ********************************************************************/
353 NTSTATUS
vfs_file_exist(connection_struct
*conn
, struct smb_filename
*smb_fname
)
355 /* Only return OK if stat was successful and S_ISREG */
356 if ((SMB_VFS_STAT(conn
, smb_fname
) != -1) &&
357 S_ISREG(smb_fname
->st
.st_ex_mode
)) {
361 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
364 /****************************************************************************
365 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
366 ****************************************************************************/
368 ssize_t
vfs_read_data(files_struct
*fsp
, char *buf
, size_t byte_count
)
372 while (total
< byte_count
)
374 ssize_t ret
= SMB_VFS_READ(fsp
, buf
+ total
,
377 if (ret
== 0) return total
;
386 return (ssize_t
)total
;
389 ssize_t
vfs_pread_data(files_struct
*fsp
, char *buf
,
390 size_t byte_count
, off_t offset
)
394 while (total
< byte_count
)
396 ssize_t ret
= SMB_VFS_PREAD(fsp
, buf
+ total
,
397 byte_count
- total
, offset
+ total
);
399 if (ret
== 0) return total
;
408 return (ssize_t
)total
;
411 /****************************************************************************
412 Write data to a fd on the vfs.
413 ****************************************************************************/
415 ssize_t
vfs_write_data(struct smb_request
*req
,
423 if (req
&& req
->unread_bytes
) {
424 SMB_ASSERT(req
->unread_bytes
== N
);
425 /* VFS_RECVFILE must drain the socket
426 * before returning. */
427 req
->unread_bytes
= 0;
428 return SMB_VFS_RECVFILE(req
->sconn
->sock
,
435 ret
= SMB_VFS_WRITE(fsp
, buffer
+ total
, N
- total
);
444 return (ssize_t
)total
;
447 ssize_t
vfs_pwrite_data(struct smb_request
*req
,
456 if (req
&& req
->unread_bytes
) {
457 SMB_ASSERT(req
->unread_bytes
== N
);
458 /* VFS_RECVFILE must drain the socket
459 * before returning. */
460 req
->unread_bytes
= 0;
461 return SMB_VFS_RECVFILE(req
->sconn
->sock
,
468 ret
= SMB_VFS_PWRITE(fsp
, buffer
+ total
, N
- total
,
478 return (ssize_t
)total
;
480 /****************************************************************************
481 An allocate file space call using the vfs interface.
482 Allocates space for a file from a filedescriptor.
483 Returns 0 on success, -1 on failure.
484 ****************************************************************************/
486 int vfs_allocate_file_space(files_struct
*fsp
, uint64_t len
)
489 connection_struct
*conn
= fsp
->conn
;
490 uint64_t space_avail
;
491 uint64_t bsize
,dfree
,dsize
;
495 * Actually try and commit the space on disk....
498 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
499 fsp_str_dbg(fsp
), (double)len
));
501 if (((off_t
)len
) < 0) {
502 DEBUG(0,("vfs_allocate_file_space: %s negative len "
503 "requested.\n", fsp_str_dbg(fsp
)));
508 status
= vfs_stat_fsp(fsp
);
509 if (!NT_STATUS_IS_OK(status
)) {
513 if (len
== (uint64_t)fsp
->fsp_name
->st
.st_ex_size
)
516 if (len
< (uint64_t)fsp
->fsp_name
->st
.st_ex_size
) {
517 /* Shrink - use ftruncate. */
519 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
520 "size %.0f\n", fsp_str_dbg(fsp
),
521 (double)fsp
->fsp_name
->st
.st_ex_size
));
523 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_ALLOC_SHRINK
);
525 flush_write_cache(fsp
, SIZECHANGE_FLUSH
);
526 if ((ret
= SMB_VFS_FTRUNCATE(fsp
, (off_t
)len
)) != -1) {
527 set_filelen_write_cache(fsp
, len
);
530 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_ALLOC_SHRINK
);
535 if (!lp_strict_allocate(SNUM(fsp
->conn
)))
538 /* Grow - we need to test if we have enough space. */
540 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_ALLOC_GROW
);
542 /* See if we have a syscall that will allocate beyond end-of-file
543 without changing EOF. */
544 ret
= SMB_VFS_FALLOCATE(fsp
, VFS_FALLOCATE_KEEP_SIZE
, 0, len
);
546 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_ALLOC_GROW
);
549 /* We changed the allocation size on disk, but not
550 EOF - exactly as required. We're done ! */
554 len
-= fsp
->fsp_name
->st
.st_ex_size
;
555 len
/= 1024; /* Len is now number of 1k blocks needed. */
556 space_avail
= get_dfree_info(conn
, fsp
->fsp_name
->base_name
, false,
557 &bsize
, &dfree
, &dsize
);
558 if (space_avail
== (uint64_t)-1) {
562 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
563 "needed blocks = %.0f, space avail = %.0f\n",
564 fsp_str_dbg(fsp
), (double)fsp
->fsp_name
->st
.st_ex_size
, (double)len
,
565 (double)space_avail
));
567 if (len
> space_avail
) {
575 /****************************************************************************
576 A vfs set_filelen call.
577 set the length of a file from a filedescriptor.
578 Returns 0 on success, -1 on failure.
579 ****************************************************************************/
581 int vfs_set_filelen(files_struct
*fsp
, off_t len
)
585 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_SET_FILE_LEN
);
587 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
588 fsp_str_dbg(fsp
), (double)len
));
589 flush_write_cache(fsp
, SIZECHANGE_FLUSH
);
590 if ((ret
= SMB_VFS_FTRUNCATE(fsp
, len
)) != -1) {
591 set_filelen_write_cache(fsp
, len
);
592 notify_fname(fsp
->conn
, NOTIFY_ACTION_MODIFIED
,
593 FILE_NOTIFY_CHANGE_SIZE
594 | FILE_NOTIFY_CHANGE_ATTRIBUTES
,
595 fsp
->fsp_name
->base_name
);
598 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_SET_FILE_LEN
);
603 /****************************************************************************
604 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
605 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
606 as this is also called from the default SMB_VFS_FTRUNCATE code.
607 Always extends the file size.
608 Returns 0 on success, errno on failure.
609 ****************************************************************************/
611 #define SPARSE_BUF_WRITE_SIZE (32*1024)
613 int vfs_slow_fallocate(files_struct
*fsp
, off_t offset
, off_t len
)
619 sparse_buf
= SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE
);
626 while (total
< len
) {
627 size_t curr_write_size
= MIN(SPARSE_BUF_WRITE_SIZE
, (len
- total
));
629 pwrite_ret
= SMB_VFS_PWRITE(fsp
, sparse_buf
, curr_write_size
, offset
+ total
);
630 if (pwrite_ret
== -1) {
631 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
632 "%s failed with error %s\n",
633 fsp_str_dbg(fsp
), strerror(errno
)));
642 /****************************************************************************
643 A vfs fill sparse call.
644 Writes zeros from the end of file to len, if len is greater than EOF.
645 Used only by strict_sync.
646 Returns 0 on success, -1 on failure.
647 ****************************************************************************/
649 int vfs_fill_sparse(files_struct
*fsp
, off_t len
)
656 status
= vfs_stat_fsp(fsp
);
657 if (!NT_STATUS_IS_OK(status
)) {
661 if (len
<= fsp
->fsp_name
->st
.st_ex_size
) {
666 if (S_ISFIFO(fsp
->fsp_name
->st
.st_ex_mode
)) {
671 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
672 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp
),
673 (double)fsp
->fsp_name
->st
.st_ex_size
, (double)len
,
674 (double)(len
- fsp
->fsp_name
->st
.st_ex_size
)));
676 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_FILL_SPARSE
);
678 flush_write_cache(fsp
, SIZECHANGE_FLUSH
);
680 offset
= fsp
->fsp_name
->st
.st_ex_size
;
681 num_to_write
= len
- fsp
->fsp_name
->st
.st_ex_size
;
683 /* Only do this on non-stream file handles. */
684 if (fsp
->base_fsp
== NULL
) {
685 /* for allocation try fallocate first. This can fail on some
686 * platforms e.g. when the filesystem doesn't support it and no
687 * emulation is being done by the libc (like on AIX with JFS1). In that
688 * case we do our own emulation. fallocate implementations can
689 * return ENOTSUP or EINVAL in cases like that. */
690 ret
= SMB_VFS_FALLOCATE(fsp
, VFS_FALLOCATE_EXTEND_SIZE
,
691 offset
, num_to_write
);
700 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
701 "error %d. Falling back to slow manual allocation\n", ret
));
704 ret
= vfs_slow_fallocate(fsp
, offset
, num_to_write
);
713 set_filelen_write_cache(fsp
, len
);
716 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_FILL_SPARSE
);
720 /****************************************************************************
721 Transfer some data (n bytes) between two file_struct's.
722 ****************************************************************************/
724 static ssize_t
vfs_read_fn(void *file
, void *buf
, size_t len
)
726 struct files_struct
*fsp
= (struct files_struct
*)file
;
728 return SMB_VFS_READ(fsp
, buf
, len
);
731 static ssize_t
vfs_write_fn(void *file
, const void *buf
, size_t len
)
733 struct files_struct
*fsp
= (struct files_struct
*)file
;
735 return SMB_VFS_WRITE(fsp
, buf
, len
);
738 off_t
vfs_transfer_file(files_struct
*in
, files_struct
*out
, off_t n
)
740 return transfer_file_internal((void *)in
, (void *)out
, n
,
741 vfs_read_fn
, vfs_write_fn
);
744 /*******************************************************************
745 A vfs_readdir wrapper which just returns the file name.
746 ********************************************************************/
748 const char *vfs_readdirname(connection_struct
*conn
, void *p
,
749 SMB_STRUCT_STAT
*sbuf
, char **talloced
)
751 struct dirent
*ptr
= NULL
;
759 ptr
= SMB_VFS_READDIR(conn
, (DIR *)p
, sbuf
);
771 #ifdef HAVE_BROKEN_READDIR_NAME
772 /* using /usr/ucb/cc is BAD */
776 status
= SMB_VFS_TRANSLATE_NAME(conn
, dname
, vfs_translate_to_windows
,
777 talloc_tos(), &translated
);
778 if (NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
782 *talloced
= translated
;
783 if (!NT_STATUS_IS_OK(status
)) {
789 /*******************************************************************
790 A wrapper for vfs_chdir().
791 ********************************************************************/
793 int vfs_ChDir(connection_struct
*conn
, const char *path
)
798 LastDir
= SMB_STRDUP("");
801 if (strcsequal(path
,"."))
804 if (*path
== '/' && strcsequal(LastDir
,path
))
807 DEBUG(4,("vfs_ChDir to %s\n",path
));
809 res
= SMB_VFS_CHDIR(conn
,path
);
812 LastDir
= SMB_STRDUP(path
);
817 /*******************************************************************
818 Return the absolute current directory path - given a UNIX pathname.
819 Note that this path is returned in DOS format, not UNIX
820 format. Note this can be called with conn == NULL.
821 ********************************************************************/
823 char *vfs_GetWd(TALLOC_CTX
*ctx
, connection_struct
*conn
)
825 char *current_dir
= NULL
;
827 DATA_BLOB cache_value
;
829 struct smb_filename
*smb_fname_dot
= NULL
;
830 struct smb_filename
*smb_fname_full
= NULL
;
833 if (!lp_getwd_cache()) {
837 status
= create_synthetic_smb_fname(ctx
, ".", NULL
, NULL
,
839 if (!NT_STATUS_IS_OK(status
)) {
840 errno
= map_errno_from_nt_status(status
);
844 if (SMB_VFS_STAT(conn
, smb_fname_dot
) == -1) {
846 * Known to fail for root: the directory may be NFS-mounted
847 * and exported with root_squash (so has no root access).
849 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
850 "(NFS problem ?)\n", strerror(errno
) ));
854 key
= vfs_file_id_from_sbuf(conn
, &smb_fname_dot
->st
);
856 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE
,
857 data_blob_const(&key
, sizeof(key
)),
862 SMB_ASSERT((cache_value
.length
> 0)
863 && (cache_value
.data
[cache_value
.length
-1] == '\0'));
865 status
= create_synthetic_smb_fname(ctx
, (char *)cache_value
.data
,
866 NULL
, NULL
, &smb_fname_full
);
867 if (!NT_STATUS_IS_OK(status
)) {
868 errno
= map_errno_from_nt_status(status
);
872 if ((SMB_VFS_STAT(conn
, smb_fname_full
) == 0) &&
873 (smb_fname_dot
->st
.st_ex_dev
== smb_fname_full
->st
.st_ex_dev
) &&
874 (smb_fname_dot
->st
.st_ex_ino
== smb_fname_full
->st
.st_ex_ino
) &&
875 (S_ISDIR(smb_fname_dot
->st
.st_ex_mode
))) {
879 result
= talloc_strdup(ctx
, smb_fname_full
->base_name
);
880 if (result
== NULL
) {
889 * We don't have the information to hand so rely on traditional
890 * methods. The very slow getcwd, which spawns a process on some
891 * systems, or the not quite so bad getwd.
894 current_dir
= SMB_VFS_GETWD(conn
);
895 if (current_dir
== NULL
) {
896 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
901 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot
->st
)) {
902 key
= vfs_file_id_from_sbuf(conn
, &smb_fname_dot
->st
);
904 memcache_add(smbd_memcache(), GETWD_CACHE
,
905 data_blob_const(&key
, sizeof(key
)),
906 data_blob_const(current_dir
,
907 strlen(current_dir
)+1));
910 result
= talloc_strdup(ctx
, current_dir
);
911 if (result
== NULL
) {
916 TALLOC_FREE(smb_fname_dot
);
917 TALLOC_FREE(smb_fname_full
);
918 SAFE_FREE(current_dir
);
922 /*******************************************************************
923 Reduce a file name, removing .. elements and checking that
924 it is below dir in the heirachy. This uses realpath.
925 This function must run as root, and will return names
926 and valid stat structs that can be checked on open.
927 ********************************************************************/
929 NTSTATUS
check_reduced_name_with_privilege(connection_struct
*conn
,
931 struct smb_request
*smbreq
)
934 TALLOC_CTX
*ctx
= talloc_tos();
935 const char *conn_rootdir
;
937 char *dir_name
= NULL
;
938 const char *last_component
= NULL
;
939 char *resolved_name
= NULL
;
940 char *saved_dir
= NULL
;
941 struct smb_filename
*smb_fname_cwd
= NULL
;
942 struct privilege_paths
*priv_paths
= NULL
;
945 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
950 priv_paths
= talloc_zero(smbreq
, struct privilege_paths
);
952 status
= NT_STATUS_NO_MEMORY
;
956 if (!parent_dirname(ctx
, fname
, &dir_name
, &last_component
)) {
957 status
= NT_STATUS_NO_MEMORY
;
961 priv_paths
->parent_name
.base_name
= talloc_strdup(priv_paths
, dir_name
);
962 priv_paths
->file_name
.base_name
= talloc_strdup(priv_paths
, last_component
);
964 if (priv_paths
->parent_name
.base_name
== NULL
||
965 priv_paths
->file_name
.base_name
== NULL
) {
966 status
= NT_STATUS_NO_MEMORY
;
970 if (SMB_VFS_STAT(conn
, &priv_paths
->parent_name
) != 0) {
971 status
= map_nt_error_from_unix(errno
);
974 /* Remember where we were. */
975 saved_dir
= vfs_GetWd(ctx
, conn
);
977 status
= map_nt_error_from_unix(errno
);
981 /* Go to the parent directory to lock in memory. */
982 if (vfs_ChDir(conn
, priv_paths
->parent_name
.base_name
) == -1) {
983 status
= map_nt_error_from_unix(errno
);
987 /* Get the absolute path of the parent directory. */
988 resolved_name
= SMB_VFS_REALPATH(conn
,".");
989 if (!resolved_name
) {
990 status
= map_nt_error_from_unix(errno
);
994 if (*resolved_name
!= '/') {
995 DEBUG(0,("check_reduced_name_with_privilege: realpath "
996 "doesn't return absolute paths !\n"));
997 status
= NT_STATUS_OBJECT_NAME_INVALID
;
1001 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1002 priv_paths
->parent_name
.base_name
,
1005 /* Now check the stat value is the same. */
1006 status
= create_synthetic_smb_fname(talloc_tos(), ".",
1009 if (!NT_STATUS_IS_OK(status
)) {
1013 if (SMB_VFS_LSTAT(conn
, smb_fname_cwd
) != 0) {
1014 status
= map_nt_error_from_unix(errno
);
1018 /* Ensure we're pointing at the same place. */
1019 if (!check_same_stat(&smb_fname_cwd
->st
, &priv_paths
->parent_name
.st
)) {
1020 DEBUG(0,("check_reduced_name_with_privilege: "
1021 "device/inode/uid/gid on directory %s changed. "
1022 "Denying access !\n",
1023 priv_paths
->parent_name
.base_name
));
1024 status
= NT_STATUS_ACCESS_DENIED
;
1028 /* Ensure we're below the connect path. */
1030 conn_rootdir
= SMB_VFS_CONNECTPATH(conn
, fname
);
1031 if (conn_rootdir
== NULL
) {
1032 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1034 status
= NT_STATUS_ACCESS_DENIED
;
1038 rootdir_len
= strlen(conn_rootdir
);
1039 if (strncmp(conn_rootdir
, resolved_name
, rootdir_len
) != 0) {
1040 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1041 "attempt: %s is a symlink outside the "
1044 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir
));
1045 DEBUGADD(2, ("resolved_name=%s\n", resolved_name
));
1046 status
= NT_STATUS_ACCESS_DENIED
;
1050 /* Now ensure that the last component either doesn't
1051 exist, or is *NOT* a symlink. */
1053 ret
= SMB_VFS_LSTAT(conn
, &priv_paths
->file_name
);
1055 /* Errno must be ENOENT for this be ok. */
1056 if (errno
!= ENOENT
) {
1057 status
= map_nt_error_from_unix(errno
);
1058 DEBUG(2, ("check_reduced_name_with_privilege: "
1059 "LSTAT on %s failed with %s\n",
1060 priv_paths
->file_name
.base_name
,
1061 nt_errstr(status
)));
1066 if (VALID_STAT(priv_paths
->file_name
.st
) &&
1067 S_ISLNK(priv_paths
->file_name
.st
.st_ex_mode
)) {
1068 DEBUG(2, ("check_reduced_name_with_privilege: "
1069 "Last component %s is a symlink. Denying"
1071 priv_paths
->file_name
.base_name
));
1072 status
= NT_STATUS_ACCESS_DENIED
;
1076 smbreq
->priv_paths
= priv_paths
;
1077 status
= NT_STATUS_OK
;
1082 vfs_ChDir(conn
, saved_dir
);
1084 SAFE_FREE(resolved_name
);
1085 if (!NT_STATUS_IS_OK(status
)) {
1086 TALLOC_FREE(priv_paths
);
1091 /*******************************************************************
1092 Reduce a file name, removing .. elements and checking that
1093 it is below dir in the heirachy. This uses realpath.
1094 ********************************************************************/
1096 NTSTATUS
check_reduced_name(connection_struct
*conn
, const char *fname
)
1098 char *resolved_name
= NULL
;
1099 bool allow_symlinks
= true;
1100 bool allow_widelinks
= false;
1102 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname
, conn
->connectpath
));
1104 resolved_name
= SMB_VFS_REALPATH(conn
,fname
);
1106 if (!resolved_name
) {
1109 DEBUG(3,("check_reduced_name: Component not a "
1110 "directory in getting realpath for "
1112 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1115 TALLOC_CTX
*ctx
= talloc_tos();
1116 char *dir_name
= NULL
;
1117 const char *last_component
= NULL
;
1118 char *new_name
= NULL
;
1121 /* Last component didn't exist.
1122 Remove it and try and canonicalise
1123 the directory name. */
1124 if (!parent_dirname(ctx
, fname
,
1127 return NT_STATUS_NO_MEMORY
;
1130 resolved_name
= SMB_VFS_REALPATH(conn
,dir_name
);
1131 if (!resolved_name
) {
1132 NTSTATUS status
= map_nt_error_from_unix(errno
);
1134 if (errno
== ENOENT
|| errno
== ENOTDIR
) {
1135 status
= NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1138 DEBUG(3,("check_reduce_name: "
1139 "couldn't get realpath for "
1142 nt_errstr(status
)));
1145 ret
= asprintf(&new_name
, "%s/%s",
1146 resolved_name
, last_component
);
1147 SAFE_FREE(resolved_name
);
1149 return NT_STATUS_NO_MEMORY
;
1151 resolved_name
= new_name
;
1155 DEBUG(3,("check_reduced_name: couldn't get "
1156 "realpath for %s\n", fname
));
1157 return map_nt_error_from_unix(errno
);
1161 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname
,
1164 if (*resolved_name
!= '/') {
1165 DEBUG(0,("check_reduced_name: realpath doesn't return "
1166 "absolute paths !\n"));
1167 SAFE_FREE(resolved_name
);
1168 return NT_STATUS_OBJECT_NAME_INVALID
;
1171 allow_widelinks
= lp_widelinks(SNUM(conn
));
1172 allow_symlinks
= lp_symlinks(SNUM(conn
));
1174 /* Common widelinks and symlinks checks. */
1175 if (!allow_widelinks
|| !allow_symlinks
) {
1176 const char *conn_rootdir
;
1179 conn_rootdir
= SMB_VFS_CONNECTPATH(conn
, fname
);
1180 if (conn_rootdir
== NULL
) {
1181 DEBUG(2, ("check_reduced_name: Could not get "
1183 SAFE_FREE(resolved_name
);
1184 return NT_STATUS_ACCESS_DENIED
;
1187 rootdir_len
= strlen(conn_rootdir
);
1188 if (strncmp(conn_rootdir
, resolved_name
,
1189 rootdir_len
) != 0) {
1190 DEBUG(2, ("check_reduced_name: Bad access "
1191 "attempt: %s is a symlink outside the "
1192 "share path\n", fname
));
1193 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir
));
1194 DEBUGADD(2, ("resolved_name=%s\n", resolved_name
));
1195 SAFE_FREE(resolved_name
);
1196 return NT_STATUS_ACCESS_DENIED
;
1199 /* Extra checks if all symlinks are disallowed. */
1200 if (!allow_symlinks
) {
1201 /* fname can't have changed in resolved_path. */
1202 const char *p
= &resolved_name
[rootdir_len
];
1204 /* *p can be '\0' if fname was "." */
1205 if (*p
== '\0' && ISDOT(fname
)) {
1210 DEBUG(2, ("check_reduced_name: logic error (%c) "
1211 "in resolved_name: %s\n",
1214 SAFE_FREE(resolved_name
);
1215 return NT_STATUS_ACCESS_DENIED
;
1219 if (strcmp(fname
, p
)!=0) {
1220 DEBUG(2, ("check_reduced_name: Bad access "
1221 "attempt: %s is a symlink\n",
1223 SAFE_FREE(resolved_name
);
1224 return NT_STATUS_ACCESS_DENIED
;
1231 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname
,
1233 SAFE_FREE(resolved_name
);
1234 return NT_STATUS_OK
;
1238 * XXX: This is temporary and there should be no callers of this once
1239 * smb_filename is plumbed through all path based operations.
1241 int vfs_stat_smb_fname(struct connection_struct
*conn
, const char *fname
,
1242 SMB_STRUCT_STAT
*psbuf
)
1244 struct smb_filename
*smb_fname
= NULL
;
1248 status
= create_synthetic_smb_fname_split(talloc_tos(), fname
, NULL
,
1250 if (!NT_STATUS_IS_OK(status
)) {
1251 errno
= map_errno_from_nt_status(status
);
1255 if (lp_posix_pathnames()) {
1256 ret
= SMB_VFS_LSTAT(conn
, smb_fname
);
1258 ret
= SMB_VFS_STAT(conn
, smb_fname
);
1262 *psbuf
= smb_fname
->st
;
1265 TALLOC_FREE(smb_fname
);
1270 * XXX: This is temporary and there should be no callers of this once
1271 * smb_filename is plumbed through all path based operations.
1273 int vfs_lstat_smb_fname(struct connection_struct
*conn
, const char *fname
,
1274 SMB_STRUCT_STAT
*psbuf
)
1276 struct smb_filename
*smb_fname
= NULL
;
1280 status
= create_synthetic_smb_fname_split(talloc_tos(), fname
, NULL
,
1282 if (!NT_STATUS_IS_OK(status
)) {
1283 errno
= map_errno_from_nt_status(status
);
1287 ret
= SMB_VFS_LSTAT(conn
, smb_fname
);
1289 *psbuf
= smb_fname
->st
;
1292 TALLOC_FREE(smb_fname
);
1297 * Ensure LSTAT is called for POSIX paths.
1300 NTSTATUS
vfs_stat_fsp(files_struct
*fsp
)
1304 if(fsp
->fh
->fd
== -1) {
1305 if (fsp
->posix_open
) {
1306 ret
= SMB_VFS_LSTAT(fsp
->conn
, fsp
->fsp_name
);
1308 ret
= SMB_VFS_STAT(fsp
->conn
, fsp
->fsp_name
);
1311 return map_nt_error_from_unix(errno
);
1314 if(SMB_VFS_FSTAT(fsp
, &fsp
->fsp_name
->st
) != 0) {
1315 return map_nt_error_from_unix(errno
);
1318 return NT_STATUS_OK
;
1322 * Initialize num_streams and streams, then call VFS op streaminfo
1324 NTSTATUS
vfs_streaminfo(connection_struct
*conn
,
1325 struct files_struct
*fsp
,
1327 TALLOC_CTX
*mem_ctx
,
1328 unsigned int *num_streams
,
1329 struct stream_struct
**streams
)
1333 return SMB_VFS_STREAMINFO(conn
, fsp
, fname
, mem_ctx
, num_streams
, streams
);
1337 generate a file_id from a stat structure
1339 struct file_id
vfs_file_id_from_sbuf(connection_struct
*conn
, const SMB_STRUCT_STAT
*sbuf
)
1341 return SMB_VFS_FILE_ID_CREATE(conn
, sbuf
);
1344 int smb_vfs_call_connect(struct vfs_handle_struct
*handle
,
1345 const char *service
, const char *user
)
1348 return handle
->fns
->connect_fn(handle
, service
, user
);
1351 void smb_vfs_call_disconnect(struct vfs_handle_struct
*handle
)
1353 VFS_FIND(disconnect
);
1354 handle
->fns
->disconnect_fn(handle
);
1357 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct
*handle
,
1358 const char *path
, bool small_query
,
1359 uint64_t *bsize
, uint64_t *dfree
,
1362 VFS_FIND(disk_free
);
1363 return handle
->fns
->disk_free_fn(handle
, path
, small_query
, bsize
,
1367 int smb_vfs_call_get_quota(struct vfs_handle_struct
*handle
,
1368 enum SMB_QUOTA_TYPE qtype
, unid_t id
,
1371 VFS_FIND(get_quota
);
1372 return handle
->fns
->get_quota_fn(handle
, qtype
, id
, qt
);
1375 int smb_vfs_call_set_quota(struct vfs_handle_struct
*handle
,
1376 enum SMB_QUOTA_TYPE qtype
, unid_t id
,
1379 VFS_FIND(set_quota
);
1380 return handle
->fns
->set_quota_fn(handle
, qtype
, id
, qt
);
1383 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct
*handle
,
1384 struct files_struct
*fsp
,
1385 struct shadow_copy_data
*shadow_copy_data
,
1388 VFS_FIND(get_shadow_copy_data
);
1389 return handle
->fns
->get_shadow_copy_data_fn(handle
, fsp
,
1393 int smb_vfs_call_statvfs(struct vfs_handle_struct
*handle
, const char *path
,
1394 struct vfs_statvfs_struct
*statbuf
)
1397 return handle
->fns
->statvfs_fn(handle
, path
, statbuf
);
1400 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct
*handle
,
1401 enum timestamp_set_resolution
*p_ts_res
)
1403 VFS_FIND(fs_capabilities
);
1404 return handle
->fns
->fs_capabilities_fn(handle
, p_ts_res
);
1407 NTSTATUS
smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct
*handle
,
1408 struct dfs_GetDFSReferral
*r
)
1410 VFS_FIND(get_dfs_referrals
);
1411 return handle
->fns
->get_dfs_referrals_fn(handle
, r
);
1414 DIR *smb_vfs_call_opendir(struct vfs_handle_struct
*handle
,
1415 const char *fname
, const char *mask
,
1419 return handle
->fns
->opendir_fn(handle
, fname
, mask
, attributes
);
1422 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct
*handle
,
1423 struct files_struct
*fsp
,
1427 VFS_FIND(fdopendir
);
1428 return handle
->fns
->fdopendir_fn(handle
, fsp
, mask
, attributes
);
1431 struct dirent
*smb_vfs_call_readdir(struct vfs_handle_struct
*handle
,
1433 SMB_STRUCT_STAT
*sbuf
)
1436 return handle
->fns
->readdir_fn(handle
, dirp
, sbuf
);
1439 void smb_vfs_call_seekdir(struct vfs_handle_struct
*handle
,
1440 DIR *dirp
, long offset
)
1443 handle
->fns
->seekdir_fn(handle
, dirp
, offset
);
1446 long smb_vfs_call_telldir(struct vfs_handle_struct
*handle
,
1450 return handle
->fns
->telldir_fn(handle
, dirp
);
1453 void smb_vfs_call_rewind_dir(struct vfs_handle_struct
*handle
,
1456 VFS_FIND(rewind_dir
);
1457 handle
->fns
->rewind_dir_fn(handle
, dirp
);
1460 int smb_vfs_call_mkdir(struct vfs_handle_struct
*handle
, const char *path
,
1464 return handle
->fns
->mkdir_fn(handle
, path
, mode
);
1467 int smb_vfs_call_rmdir(struct vfs_handle_struct
*handle
, const char *path
)
1470 return handle
->fns
->rmdir_fn(handle
, path
);
1473 int smb_vfs_call_closedir(struct vfs_handle_struct
*handle
,
1477 return handle
->fns
->closedir_fn(handle
, dir
);
1480 void smb_vfs_call_init_search_op(struct vfs_handle_struct
*handle
,
1483 VFS_FIND(init_search_op
);
1484 handle
->fns
->init_search_op_fn(handle
, dirp
);
1487 int smb_vfs_call_open(struct vfs_handle_struct
*handle
,
1488 struct smb_filename
*smb_fname
, struct files_struct
*fsp
,
1489 int flags
, mode_t mode
)
1492 return handle
->fns
->open_fn(handle
, smb_fname
, fsp
, flags
, mode
);
1495 NTSTATUS
smb_vfs_call_create_file(struct vfs_handle_struct
*handle
,
1496 struct smb_request
*req
,
1497 uint16_t root_dir_fid
,
1498 struct smb_filename
*smb_fname
,
1499 uint32_t access_mask
,
1500 uint32_t share_access
,
1501 uint32_t create_disposition
,
1502 uint32_t create_options
,
1503 uint32_t file_attributes
,
1504 uint32_t oplock_request
,
1505 uint64_t allocation_size
,
1506 uint32_t private_flags
,
1507 struct security_descriptor
*sd
,
1508 struct ea_list
*ea_list
,
1509 files_struct
**result
,
1512 VFS_FIND(create_file
);
1513 return handle
->fns
->create_file_fn(
1514 handle
, req
, root_dir_fid
, smb_fname
, access_mask
,
1515 share_access
, create_disposition
, create_options
,
1516 file_attributes
, oplock_request
, allocation_size
,
1517 private_flags
, sd
, ea_list
,
1521 int smb_vfs_call_close(struct vfs_handle_struct
*handle
,
1522 struct files_struct
*fsp
)
1525 return handle
->fns
->close_fn(handle
, fsp
);
1528 ssize_t
smb_vfs_call_read(struct vfs_handle_struct
*handle
,
1529 struct files_struct
*fsp
, void *data
, size_t n
)
1532 return handle
->fns
->read_fn(handle
, fsp
, data
, n
);
1535 ssize_t
smb_vfs_call_pread(struct vfs_handle_struct
*handle
,
1536 struct files_struct
*fsp
, void *data
, size_t n
,
1540 return handle
->fns
->pread_fn(handle
, fsp
, data
, n
, offset
);
1543 ssize_t
smb_vfs_call_write(struct vfs_handle_struct
*handle
,
1544 struct files_struct
*fsp
, const void *data
,
1548 return handle
->fns
->write_fn(handle
, fsp
, data
, n
);
1551 ssize_t
smb_vfs_call_pwrite(struct vfs_handle_struct
*handle
,
1552 struct files_struct
*fsp
, const void *data
,
1553 size_t n
, off_t offset
)
1556 return handle
->fns
->pwrite_fn(handle
, fsp
, data
, n
, offset
);
1559 off_t
smb_vfs_call_lseek(struct vfs_handle_struct
*handle
,
1560 struct files_struct
*fsp
, off_t offset
,
1564 return handle
->fns
->lseek_fn(handle
, fsp
, offset
, whence
);
1567 ssize_t
smb_vfs_call_sendfile(struct vfs_handle_struct
*handle
, int tofd
,
1568 files_struct
*fromfsp
, const DATA_BLOB
*header
,
1569 off_t offset
, size_t count
)
1572 return handle
->fns
->sendfile_fn(handle
, tofd
, fromfsp
, header
, offset
,
1576 ssize_t
smb_vfs_call_recvfile(struct vfs_handle_struct
*handle
, int fromfd
,
1577 files_struct
*tofsp
, off_t offset
,
1581 return handle
->fns
->recvfile_fn(handle
, fromfd
, tofsp
, offset
, count
);
1584 int smb_vfs_call_rename(struct vfs_handle_struct
*handle
,
1585 const struct smb_filename
*smb_fname_src
,
1586 const struct smb_filename
*smb_fname_dst
)
1589 return handle
->fns
->rename_fn(handle
, smb_fname_src
, smb_fname_dst
);
1592 int smb_vfs_call_fsync(struct vfs_handle_struct
*handle
,
1593 struct files_struct
*fsp
)
1596 return handle
->fns
->fsync_fn(handle
, fsp
);
1599 int smb_vfs_call_stat(struct vfs_handle_struct
*handle
,
1600 struct smb_filename
*smb_fname
)
1603 return handle
->fns
->stat_fn(handle
, smb_fname
);
1606 int smb_vfs_call_fstat(struct vfs_handle_struct
*handle
,
1607 struct files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
1610 return handle
->fns
->fstat_fn(handle
, fsp
, sbuf
);
1613 int smb_vfs_call_lstat(struct vfs_handle_struct
*handle
,
1614 struct smb_filename
*smb_filename
)
1617 return handle
->fns
->lstat_fn(handle
, smb_filename
);
1620 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct
*handle
,
1621 struct files_struct
*fsp
,
1622 const SMB_STRUCT_STAT
*sbuf
)
1624 VFS_FIND(get_alloc_size
);
1625 return handle
->fns
->get_alloc_size_fn(handle
, fsp
, sbuf
);
1628 int smb_vfs_call_unlink(struct vfs_handle_struct
*handle
,
1629 const struct smb_filename
*smb_fname
)
1632 return handle
->fns
->unlink_fn(handle
, smb_fname
);
1635 int smb_vfs_call_chmod(struct vfs_handle_struct
*handle
, const char *path
,
1639 return handle
->fns
->chmod_fn(handle
, path
, mode
);
1642 int smb_vfs_call_fchmod(struct vfs_handle_struct
*handle
,
1643 struct files_struct
*fsp
, mode_t mode
)
1646 return handle
->fns
->fchmod_fn(handle
, fsp
, mode
);
1649 int smb_vfs_call_chown(struct vfs_handle_struct
*handle
, const char *path
,
1650 uid_t uid
, gid_t gid
)
1653 return handle
->fns
->chown_fn(handle
, path
, uid
, gid
);
1656 int smb_vfs_call_fchown(struct vfs_handle_struct
*handle
,
1657 struct files_struct
*fsp
, uid_t uid
, gid_t gid
)
1660 return handle
->fns
->fchown_fn(handle
, fsp
, uid
, gid
);
1663 int smb_vfs_call_lchown(struct vfs_handle_struct
*handle
, const char *path
,
1664 uid_t uid
, gid_t gid
)
1667 return handle
->fns
->lchown_fn(handle
, path
, uid
, gid
);
1670 NTSTATUS
vfs_chown_fsp(files_struct
*fsp
, uid_t uid
, gid_t gid
)
1673 bool as_root
= false;
1675 char *saved_dir
= NULL
;
1676 char *parent_dir
= NULL
;
1679 if (fsp
->fh
->fd
!= -1) {
1681 ret
= SMB_VFS_FCHOWN(fsp
, uid
, gid
);
1683 return NT_STATUS_OK
;
1685 if (ret
== -1 && errno
!= ENOSYS
) {
1686 return map_nt_error_from_unix(errno
);
1690 as_root
= (geteuid() == 0);
1694 * We are being asked to chown as root. Make
1695 * sure we chdir() into the path to pin it,
1696 * and always act using lchown to ensure we
1697 * don't deref any symbolic links.
1699 const char *final_component
= NULL
;
1700 struct smb_filename local_fname
;
1702 saved_dir
= vfs_GetWd(talloc_tos(),fsp
->conn
);
1704 status
= map_nt_error_from_unix(errno
);
1705 DEBUG(0,("vfs_chown_fsp: failed to get "
1706 "current working directory. Error was %s\n",
1711 if (!parent_dirname(talloc_tos(),
1712 fsp
->fsp_name
->base_name
,
1714 &final_component
)) {
1715 return NT_STATUS_NO_MEMORY
;
1718 /* cd into the parent dir to pin it. */
1719 ret
= vfs_ChDir(fsp
->conn
, parent_dir
);
1721 return map_nt_error_from_unix(errno
);
1724 ZERO_STRUCT(local_fname
);
1725 local_fname
.base_name
= discard_const_p(char, final_component
);
1727 /* Must use lstat here. */
1728 ret
= SMB_VFS_LSTAT(fsp
->conn
, &local_fname
);
1730 status
= map_nt_error_from_unix(errno
);
1734 /* Ensure it matches the fsp stat. */
1735 if (!check_same_stat(&local_fname
.st
, &fsp
->fsp_name
->st
)) {
1736 status
= NT_STATUS_ACCESS_DENIED
;
1739 path
= final_component
;
1741 path
= fsp
->fsp_name
->base_name
;
1744 if (fsp
->posix_open
|| as_root
) {
1745 ret
= SMB_VFS_LCHOWN(fsp
->conn
,
1749 ret
= SMB_VFS_CHOWN(fsp
->conn
,
1755 status
= NT_STATUS_OK
;
1757 status
= map_nt_error_from_unix(errno
);
1763 vfs_ChDir(fsp
->conn
,saved_dir
);
1764 TALLOC_FREE(saved_dir
);
1765 TALLOC_FREE(parent_dir
);
1770 int smb_vfs_call_chdir(struct vfs_handle_struct
*handle
, const char *path
)
1773 return handle
->fns
->chdir_fn(handle
, path
);
1776 char *smb_vfs_call_getwd(struct vfs_handle_struct
*handle
)
1779 return handle
->fns
->getwd_fn(handle
);
1782 int smb_vfs_call_ntimes(struct vfs_handle_struct
*handle
,
1783 const struct smb_filename
*smb_fname
,
1784 struct smb_file_time
*ft
)
1787 return handle
->fns
->ntimes_fn(handle
, smb_fname
, ft
);
1790 int smb_vfs_call_ftruncate(struct vfs_handle_struct
*handle
,
1791 struct files_struct
*fsp
, off_t offset
)
1793 VFS_FIND(ftruncate
);
1794 return handle
->fns
->ftruncate_fn(handle
, fsp
, offset
);
1797 int smb_vfs_call_fallocate(struct vfs_handle_struct
*handle
,
1798 struct files_struct
*fsp
,
1799 enum vfs_fallocate_mode mode
,
1803 VFS_FIND(fallocate
);
1804 return handle
->fns
->fallocate_fn(handle
, fsp
, mode
, offset
, len
);
1807 int smb_vfs_call_kernel_flock(struct vfs_handle_struct
*handle
,
1808 struct files_struct
*fsp
, uint32 share_mode
,
1809 uint32_t access_mask
)
1811 VFS_FIND(kernel_flock
);
1812 return handle
->fns
->kernel_flock_fn(handle
, fsp
, share_mode
,
1816 int smb_vfs_call_linux_setlease(struct vfs_handle_struct
*handle
,
1817 struct files_struct
*fsp
, int leasetype
)
1819 VFS_FIND(linux_setlease
);
1820 return handle
->fns
->linux_setlease_fn(handle
, fsp
, leasetype
);
1823 int smb_vfs_call_symlink(struct vfs_handle_struct
*handle
, const char *oldpath
,
1824 const char *newpath
)
1827 return handle
->fns
->symlink_fn(handle
, oldpath
, newpath
);
1830 int smb_vfs_call_readlink(struct vfs_handle_struct
*handle
,
1831 const char *path
, char *buf
, size_t bufsiz
)
1834 return handle
->fns
->readlink_fn(handle
, path
, buf
, bufsiz
);
1837 int smb_vfs_call_link(struct vfs_handle_struct
*handle
, const char *oldpath
,
1838 const char *newpath
)
1841 return handle
->fns
->link_fn(handle
, oldpath
, newpath
);
1844 int smb_vfs_call_mknod(struct vfs_handle_struct
*handle
, const char *path
,
1845 mode_t mode
, SMB_DEV_T dev
)
1848 return handle
->fns
->mknod_fn(handle
, path
, mode
, dev
);
1851 char *smb_vfs_call_realpath(struct vfs_handle_struct
*handle
, const char *path
)
1854 return handle
->fns
->realpath_fn(handle
, path
);
1857 NTSTATUS
smb_vfs_call_notify_watch(struct vfs_handle_struct
*handle
,
1858 struct sys_notify_context
*ctx
,
1861 uint32_t *subdir_filter
,
1862 void (*callback
)(struct sys_notify_context
*ctx
,
1864 struct notify_event
*ev
),
1865 void *private_data
, void *handle_p
)
1867 VFS_FIND(notify_watch
);
1868 return handle
->fns
->notify_watch_fn(handle
, ctx
, path
,
1869 filter
, subdir_filter
, callback
,
1870 private_data
, handle_p
);
1873 int smb_vfs_call_chflags(struct vfs_handle_struct
*handle
, const char *path
,
1877 return handle
->fns
->chflags_fn(handle
, path
, flags
);
1880 struct file_id
smb_vfs_call_file_id_create(struct vfs_handle_struct
*handle
,
1881 const SMB_STRUCT_STAT
*sbuf
)
1883 VFS_FIND(file_id_create
);
1884 return handle
->fns
->file_id_create_fn(handle
, sbuf
);
1887 NTSTATUS
smb_vfs_call_streaminfo(struct vfs_handle_struct
*handle
,
1888 struct files_struct
*fsp
,
1890 TALLOC_CTX
*mem_ctx
,
1891 unsigned int *num_streams
,
1892 struct stream_struct
**streams
)
1894 VFS_FIND(streaminfo
);
1895 return handle
->fns
->streaminfo_fn(handle
, fsp
, fname
, mem_ctx
,
1896 num_streams
, streams
);
1899 int smb_vfs_call_get_real_filename(struct vfs_handle_struct
*handle
,
1900 const char *path
, const char *name
,
1901 TALLOC_CTX
*mem_ctx
, char **found_name
)
1903 VFS_FIND(get_real_filename
);
1904 return handle
->fns
->get_real_filename_fn(handle
, path
, name
, mem_ctx
,
1908 const char *smb_vfs_call_connectpath(struct vfs_handle_struct
*handle
,
1909 const char *filename
)
1911 VFS_FIND(connectpath
);
1912 return handle
->fns
->connectpath_fn(handle
, filename
);
1915 bool smb_vfs_call_strict_lock(struct vfs_handle_struct
*handle
,
1916 struct files_struct
*fsp
,
1917 struct lock_struct
*plock
)
1919 VFS_FIND(strict_lock
);
1920 return handle
->fns
->strict_lock_fn(handle
, fsp
, plock
);
1923 void smb_vfs_call_strict_unlock(struct vfs_handle_struct
*handle
,
1924 struct files_struct
*fsp
,
1925 struct lock_struct
*plock
)
1927 VFS_FIND(strict_unlock
);
1928 handle
->fns
->strict_unlock_fn(handle
, fsp
, plock
);
1931 NTSTATUS
smb_vfs_call_translate_name(struct vfs_handle_struct
*handle
,
1933 enum vfs_translate_direction direction
,
1934 TALLOC_CTX
*mem_ctx
,
1937 VFS_FIND(translate_name
);
1938 return handle
->fns
->translate_name_fn(handle
, name
, direction
, mem_ctx
,
1942 NTSTATUS
smb_vfs_call_fsctl(struct vfs_handle_struct
*handle
,
1943 struct files_struct
*fsp
,
1947 const uint8_t *in_data
,
1950 uint32_t max_out_len
,
1954 return handle
->fns
->fsctl_fn(handle
, fsp
, ctx
, function
, req_flags
,
1955 in_data
, in_len
, out_data
, max_out_len
,
1959 NTSTATUS
smb_vfs_call_fget_nt_acl(struct vfs_handle_struct
*handle
,
1960 struct files_struct
*fsp
,
1961 uint32 security_info
,
1962 struct security_descriptor
**ppdesc
)
1964 VFS_FIND(fget_nt_acl
);
1965 return handle
->fns
->fget_nt_acl_fn(handle
, fsp
, security_info
,
1969 NTSTATUS
smb_vfs_call_get_nt_acl(struct vfs_handle_struct
*handle
,
1971 uint32 security_info
,
1972 struct security_descriptor
**ppdesc
)
1974 VFS_FIND(get_nt_acl
);
1975 return handle
->fns
->get_nt_acl_fn(handle
, name
, security_info
, ppdesc
);
1978 NTSTATUS
smb_vfs_call_fset_nt_acl(struct vfs_handle_struct
*handle
,
1979 struct files_struct
*fsp
,
1980 uint32 security_info_sent
,
1981 const struct security_descriptor
*psd
)
1983 VFS_FIND(fset_nt_acl
);
1984 return handle
->fns
->fset_nt_acl_fn(handle
, fsp
, security_info_sent
,
1988 NTSTATUS
smb_vfs_call_audit_file(struct vfs_handle_struct
*handle
,
1989 struct smb_filename
*file
,
1990 struct security_acl
*sacl
,
1991 uint32_t access_requested
,
1992 uint32_t access_denied
)
1994 VFS_FIND(audit_file
);
1995 return handle
->fns
->audit_file_fn(handle
,
2002 int smb_vfs_call_chmod_acl(struct vfs_handle_struct
*handle
, const char *name
,
2005 VFS_FIND(chmod_acl
);
2006 return handle
->fns
->chmod_acl_fn(handle
, name
, mode
);
2009 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct
*handle
,
2010 struct files_struct
*fsp
, mode_t mode
)
2012 VFS_FIND(fchmod_acl
);
2013 return handle
->fns
->fchmod_acl_fn(handle
, fsp
, mode
);
2016 int smb_vfs_call_sys_acl_get_entry(struct vfs_handle_struct
*handle
,
2017 SMB_ACL_T theacl
, int entry_id
,
2018 SMB_ACL_ENTRY_T
*entry_p
)
2020 VFS_FIND(sys_acl_get_entry
);
2021 return handle
->fns
->sys_acl_get_entry_fn(handle
, theacl
, entry_id
,
2025 int smb_vfs_call_sys_acl_get_tag_type(struct vfs_handle_struct
*handle
,
2026 SMB_ACL_ENTRY_T entry_d
,
2027 SMB_ACL_TAG_T
*tag_type_p
)
2029 VFS_FIND(sys_acl_get_tag_type
);
2030 return handle
->fns
->sys_acl_get_tag_type_fn(handle
, entry_d
,
2034 int smb_vfs_call_sys_acl_get_permset(struct vfs_handle_struct
*handle
,
2035 SMB_ACL_ENTRY_T entry_d
,
2036 SMB_ACL_PERMSET_T
*permset_p
)
2038 VFS_FIND(sys_acl_get_permset
);
2039 return handle
->fns
->sys_acl_get_permset_fn(handle
, entry_d
, permset_p
);
2042 void * smb_vfs_call_sys_acl_get_qualifier(struct vfs_handle_struct
*handle
,
2043 SMB_ACL_ENTRY_T entry_d
)
2045 VFS_FIND(sys_acl_get_qualifier
);
2046 return handle
->fns
->sys_acl_get_qualifier_fn(handle
, entry_d
);
2049 SMB_ACL_T
smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct
*handle
,
2051 SMB_ACL_TYPE_T type
)
2053 VFS_FIND(sys_acl_get_file
);
2054 return handle
->fns
->sys_acl_get_file_fn(handle
, path_p
, type
);
2057 SMB_ACL_T
smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct
*handle
,
2058 struct files_struct
*fsp
)
2060 VFS_FIND(sys_acl_get_fd
);
2061 return handle
->fns
->sys_acl_get_fd_fn(handle
, fsp
);
2064 int smb_vfs_call_sys_acl_clear_perms(struct vfs_handle_struct
*handle
,
2065 SMB_ACL_PERMSET_T permset
)
2067 VFS_FIND(sys_acl_clear_perms
);
2068 return handle
->fns
->sys_acl_clear_perms_fn(handle
, permset
);
2071 int smb_vfs_call_sys_acl_add_perm(struct vfs_handle_struct
*handle
,
2072 SMB_ACL_PERMSET_T permset
,
2073 SMB_ACL_PERM_T perm
)
2075 VFS_FIND(sys_acl_add_perm
);
2076 return handle
->fns
->sys_acl_add_perm_fn(handle
, permset
, perm
);
2079 char * smb_vfs_call_sys_acl_to_text(struct vfs_handle_struct
*handle
,
2080 SMB_ACL_T theacl
, ssize_t
*plen
)
2082 VFS_FIND(sys_acl_to_text
);
2083 return handle
->fns
->sys_acl_to_text_fn(handle
, theacl
, plen
);
2086 SMB_ACL_T
smb_vfs_call_sys_acl_init(struct vfs_handle_struct
*handle
,
2089 VFS_FIND(sys_acl_init
);
2090 return handle
->fns
->sys_acl_init_fn(handle
, count
);
2093 int smb_vfs_call_sys_acl_create_entry(struct vfs_handle_struct
*handle
,
2094 SMB_ACL_T
*pacl
, SMB_ACL_ENTRY_T
*pentry
)
2096 VFS_FIND(sys_acl_create_entry
);
2097 return handle
->fns
->sys_acl_create_entry_fn(handle
, pacl
, pentry
);
2100 int smb_vfs_call_sys_acl_set_tag_type(struct vfs_handle_struct
*handle
,
2101 SMB_ACL_ENTRY_T entry
,
2102 SMB_ACL_TAG_T tagtype
)
2104 VFS_FIND(sys_acl_set_tag_type
);
2105 return handle
->fns
->sys_acl_set_tag_type_fn(handle
, entry
, tagtype
);
2108 int smb_vfs_call_sys_acl_set_qualifier(struct vfs_handle_struct
*handle
,
2109 SMB_ACL_ENTRY_T entry
, void *qual
)
2111 VFS_FIND(sys_acl_set_qualifier
);
2112 return handle
->fns
->sys_acl_set_qualifier_fn(handle
, entry
, qual
);
2115 int smb_vfs_call_sys_acl_set_permset(struct vfs_handle_struct
*handle
,
2116 SMB_ACL_ENTRY_T entry
,
2117 SMB_ACL_PERMSET_T permset
)
2119 VFS_FIND(sys_acl_set_permset
);
2120 return handle
->fns
->sys_acl_set_permset_fn(handle
, entry
, permset
);
2123 int smb_vfs_call_sys_acl_valid(struct vfs_handle_struct
*handle
,
2126 VFS_FIND(sys_acl_valid
);
2127 return handle
->fns
->sys_acl_valid_fn(handle
, theacl
);
2130 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct
*handle
,
2131 const char *name
, SMB_ACL_TYPE_T acltype
,
2134 VFS_FIND(sys_acl_set_file
);
2135 return handle
->fns
->sys_acl_set_file_fn(handle
, name
, acltype
, theacl
);
2138 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct
*handle
,
2139 struct files_struct
*fsp
, SMB_ACL_T theacl
)
2141 VFS_FIND(sys_acl_set_fd
);
2142 return handle
->fns
->sys_acl_set_fd_fn(handle
, fsp
, theacl
);
2145 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct
*handle
,
2148 VFS_FIND(sys_acl_delete_def_file
);
2149 return handle
->fns
->sys_acl_delete_def_file_fn(handle
, path
);
2152 int smb_vfs_call_sys_acl_get_perm(struct vfs_handle_struct
*handle
,
2153 SMB_ACL_PERMSET_T permset
,
2154 SMB_ACL_PERM_T perm
)
2156 VFS_FIND(sys_acl_get_perm
);
2157 return handle
->fns
->sys_acl_get_perm_fn(handle
, permset
, perm
);
2160 int smb_vfs_call_sys_acl_free_text(struct vfs_handle_struct
*handle
,
2163 VFS_FIND(sys_acl_free_text
);
2164 return handle
->fns
->sys_acl_free_text_fn(handle
, text
);
2167 int smb_vfs_call_sys_acl_free_acl(struct vfs_handle_struct
*handle
,
2168 SMB_ACL_T posix_acl
)
2170 VFS_FIND(sys_acl_free_acl
);
2171 return handle
->fns
->sys_acl_free_acl_fn(handle
, posix_acl
);
2174 int smb_vfs_call_sys_acl_free_qualifier(struct vfs_handle_struct
*handle
,
2175 void *qualifier
, SMB_ACL_TAG_T tagtype
)
2177 VFS_FIND(sys_acl_free_qualifier
);
2178 return handle
->fns
->sys_acl_free_qualifier_fn(handle
, qualifier
,
2182 ssize_t
smb_vfs_call_getxattr(struct vfs_handle_struct
*handle
,
2183 const char *path
, const char *name
, void *value
,
2187 return handle
->fns
->getxattr_fn(handle
, path
, name
, value
, size
);
2190 ssize_t
smb_vfs_call_fgetxattr(struct vfs_handle_struct
*handle
,
2191 struct files_struct
*fsp
, const char *name
,
2192 void *value
, size_t size
)
2194 VFS_FIND(fgetxattr
);
2195 return handle
->fns
->fgetxattr_fn(handle
, fsp
, name
, value
, size
);
2198 ssize_t
smb_vfs_call_listxattr(struct vfs_handle_struct
*handle
,
2199 const char *path
, char *list
, size_t size
)
2201 VFS_FIND(listxattr
);
2202 return handle
->fns
->listxattr_fn(handle
, path
, list
, size
);
2205 ssize_t
smb_vfs_call_flistxattr(struct vfs_handle_struct
*handle
,
2206 struct files_struct
*fsp
, char *list
,
2209 VFS_FIND(flistxattr
);
2210 return handle
->fns
->flistxattr_fn(handle
, fsp
, list
, size
);
2213 int smb_vfs_call_removexattr(struct vfs_handle_struct
*handle
,
2214 const char *path
, const char *name
)
2216 VFS_FIND(removexattr
);
2217 return handle
->fns
->removexattr_fn(handle
, path
, name
);
2220 int smb_vfs_call_fremovexattr(struct vfs_handle_struct
*handle
,
2221 struct files_struct
*fsp
, const char *name
)
2223 VFS_FIND(fremovexattr
);
2224 return handle
->fns
->fremovexattr_fn(handle
, fsp
, name
);
2227 int smb_vfs_call_setxattr(struct vfs_handle_struct
*handle
, const char *path
,
2228 const char *name
, const void *value
, size_t size
,
2232 return handle
->fns
->setxattr_fn(handle
, path
, name
, value
, size
, flags
);
2235 int smb_vfs_call_fsetxattr(struct vfs_handle_struct
*handle
,
2236 struct files_struct
*fsp
, const char *name
,
2237 const void *value
, size_t size
, int flags
)
2239 VFS_FIND(fsetxattr
);
2240 return handle
->fns
->fsetxattr_fn(handle
, fsp
, name
, value
, size
, flags
);
2243 int smb_vfs_call_aio_read(struct vfs_handle_struct
*handle
,
2244 struct files_struct
*fsp
, SMB_STRUCT_AIOCB
*aiocb
)
2247 return handle
->fns
->aio_read_fn(handle
, fsp
, aiocb
);
2250 int smb_vfs_call_aio_write(struct vfs_handle_struct
*handle
,
2251 struct files_struct
*fsp
, SMB_STRUCT_AIOCB
*aiocb
)
2253 VFS_FIND(aio_write
);
2254 return handle
->fns
->aio_write_fn(handle
, fsp
, aiocb
);
2257 ssize_t
smb_vfs_call_aio_return(struct vfs_handle_struct
*handle
,
2258 struct files_struct
*fsp
,
2259 SMB_STRUCT_AIOCB
*aiocb
)
2261 VFS_FIND(aio_return
);
2262 return handle
->fns
->aio_return_fn(handle
, fsp
, aiocb
);
2265 int smb_vfs_call_aio_cancel(struct vfs_handle_struct
*handle
,
2266 struct files_struct
*fsp
, SMB_STRUCT_AIOCB
*aiocb
)
2268 VFS_FIND(aio_cancel
);
2269 return handle
->fns
->aio_cancel_fn(handle
, fsp
, aiocb
);
2272 int smb_vfs_call_aio_error(struct vfs_handle_struct
*handle
,
2273 struct files_struct
*fsp
,
2274 SMB_STRUCT_AIOCB
*aiocb
)
2276 VFS_FIND(aio_error
);
2277 return handle
->fns
->aio_error_fn(handle
, fsp
, aiocb
);
2280 int smb_vfs_call_aio_fsync(struct vfs_handle_struct
*handle
,
2281 struct files_struct
*fsp
, int op
,
2282 SMB_STRUCT_AIOCB
*aiocb
)
2284 VFS_FIND(aio_fsync
);
2285 return handle
->fns
->aio_fsync_fn(handle
, fsp
, op
, aiocb
);
2288 int smb_vfs_call_aio_suspend(struct vfs_handle_struct
*handle
,
2289 struct files_struct
*fsp
,
2290 const SMB_STRUCT_AIOCB
* const aiocb
[], int n
,
2291 const struct timespec
*timeout
)
2293 VFS_FIND(aio_suspend
);
2294 return handle
->fns
->aio_suspend_fn(handle
, fsp
, aiocb
, n
, timeout
);
2297 bool smb_vfs_call_aio_force(struct vfs_handle_struct
*handle
,
2298 struct files_struct
*fsp
)
2300 VFS_FIND(aio_force
);
2301 return handle
->fns
->aio_force_fn(handle
, fsp
);
2304 bool smb_vfs_call_is_offline(struct vfs_handle_struct
*handle
,
2305 const struct smb_filename
*fname
,
2306 SMB_STRUCT_STAT
*sbuf
)
2308 VFS_FIND(is_offline
);
2309 return handle
->fns
->is_offline_fn(handle
, fname
, sbuf
);
2312 int smb_vfs_call_set_offline(struct vfs_handle_struct
*handle
,
2313 const struct smb_filename
*fname
)
2315 VFS_FIND(set_offline
);
2316 return handle
->fns
->set_offline_fn(handle
, fname
);