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
*prev
;
279 for (curr
= fsp
->vfs_extension
, prev
= NULL
;
281 prev
= curr
, curr
= curr
->next
)
284 prev
->next
= curr
->next
;
286 fsp
->vfs_extension
= curr
->next
;
289 curr
->destroy(EXT_DATA_AREA(curr
));
295 void *vfs_memctx_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
297 struct vfs_fsp_data
*head
;
299 for (head
= fsp
->vfs_extension
; head
; head
= head
->next
) {
300 if (head
->owner
== handle
) {
308 void *vfs_fetch_fsp_extension(vfs_handle_struct
*handle
, files_struct
*fsp
)
310 struct vfs_fsp_data
*head
;
312 head
= (struct vfs_fsp_data
*)vfs_memctx_fsp_extension(handle
, fsp
);
314 return EXT_DATA_AREA(head
);
322 /*****************************************************************
324 ******************************************************************/
326 bool smbd_vfs_init(connection_struct
*conn
)
328 const char **vfs_objects
;
332 /* Normal share - initialise with disk access functions */
333 vfs_init_default(conn
);
334 vfs_objects
= lp_vfs_objects(SNUM(conn
));
336 /* Override VFS functions if 'vfs object' was not specified*/
337 if (!vfs_objects
|| !vfs_objects
[0])
340 for (i
=0; vfs_objects
[i
] ;) {
344 for (j
=i
-1; j
>= 0; j
--) {
345 if (!vfs_init_custom(conn
, vfs_objects
[j
])) {
346 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects
[j
]));
353 /*******************************************************************
354 Check if a file exists in the vfs.
355 ********************************************************************/
357 NTSTATUS
vfs_file_exist(connection_struct
*conn
, struct smb_filename
*smb_fname
)
359 /* Only return OK if stat was successful and S_ISREG */
360 if ((SMB_VFS_STAT(conn
, smb_fname
) != -1) &&
361 S_ISREG(smb_fname
->st
.st_ex_mode
)) {
365 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
368 /****************************************************************************
369 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
370 ****************************************************************************/
372 ssize_t
vfs_read_data(files_struct
*fsp
, char *buf
, size_t byte_count
)
376 while (total
< byte_count
)
378 ssize_t ret
= SMB_VFS_READ(fsp
, buf
+ total
,
381 if (ret
== 0) return total
;
390 return (ssize_t
)total
;
393 ssize_t
vfs_pread_data(files_struct
*fsp
, char *buf
,
394 size_t byte_count
, off_t offset
)
398 while (total
< byte_count
)
400 ssize_t ret
= SMB_VFS_PREAD(fsp
, buf
+ total
,
401 byte_count
- total
, offset
+ total
);
403 if (ret
== 0) return total
;
412 return (ssize_t
)total
;
415 /****************************************************************************
416 Write data to a fd on the vfs.
417 ****************************************************************************/
419 ssize_t
vfs_write_data(struct smb_request
*req
,
427 if (req
&& req
->unread_bytes
) {
428 SMB_ASSERT(req
->unread_bytes
== N
);
429 /* VFS_RECVFILE must drain the socket
430 * before returning. */
431 req
->unread_bytes
= 0;
432 return SMB_VFS_RECVFILE(req
->sconn
->sock
,
439 ret
= SMB_VFS_WRITE(fsp
, buffer
+ total
, N
- total
);
448 return (ssize_t
)total
;
451 ssize_t
vfs_pwrite_data(struct smb_request
*req
,
460 if (req
&& req
->unread_bytes
) {
461 SMB_ASSERT(req
->unread_bytes
== N
);
462 /* VFS_RECVFILE must drain the socket
463 * before returning. */
464 req
->unread_bytes
= 0;
465 return SMB_VFS_RECVFILE(req
->sconn
->sock
,
472 ret
= SMB_VFS_PWRITE(fsp
, buffer
+ total
, N
- total
,
482 return (ssize_t
)total
;
484 /****************************************************************************
485 An allocate file space call using the vfs interface.
486 Allocates space for a file from a filedescriptor.
487 Returns 0 on success, -1 on failure.
488 ****************************************************************************/
490 int vfs_allocate_file_space(files_struct
*fsp
, uint64_t len
)
493 connection_struct
*conn
= fsp
->conn
;
494 uint64_t space_avail
;
495 uint64_t bsize
,dfree
,dsize
;
499 * Actually try and commit the space on disk....
502 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
503 fsp_str_dbg(fsp
), (double)len
));
505 if (((off_t
)len
) < 0) {
506 DEBUG(0,("vfs_allocate_file_space: %s negative len "
507 "requested.\n", fsp_str_dbg(fsp
)));
512 status
= vfs_stat_fsp(fsp
);
513 if (!NT_STATUS_IS_OK(status
)) {
517 if (len
== (uint64_t)fsp
->fsp_name
->st
.st_ex_size
)
520 if (len
< (uint64_t)fsp
->fsp_name
->st
.st_ex_size
) {
521 /* Shrink - use ftruncate. */
523 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
524 "size %.0f\n", fsp_str_dbg(fsp
),
525 (double)fsp
->fsp_name
->st
.st_ex_size
));
527 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_ALLOC_SHRINK
);
529 flush_write_cache(fsp
, SIZECHANGE_FLUSH
);
530 if ((ret
= SMB_VFS_FTRUNCATE(fsp
, (off_t
)len
)) != -1) {
531 set_filelen_write_cache(fsp
, len
);
534 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_ALLOC_SHRINK
);
539 if (!lp_strict_allocate(SNUM(fsp
->conn
)))
542 /* Grow - we need to test if we have enough space. */
544 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_ALLOC_GROW
);
546 /* See if we have a syscall that will allocate beyond end-of-file
547 without changing EOF. */
548 ret
= SMB_VFS_FALLOCATE(fsp
, VFS_FALLOCATE_KEEP_SIZE
, 0, len
);
550 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_ALLOC_GROW
);
553 /* We changed the allocation size on disk, but not
554 EOF - exactly as required. We're done ! */
558 len
-= fsp
->fsp_name
->st
.st_ex_size
;
559 len
/= 1024; /* Len is now number of 1k blocks needed. */
560 space_avail
= get_dfree_info(conn
, fsp
->fsp_name
->base_name
, false,
561 &bsize
, &dfree
, &dsize
);
562 if (space_avail
== (uint64_t)-1) {
566 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
567 "needed blocks = %.0f, space avail = %.0f\n",
568 fsp_str_dbg(fsp
), (double)fsp
->fsp_name
->st
.st_ex_size
, (double)len
,
569 (double)space_avail
));
571 if (len
> space_avail
) {
579 /****************************************************************************
580 A vfs set_filelen call.
581 set the length of a file from a filedescriptor.
582 Returns 0 on success, -1 on failure.
583 ****************************************************************************/
585 int vfs_set_filelen(files_struct
*fsp
, off_t len
)
589 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_SET_FILE_LEN
);
591 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
592 fsp_str_dbg(fsp
), (double)len
));
593 flush_write_cache(fsp
, SIZECHANGE_FLUSH
);
594 if ((ret
= SMB_VFS_FTRUNCATE(fsp
, len
)) != -1) {
595 set_filelen_write_cache(fsp
, len
);
596 notify_fname(fsp
->conn
, NOTIFY_ACTION_MODIFIED
,
597 FILE_NOTIFY_CHANGE_SIZE
598 | FILE_NOTIFY_CHANGE_ATTRIBUTES
,
599 fsp
->fsp_name
->base_name
);
602 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_SET_FILE_LEN
);
607 /****************************************************************************
608 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
609 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
610 as this is also called from the default SMB_VFS_FTRUNCATE code.
611 Always extends the file size.
612 Returns 0 on success, errno on failure.
613 ****************************************************************************/
615 #define SPARSE_BUF_WRITE_SIZE (32*1024)
617 int vfs_slow_fallocate(files_struct
*fsp
, off_t offset
, off_t len
)
623 sparse_buf
= SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE
);
630 while (total
< len
) {
631 size_t curr_write_size
= MIN(SPARSE_BUF_WRITE_SIZE
, (len
- total
));
633 pwrite_ret
= SMB_VFS_PWRITE(fsp
, sparse_buf
, curr_write_size
, offset
+ total
);
634 if (pwrite_ret
== -1) {
635 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
636 "%s failed with error %s\n",
637 fsp_str_dbg(fsp
), strerror(errno
)));
646 /****************************************************************************
647 A vfs fill sparse call.
648 Writes zeros from the end of file to len, if len is greater than EOF.
649 Used only by strict_sync.
650 Returns 0 on success, -1 on failure.
651 ****************************************************************************/
653 int vfs_fill_sparse(files_struct
*fsp
, off_t len
)
660 status
= vfs_stat_fsp(fsp
);
661 if (!NT_STATUS_IS_OK(status
)) {
665 if (len
<= fsp
->fsp_name
->st
.st_ex_size
) {
670 if (S_ISFIFO(fsp
->fsp_name
->st
.st_ex_mode
)) {
675 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
676 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp
),
677 (double)fsp
->fsp_name
->st
.st_ex_size
, (double)len
,
678 (double)(len
- fsp
->fsp_name
->st
.st_ex_size
)));
680 contend_level2_oplocks_begin(fsp
, LEVEL2_CONTEND_FILL_SPARSE
);
682 flush_write_cache(fsp
, SIZECHANGE_FLUSH
);
684 offset
= fsp
->fsp_name
->st
.st_ex_size
;
685 num_to_write
= len
- fsp
->fsp_name
->st
.st_ex_size
;
687 /* Only do this on non-stream file handles. */
688 if (fsp
->base_fsp
== NULL
) {
689 /* for allocation try fallocate first. This can fail on some
690 * platforms e.g. when the filesystem doesn't support it and no
691 * emulation is being done by the libc (like on AIX with JFS1). In that
692 * case we do our own emulation. fallocate implementations can
693 * return ENOTSUP or EINVAL in cases like that. */
694 ret
= SMB_VFS_FALLOCATE(fsp
, VFS_FALLOCATE_EXTEND_SIZE
,
695 offset
, num_to_write
);
704 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
705 "error %d. Falling back to slow manual allocation\n", ret
));
708 ret
= vfs_slow_fallocate(fsp
, offset
, num_to_write
);
717 set_filelen_write_cache(fsp
, len
);
720 contend_level2_oplocks_end(fsp
, LEVEL2_CONTEND_FILL_SPARSE
);
724 /****************************************************************************
725 Transfer some data (n bytes) between two file_struct's.
726 ****************************************************************************/
728 static ssize_t
vfs_read_fn(void *file
, void *buf
, size_t len
)
730 struct files_struct
*fsp
= (struct files_struct
*)file
;
732 return SMB_VFS_READ(fsp
, buf
, len
);
735 static ssize_t
vfs_write_fn(void *file
, const void *buf
, size_t len
)
737 struct files_struct
*fsp
= (struct files_struct
*)file
;
739 return SMB_VFS_WRITE(fsp
, buf
, len
);
742 off_t
vfs_transfer_file(files_struct
*in
, files_struct
*out
, off_t n
)
744 return transfer_file_internal((void *)in
, (void *)out
, n
,
745 vfs_read_fn
, vfs_write_fn
);
748 /*******************************************************************
749 A vfs_readdir wrapper which just returns the file name.
750 ********************************************************************/
752 const char *vfs_readdirname(connection_struct
*conn
, void *p
,
753 SMB_STRUCT_STAT
*sbuf
, char **talloced
)
755 struct dirent
*ptr
= NULL
;
763 ptr
= SMB_VFS_READDIR(conn
, (DIR *)p
, sbuf
);
775 #ifdef HAVE_BROKEN_READDIR_NAME
776 /* using /usr/ucb/cc is BAD */
780 status
= SMB_VFS_TRANSLATE_NAME(conn
, dname
, vfs_translate_to_windows
,
781 talloc_tos(), &translated
);
782 if (NT_STATUS_EQUAL(status
, NT_STATUS_NONE_MAPPED
)) {
786 *talloced
= translated
;
787 if (!NT_STATUS_IS_OK(status
)) {
793 /*******************************************************************
794 A wrapper for vfs_chdir().
795 ********************************************************************/
797 int vfs_ChDir(connection_struct
*conn
, const char *path
)
802 LastDir
= SMB_STRDUP("");
805 if (strcsequal(path
,"."))
808 if (*path
== '/' && strcsequal(LastDir
,path
))
811 DEBUG(4,("vfs_ChDir to %s\n",path
));
813 res
= SMB_VFS_CHDIR(conn
,path
);
816 LastDir
= SMB_STRDUP(path
);
821 /*******************************************************************
822 Return the absolute current directory path - given a UNIX pathname.
823 Note that this path is returned in DOS format, not UNIX
824 format. Note this can be called with conn == NULL.
825 ********************************************************************/
827 char *vfs_GetWd(TALLOC_CTX
*ctx
, connection_struct
*conn
)
829 char *current_dir
= NULL
;
831 DATA_BLOB cache_value
;
833 struct smb_filename
*smb_fname_dot
= NULL
;
834 struct smb_filename
*smb_fname_full
= NULL
;
837 if (!lp_getwd_cache()) {
841 status
= create_synthetic_smb_fname(ctx
, ".", NULL
, NULL
,
843 if (!NT_STATUS_IS_OK(status
)) {
844 errno
= map_errno_from_nt_status(status
);
848 if (SMB_VFS_STAT(conn
, smb_fname_dot
) == -1) {
850 * Known to fail for root: the directory may be NFS-mounted
851 * and exported with root_squash (so has no root access).
853 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
854 "(NFS problem ?)\n", strerror(errno
) ));
858 key
= vfs_file_id_from_sbuf(conn
, &smb_fname_dot
->st
);
860 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE
,
861 data_blob_const(&key
, sizeof(key
)),
866 SMB_ASSERT((cache_value
.length
> 0)
867 && (cache_value
.data
[cache_value
.length
-1] == '\0'));
869 status
= create_synthetic_smb_fname(ctx
, (char *)cache_value
.data
,
870 NULL
, NULL
, &smb_fname_full
);
871 if (!NT_STATUS_IS_OK(status
)) {
872 errno
= map_errno_from_nt_status(status
);
876 if ((SMB_VFS_STAT(conn
, smb_fname_full
) == 0) &&
877 (smb_fname_dot
->st
.st_ex_dev
== smb_fname_full
->st
.st_ex_dev
) &&
878 (smb_fname_dot
->st
.st_ex_ino
== smb_fname_full
->st
.st_ex_ino
) &&
879 (S_ISDIR(smb_fname_dot
->st
.st_ex_mode
))) {
883 result
= talloc_strdup(ctx
, smb_fname_full
->base_name
);
884 if (result
== NULL
) {
893 * We don't have the information to hand so rely on traditional
894 * methods. The very slow getcwd, which spawns a process on some
895 * systems, or the not quite so bad getwd.
898 current_dir
= SMB_VFS_GETWD(conn
);
899 if (current_dir
== NULL
) {
900 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
905 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot
->st
)) {
906 key
= vfs_file_id_from_sbuf(conn
, &smb_fname_dot
->st
);
908 memcache_add(smbd_memcache(), GETWD_CACHE
,
909 data_blob_const(&key
, sizeof(key
)),
910 data_blob_const(current_dir
,
911 strlen(current_dir
)+1));
914 result
= talloc_strdup(ctx
, current_dir
);
915 if (result
== NULL
) {
920 TALLOC_FREE(smb_fname_dot
);
921 TALLOC_FREE(smb_fname_full
);
922 SAFE_FREE(current_dir
);
926 /*******************************************************************
927 Reduce a file name, removing .. elements and checking that
928 it is below dir in the heirachy. This uses realpath.
929 This function must run as root, and will return names
930 and valid stat structs that can be checked on open.
931 ********************************************************************/
933 NTSTATUS
check_reduced_name_with_privilege(connection_struct
*conn
,
935 struct smb_request
*smbreq
)
938 TALLOC_CTX
*ctx
= talloc_tos();
939 const char *conn_rootdir
;
941 char *dir_name
= NULL
;
942 const char *last_component
= NULL
;
943 char *resolved_name
= NULL
;
944 char *saved_dir
= NULL
;
945 struct smb_filename
*smb_fname_cwd
= NULL
;
946 struct privilege_paths
*priv_paths
= NULL
;
949 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
954 priv_paths
= talloc_zero(smbreq
, struct privilege_paths
);
956 status
= NT_STATUS_NO_MEMORY
;
960 if (!parent_dirname(ctx
, fname
, &dir_name
, &last_component
)) {
961 status
= NT_STATUS_NO_MEMORY
;
965 priv_paths
->parent_name
.base_name
= talloc_strdup(priv_paths
, dir_name
);
966 priv_paths
->file_name
.base_name
= talloc_strdup(priv_paths
, last_component
);
968 if (priv_paths
->parent_name
.base_name
== NULL
||
969 priv_paths
->file_name
.base_name
== NULL
) {
970 status
= NT_STATUS_NO_MEMORY
;
974 if (SMB_VFS_STAT(conn
, &priv_paths
->parent_name
) != 0) {
975 status
= map_nt_error_from_unix(errno
);
978 /* Remember where we were. */
979 saved_dir
= vfs_GetWd(ctx
, conn
);
981 status
= map_nt_error_from_unix(errno
);
985 /* Go to the parent directory to lock in memory. */
986 if (vfs_ChDir(conn
, priv_paths
->parent_name
.base_name
) == -1) {
987 status
= map_nt_error_from_unix(errno
);
991 /* Get the absolute path of the parent directory. */
992 resolved_name
= SMB_VFS_REALPATH(conn
,".");
993 if (!resolved_name
) {
994 status
= map_nt_error_from_unix(errno
);
998 if (*resolved_name
!= '/') {
999 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1000 "doesn't return absolute paths !\n"));
1001 status
= NT_STATUS_OBJECT_NAME_INVALID
;
1005 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1006 priv_paths
->parent_name
.base_name
,
1009 /* Now check the stat value is the same. */
1010 status
= create_synthetic_smb_fname(talloc_tos(), ".",
1013 if (!NT_STATUS_IS_OK(status
)) {
1017 if (SMB_VFS_LSTAT(conn
, smb_fname_cwd
) != 0) {
1018 status
= map_nt_error_from_unix(errno
);
1022 /* Ensure we're pointing at the same place. */
1023 if (!check_same_stat(&smb_fname_cwd
->st
, &priv_paths
->parent_name
.st
)) {
1024 DEBUG(0,("check_reduced_name_with_privilege: "
1025 "device/inode/uid/gid on directory %s changed. "
1026 "Denying access !\n",
1027 priv_paths
->parent_name
.base_name
));
1028 status
= NT_STATUS_ACCESS_DENIED
;
1032 /* Ensure we're below the connect path. */
1034 conn_rootdir
= SMB_VFS_CONNECTPATH(conn
, fname
);
1035 if (conn_rootdir
== NULL
) {
1036 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1038 status
= NT_STATUS_ACCESS_DENIED
;
1042 rootdir_len
= strlen(conn_rootdir
);
1043 if (strncmp(conn_rootdir
, resolved_name
, rootdir_len
) != 0) {
1044 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1045 "attempt: %s is a symlink outside the "
1048 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir
));
1049 DEBUGADD(2, ("resolved_name=%s\n", resolved_name
));
1050 status
= NT_STATUS_ACCESS_DENIED
;
1054 /* Now ensure that the last component either doesn't
1055 exist, or is *NOT* a symlink. */
1057 ret
= SMB_VFS_LSTAT(conn
, &priv_paths
->file_name
);
1059 /* Errno must be ENOENT for this be ok. */
1060 if (errno
!= ENOENT
) {
1061 status
= map_nt_error_from_unix(errno
);
1062 DEBUG(2, ("check_reduced_name_with_privilege: "
1063 "LSTAT on %s failed with %s\n",
1064 priv_paths
->file_name
.base_name
,
1065 nt_errstr(status
)));
1070 if (VALID_STAT(priv_paths
->file_name
.st
) &&
1071 S_ISLNK(priv_paths
->file_name
.st
.st_ex_mode
)) {
1072 DEBUG(2, ("check_reduced_name_with_privilege: "
1073 "Last component %s is a symlink. Denying"
1075 priv_paths
->file_name
.base_name
));
1076 status
= NT_STATUS_ACCESS_DENIED
;
1080 smbreq
->priv_paths
= priv_paths
;
1081 status
= NT_STATUS_OK
;
1086 vfs_ChDir(conn
, saved_dir
);
1088 SAFE_FREE(resolved_name
);
1089 if (!NT_STATUS_IS_OK(status
)) {
1090 TALLOC_FREE(priv_paths
);
1095 /*******************************************************************
1096 Reduce a file name, removing .. elements and checking that
1097 it is below dir in the heirachy. This uses realpath.
1098 ********************************************************************/
1100 NTSTATUS
check_reduced_name(connection_struct
*conn
, const char *fname
)
1102 char *resolved_name
= NULL
;
1103 bool allow_symlinks
= true;
1104 bool allow_widelinks
= false;
1106 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname
, conn
->connectpath
));
1108 resolved_name
= SMB_VFS_REALPATH(conn
,fname
);
1110 if (!resolved_name
) {
1113 DEBUG(3,("check_reduced_name: Component not a "
1114 "directory in getting realpath for "
1116 return NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1119 TALLOC_CTX
*ctx
= talloc_tos();
1120 char *dir_name
= NULL
;
1121 const char *last_component
= NULL
;
1122 char *new_name
= NULL
;
1125 /* Last component didn't exist.
1126 Remove it and try and canonicalise
1127 the directory name. */
1128 if (!parent_dirname(ctx
, fname
,
1131 return NT_STATUS_NO_MEMORY
;
1134 resolved_name
= SMB_VFS_REALPATH(conn
,dir_name
);
1135 if (!resolved_name
) {
1136 NTSTATUS status
= map_nt_error_from_unix(errno
);
1138 if (errno
== ENOENT
|| errno
== ENOTDIR
) {
1139 status
= NT_STATUS_OBJECT_PATH_NOT_FOUND
;
1142 DEBUG(3,("check_reduce_name: "
1143 "couldn't get realpath for "
1146 nt_errstr(status
)));
1149 ret
= asprintf(&new_name
, "%s/%s",
1150 resolved_name
, last_component
);
1151 SAFE_FREE(resolved_name
);
1153 return NT_STATUS_NO_MEMORY
;
1155 resolved_name
= new_name
;
1159 DEBUG(3,("check_reduced_name: couldn't get "
1160 "realpath for %s\n", fname
));
1161 return map_nt_error_from_unix(errno
);
1165 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname
,
1168 if (*resolved_name
!= '/') {
1169 DEBUG(0,("check_reduced_name: realpath doesn't return "
1170 "absolute paths !\n"));
1171 SAFE_FREE(resolved_name
);
1172 return NT_STATUS_OBJECT_NAME_INVALID
;
1175 allow_widelinks
= lp_widelinks(SNUM(conn
));
1176 allow_symlinks
= lp_symlinks(SNUM(conn
));
1178 /* Common widelinks and symlinks checks. */
1179 if (!allow_widelinks
|| !allow_symlinks
) {
1180 const char *conn_rootdir
;
1183 conn_rootdir
= SMB_VFS_CONNECTPATH(conn
, fname
);
1184 if (conn_rootdir
== NULL
) {
1185 DEBUG(2, ("check_reduced_name: Could not get "
1187 SAFE_FREE(resolved_name
);
1188 return NT_STATUS_ACCESS_DENIED
;
1191 rootdir_len
= strlen(conn_rootdir
);
1192 if (strncmp(conn_rootdir
, resolved_name
,
1193 rootdir_len
) != 0) {
1194 DEBUG(2, ("check_reduced_name: Bad access "
1195 "attempt: %s is a symlink outside the "
1196 "share path\n", fname
));
1197 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir
));
1198 DEBUGADD(2, ("resolved_name=%s\n", resolved_name
));
1199 SAFE_FREE(resolved_name
);
1200 return NT_STATUS_ACCESS_DENIED
;
1203 /* Extra checks if all symlinks are disallowed. */
1204 if (!allow_symlinks
) {
1205 /* fname can't have changed in resolved_path. */
1206 const char *p
= &resolved_name
[rootdir_len
];
1208 /* *p can be '\0' if fname was "." */
1209 if (*p
== '\0' && ISDOT(fname
)) {
1214 DEBUG(2, ("check_reduced_name: logic error (%c) "
1215 "in resolved_name: %s\n",
1218 SAFE_FREE(resolved_name
);
1219 return NT_STATUS_ACCESS_DENIED
;
1223 if (strcmp(fname
, p
)!=0) {
1224 DEBUG(2, ("check_reduced_name: Bad access "
1225 "attempt: %s is a symlink\n",
1227 SAFE_FREE(resolved_name
);
1228 return NT_STATUS_ACCESS_DENIED
;
1235 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname
,
1237 SAFE_FREE(resolved_name
);
1238 return NT_STATUS_OK
;
1242 * XXX: This is temporary and there should be no callers of this once
1243 * smb_filename is plumbed through all path based operations.
1245 int vfs_stat_smb_fname(struct connection_struct
*conn
, const char *fname
,
1246 SMB_STRUCT_STAT
*psbuf
)
1248 struct smb_filename
*smb_fname
= NULL
;
1252 status
= create_synthetic_smb_fname_split(talloc_tos(), fname
, NULL
,
1254 if (!NT_STATUS_IS_OK(status
)) {
1255 errno
= map_errno_from_nt_status(status
);
1259 if (lp_posix_pathnames()) {
1260 ret
= SMB_VFS_LSTAT(conn
, smb_fname
);
1262 ret
= SMB_VFS_STAT(conn
, smb_fname
);
1266 *psbuf
= smb_fname
->st
;
1269 TALLOC_FREE(smb_fname
);
1274 * XXX: This is temporary and there should be no callers of this once
1275 * smb_filename is plumbed through all path based operations.
1277 int vfs_lstat_smb_fname(struct connection_struct
*conn
, const char *fname
,
1278 SMB_STRUCT_STAT
*psbuf
)
1280 struct smb_filename
*smb_fname
= NULL
;
1284 status
= create_synthetic_smb_fname_split(talloc_tos(), fname
, NULL
,
1286 if (!NT_STATUS_IS_OK(status
)) {
1287 errno
= map_errno_from_nt_status(status
);
1291 ret
= SMB_VFS_LSTAT(conn
, smb_fname
);
1293 *psbuf
= smb_fname
->st
;
1296 TALLOC_FREE(smb_fname
);
1301 * Ensure LSTAT is called for POSIX paths.
1304 NTSTATUS
vfs_stat_fsp(files_struct
*fsp
)
1308 if(fsp
->fh
->fd
== -1) {
1309 if (fsp
->posix_open
) {
1310 ret
= SMB_VFS_LSTAT(fsp
->conn
, fsp
->fsp_name
);
1312 ret
= SMB_VFS_STAT(fsp
->conn
, fsp
->fsp_name
);
1315 return map_nt_error_from_unix(errno
);
1318 if(SMB_VFS_FSTAT(fsp
, &fsp
->fsp_name
->st
) != 0) {
1319 return map_nt_error_from_unix(errno
);
1322 return NT_STATUS_OK
;
1326 * Initialize num_streams and streams, then call VFS op streaminfo
1328 NTSTATUS
vfs_streaminfo(connection_struct
*conn
,
1329 struct files_struct
*fsp
,
1331 TALLOC_CTX
*mem_ctx
,
1332 unsigned int *num_streams
,
1333 struct stream_struct
**streams
)
1337 return SMB_VFS_STREAMINFO(conn
, fsp
, fname
, mem_ctx
, num_streams
, streams
);
1341 generate a file_id from a stat structure
1343 struct file_id
vfs_file_id_from_sbuf(connection_struct
*conn
, const SMB_STRUCT_STAT
*sbuf
)
1345 return SMB_VFS_FILE_ID_CREATE(conn
, sbuf
);
1348 int smb_vfs_call_connect(struct vfs_handle_struct
*handle
,
1349 const char *service
, const char *user
)
1352 return handle
->fns
->connect_fn(handle
, service
, user
);
1355 void smb_vfs_call_disconnect(struct vfs_handle_struct
*handle
)
1357 VFS_FIND(disconnect
);
1358 handle
->fns
->disconnect_fn(handle
);
1361 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct
*handle
,
1362 const char *path
, bool small_query
,
1363 uint64_t *bsize
, uint64_t *dfree
,
1366 VFS_FIND(disk_free
);
1367 return handle
->fns
->disk_free_fn(handle
, path
, small_query
, bsize
,
1371 int smb_vfs_call_get_quota(struct vfs_handle_struct
*handle
,
1372 enum SMB_QUOTA_TYPE qtype
, unid_t id
,
1375 VFS_FIND(get_quota
);
1376 return handle
->fns
->get_quota_fn(handle
, qtype
, id
, qt
);
1379 int smb_vfs_call_set_quota(struct vfs_handle_struct
*handle
,
1380 enum SMB_QUOTA_TYPE qtype
, unid_t id
,
1383 VFS_FIND(set_quota
);
1384 return handle
->fns
->set_quota_fn(handle
, qtype
, id
, qt
);
1387 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct
*handle
,
1388 struct files_struct
*fsp
,
1389 struct shadow_copy_data
*shadow_copy_data
,
1392 VFS_FIND(get_shadow_copy_data
);
1393 return handle
->fns
->get_shadow_copy_data_fn(handle
, fsp
,
1397 int smb_vfs_call_statvfs(struct vfs_handle_struct
*handle
, const char *path
,
1398 struct vfs_statvfs_struct
*statbuf
)
1401 return handle
->fns
->statvfs_fn(handle
, path
, statbuf
);
1404 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct
*handle
,
1405 enum timestamp_set_resolution
*p_ts_res
)
1407 VFS_FIND(fs_capabilities
);
1408 return handle
->fns
->fs_capabilities_fn(handle
, p_ts_res
);
1411 NTSTATUS
smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct
*handle
,
1412 struct dfs_GetDFSReferral
*r
)
1414 VFS_FIND(get_dfs_referrals
);
1415 return handle
->fns
->get_dfs_referrals_fn(handle
, r
);
1418 DIR *smb_vfs_call_opendir(struct vfs_handle_struct
*handle
,
1419 const char *fname
, const char *mask
,
1423 return handle
->fns
->opendir_fn(handle
, fname
, mask
, attributes
);
1426 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct
*handle
,
1427 struct files_struct
*fsp
,
1431 VFS_FIND(fdopendir
);
1432 return handle
->fns
->fdopendir_fn(handle
, fsp
, mask
, attributes
);
1435 struct dirent
*smb_vfs_call_readdir(struct vfs_handle_struct
*handle
,
1437 SMB_STRUCT_STAT
*sbuf
)
1440 return handle
->fns
->readdir_fn(handle
, dirp
, sbuf
);
1443 void smb_vfs_call_seekdir(struct vfs_handle_struct
*handle
,
1444 DIR *dirp
, long offset
)
1447 handle
->fns
->seekdir_fn(handle
, dirp
, offset
);
1450 long smb_vfs_call_telldir(struct vfs_handle_struct
*handle
,
1454 return handle
->fns
->telldir_fn(handle
, dirp
);
1457 void smb_vfs_call_rewind_dir(struct vfs_handle_struct
*handle
,
1460 VFS_FIND(rewind_dir
);
1461 handle
->fns
->rewind_dir_fn(handle
, dirp
);
1464 int smb_vfs_call_mkdir(struct vfs_handle_struct
*handle
, const char *path
,
1468 return handle
->fns
->mkdir_fn(handle
, path
, mode
);
1471 int smb_vfs_call_rmdir(struct vfs_handle_struct
*handle
, const char *path
)
1474 return handle
->fns
->rmdir_fn(handle
, path
);
1477 int smb_vfs_call_closedir(struct vfs_handle_struct
*handle
,
1481 return handle
->fns
->closedir_fn(handle
, dir
);
1484 void smb_vfs_call_init_search_op(struct vfs_handle_struct
*handle
,
1487 VFS_FIND(init_search_op
);
1488 handle
->fns
->init_search_op_fn(handle
, dirp
);
1491 int smb_vfs_call_open(struct vfs_handle_struct
*handle
,
1492 struct smb_filename
*smb_fname
, struct files_struct
*fsp
,
1493 int flags
, mode_t mode
)
1496 return handle
->fns
->open_fn(handle
, smb_fname
, fsp
, flags
, mode
);
1499 NTSTATUS
smb_vfs_call_create_file(struct vfs_handle_struct
*handle
,
1500 struct smb_request
*req
,
1501 uint16_t root_dir_fid
,
1502 struct smb_filename
*smb_fname
,
1503 uint32_t access_mask
,
1504 uint32_t share_access
,
1505 uint32_t create_disposition
,
1506 uint32_t create_options
,
1507 uint32_t file_attributes
,
1508 uint32_t oplock_request
,
1509 uint64_t allocation_size
,
1510 uint32_t private_flags
,
1511 struct security_descriptor
*sd
,
1512 struct ea_list
*ea_list
,
1513 files_struct
**result
,
1516 VFS_FIND(create_file
);
1517 return handle
->fns
->create_file_fn(
1518 handle
, req
, root_dir_fid
, smb_fname
, access_mask
,
1519 share_access
, create_disposition
, create_options
,
1520 file_attributes
, oplock_request
, allocation_size
,
1521 private_flags
, sd
, ea_list
,
1525 int smb_vfs_call_close(struct vfs_handle_struct
*handle
,
1526 struct files_struct
*fsp
)
1529 return handle
->fns
->close_fn(handle
, fsp
);
1532 ssize_t
smb_vfs_call_read(struct vfs_handle_struct
*handle
,
1533 struct files_struct
*fsp
, void *data
, size_t n
)
1536 return handle
->fns
->read_fn(handle
, fsp
, data
, n
);
1539 ssize_t
smb_vfs_call_pread(struct vfs_handle_struct
*handle
,
1540 struct files_struct
*fsp
, void *data
, size_t n
,
1544 return handle
->fns
->pread_fn(handle
, fsp
, data
, n
, offset
);
1547 ssize_t
smb_vfs_call_write(struct vfs_handle_struct
*handle
,
1548 struct files_struct
*fsp
, const void *data
,
1552 return handle
->fns
->write_fn(handle
, fsp
, data
, n
);
1555 ssize_t
smb_vfs_call_pwrite(struct vfs_handle_struct
*handle
,
1556 struct files_struct
*fsp
, const void *data
,
1557 size_t n
, off_t offset
)
1560 return handle
->fns
->pwrite_fn(handle
, fsp
, data
, n
, offset
);
1563 off_t
smb_vfs_call_lseek(struct vfs_handle_struct
*handle
,
1564 struct files_struct
*fsp
, off_t offset
,
1568 return handle
->fns
->lseek_fn(handle
, fsp
, offset
, whence
);
1571 ssize_t
smb_vfs_call_sendfile(struct vfs_handle_struct
*handle
, int tofd
,
1572 files_struct
*fromfsp
, const DATA_BLOB
*header
,
1573 off_t offset
, size_t count
)
1576 return handle
->fns
->sendfile_fn(handle
, tofd
, fromfsp
, header
, offset
,
1580 ssize_t
smb_vfs_call_recvfile(struct vfs_handle_struct
*handle
, int fromfd
,
1581 files_struct
*tofsp
, off_t offset
,
1585 return handle
->fns
->recvfile_fn(handle
, fromfd
, tofsp
, offset
, count
);
1588 int smb_vfs_call_rename(struct vfs_handle_struct
*handle
,
1589 const struct smb_filename
*smb_fname_src
,
1590 const struct smb_filename
*smb_fname_dst
)
1593 return handle
->fns
->rename_fn(handle
, smb_fname_src
, smb_fname_dst
);
1596 int smb_vfs_call_fsync(struct vfs_handle_struct
*handle
,
1597 struct files_struct
*fsp
)
1600 return handle
->fns
->fsync_fn(handle
, fsp
);
1603 int smb_vfs_call_stat(struct vfs_handle_struct
*handle
,
1604 struct smb_filename
*smb_fname
)
1607 return handle
->fns
->stat_fn(handle
, smb_fname
);
1610 int smb_vfs_call_fstat(struct vfs_handle_struct
*handle
,
1611 struct files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
1614 return handle
->fns
->fstat_fn(handle
, fsp
, sbuf
);
1617 int smb_vfs_call_lstat(struct vfs_handle_struct
*handle
,
1618 struct smb_filename
*smb_filename
)
1621 return handle
->fns
->lstat_fn(handle
, smb_filename
);
1624 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct
*handle
,
1625 struct files_struct
*fsp
,
1626 const SMB_STRUCT_STAT
*sbuf
)
1628 VFS_FIND(get_alloc_size
);
1629 return handle
->fns
->get_alloc_size_fn(handle
, fsp
, sbuf
);
1632 int smb_vfs_call_unlink(struct vfs_handle_struct
*handle
,
1633 const struct smb_filename
*smb_fname
)
1636 return handle
->fns
->unlink_fn(handle
, smb_fname
);
1639 int smb_vfs_call_chmod(struct vfs_handle_struct
*handle
, const char *path
,
1643 return handle
->fns
->chmod_fn(handle
, path
, mode
);
1646 int smb_vfs_call_fchmod(struct vfs_handle_struct
*handle
,
1647 struct files_struct
*fsp
, mode_t mode
)
1650 return handle
->fns
->fchmod_fn(handle
, fsp
, mode
);
1653 int smb_vfs_call_chown(struct vfs_handle_struct
*handle
, const char *path
,
1654 uid_t uid
, gid_t gid
)
1657 return handle
->fns
->chown_fn(handle
, path
, uid
, gid
);
1660 int smb_vfs_call_fchown(struct vfs_handle_struct
*handle
,
1661 struct files_struct
*fsp
, uid_t uid
, gid_t gid
)
1664 return handle
->fns
->fchown_fn(handle
, fsp
, uid
, gid
);
1667 int smb_vfs_call_lchown(struct vfs_handle_struct
*handle
, const char *path
,
1668 uid_t uid
, gid_t gid
)
1671 return handle
->fns
->lchown_fn(handle
, path
, uid
, gid
);
1674 NTSTATUS
vfs_chown_fsp(files_struct
*fsp
, uid_t uid
, gid_t gid
)
1677 bool as_root
= false;
1679 char *saved_dir
= NULL
;
1680 char *parent_dir
= NULL
;
1683 if (fsp
->fh
->fd
!= -1) {
1685 ret
= SMB_VFS_FCHOWN(fsp
, uid
, gid
);
1687 return NT_STATUS_OK
;
1689 if (ret
== -1 && errno
!= ENOSYS
) {
1690 return map_nt_error_from_unix(errno
);
1694 as_root
= (geteuid() == 0);
1698 * We are being asked to chown as root. Make
1699 * sure we chdir() into the path to pin it,
1700 * and always act using lchown to ensure we
1701 * don't deref any symbolic links.
1703 const char *final_component
= NULL
;
1704 struct smb_filename local_fname
;
1706 saved_dir
= vfs_GetWd(talloc_tos(),fsp
->conn
);
1708 status
= map_nt_error_from_unix(errno
);
1709 DEBUG(0,("vfs_chown_fsp: failed to get "
1710 "current working directory. Error was %s\n",
1715 if (!parent_dirname(talloc_tos(),
1716 fsp
->fsp_name
->base_name
,
1718 &final_component
)) {
1719 return NT_STATUS_NO_MEMORY
;
1722 /* cd into the parent dir to pin it. */
1723 ret
= vfs_ChDir(fsp
->conn
, parent_dir
);
1725 return map_nt_error_from_unix(errno
);
1728 ZERO_STRUCT(local_fname
);
1729 local_fname
.base_name
= discard_const_p(char, final_component
);
1731 /* Must use lstat here. */
1732 ret
= SMB_VFS_LSTAT(fsp
->conn
, &local_fname
);
1734 status
= map_nt_error_from_unix(errno
);
1738 /* Ensure it matches the fsp stat. */
1739 if (!check_same_stat(&local_fname
.st
, &fsp
->fsp_name
->st
)) {
1740 status
= NT_STATUS_ACCESS_DENIED
;
1743 path
= final_component
;
1745 path
= fsp
->fsp_name
->base_name
;
1748 if (fsp
->posix_open
|| as_root
) {
1749 ret
= SMB_VFS_LCHOWN(fsp
->conn
,
1753 ret
= SMB_VFS_CHOWN(fsp
->conn
,
1759 status
= NT_STATUS_OK
;
1761 status
= map_nt_error_from_unix(errno
);
1767 vfs_ChDir(fsp
->conn
,saved_dir
);
1768 TALLOC_FREE(saved_dir
);
1769 TALLOC_FREE(parent_dir
);
1774 int smb_vfs_call_chdir(struct vfs_handle_struct
*handle
, const char *path
)
1777 return handle
->fns
->chdir_fn(handle
, path
);
1780 char *smb_vfs_call_getwd(struct vfs_handle_struct
*handle
)
1783 return handle
->fns
->getwd_fn(handle
);
1786 int smb_vfs_call_ntimes(struct vfs_handle_struct
*handle
,
1787 const struct smb_filename
*smb_fname
,
1788 struct smb_file_time
*ft
)
1791 return handle
->fns
->ntimes_fn(handle
, smb_fname
, ft
);
1794 int smb_vfs_call_ftruncate(struct vfs_handle_struct
*handle
,
1795 struct files_struct
*fsp
, off_t offset
)
1797 VFS_FIND(ftruncate
);
1798 return handle
->fns
->ftruncate_fn(handle
, fsp
, offset
);
1801 int smb_vfs_call_fallocate(struct vfs_handle_struct
*handle
,
1802 struct files_struct
*fsp
,
1803 enum vfs_fallocate_mode mode
,
1807 VFS_FIND(fallocate
);
1808 return handle
->fns
->fallocate_fn(handle
, fsp
, mode
, offset
, len
);
1811 int smb_vfs_call_kernel_flock(struct vfs_handle_struct
*handle
,
1812 struct files_struct
*fsp
, uint32 share_mode
,
1813 uint32_t access_mask
)
1815 VFS_FIND(kernel_flock
);
1816 return handle
->fns
->kernel_flock_fn(handle
, fsp
, share_mode
,
1820 int smb_vfs_call_linux_setlease(struct vfs_handle_struct
*handle
,
1821 struct files_struct
*fsp
, int leasetype
)
1823 VFS_FIND(linux_setlease
);
1824 return handle
->fns
->linux_setlease_fn(handle
, fsp
, leasetype
);
1827 int smb_vfs_call_symlink(struct vfs_handle_struct
*handle
, const char *oldpath
,
1828 const char *newpath
)
1831 return handle
->fns
->symlink_fn(handle
, oldpath
, newpath
);
1834 int smb_vfs_call_readlink(struct vfs_handle_struct
*handle
,
1835 const char *path
, char *buf
, size_t bufsiz
)
1838 return handle
->fns
->readlink_fn(handle
, path
, buf
, bufsiz
);
1841 int smb_vfs_call_link(struct vfs_handle_struct
*handle
, const char *oldpath
,
1842 const char *newpath
)
1845 return handle
->fns
->link_fn(handle
, oldpath
, newpath
);
1848 int smb_vfs_call_mknod(struct vfs_handle_struct
*handle
, const char *path
,
1849 mode_t mode
, SMB_DEV_T dev
)
1852 return handle
->fns
->mknod_fn(handle
, path
, mode
, dev
);
1855 char *smb_vfs_call_realpath(struct vfs_handle_struct
*handle
, const char *path
)
1858 return handle
->fns
->realpath_fn(handle
, path
);
1861 NTSTATUS
smb_vfs_call_notify_watch(struct vfs_handle_struct
*handle
,
1862 struct sys_notify_context
*ctx
,
1865 uint32_t *subdir_filter
,
1866 void (*callback
)(struct sys_notify_context
*ctx
,
1868 struct notify_event
*ev
),
1869 void *private_data
, void *handle_p
)
1871 VFS_FIND(notify_watch
);
1872 return handle
->fns
->notify_watch_fn(handle
, ctx
, path
,
1873 filter
, subdir_filter
, callback
,
1874 private_data
, handle_p
);
1877 int smb_vfs_call_chflags(struct vfs_handle_struct
*handle
, const char *path
,
1881 return handle
->fns
->chflags_fn(handle
, path
, flags
);
1884 struct file_id
smb_vfs_call_file_id_create(struct vfs_handle_struct
*handle
,
1885 const SMB_STRUCT_STAT
*sbuf
)
1887 VFS_FIND(file_id_create
);
1888 return handle
->fns
->file_id_create_fn(handle
, sbuf
);
1891 NTSTATUS
smb_vfs_call_streaminfo(struct vfs_handle_struct
*handle
,
1892 struct files_struct
*fsp
,
1894 TALLOC_CTX
*mem_ctx
,
1895 unsigned int *num_streams
,
1896 struct stream_struct
**streams
)
1898 VFS_FIND(streaminfo
);
1899 return handle
->fns
->streaminfo_fn(handle
, fsp
, fname
, mem_ctx
,
1900 num_streams
, streams
);
1903 int smb_vfs_call_get_real_filename(struct vfs_handle_struct
*handle
,
1904 const char *path
, const char *name
,
1905 TALLOC_CTX
*mem_ctx
, char **found_name
)
1907 VFS_FIND(get_real_filename
);
1908 return handle
->fns
->get_real_filename_fn(handle
, path
, name
, mem_ctx
,
1912 const char *smb_vfs_call_connectpath(struct vfs_handle_struct
*handle
,
1913 const char *filename
)
1915 VFS_FIND(connectpath
);
1916 return handle
->fns
->connectpath_fn(handle
, filename
);
1919 bool smb_vfs_call_strict_lock(struct vfs_handle_struct
*handle
,
1920 struct files_struct
*fsp
,
1921 struct lock_struct
*plock
)
1923 VFS_FIND(strict_lock
);
1924 return handle
->fns
->strict_lock_fn(handle
, fsp
, plock
);
1927 void smb_vfs_call_strict_unlock(struct vfs_handle_struct
*handle
,
1928 struct files_struct
*fsp
,
1929 struct lock_struct
*plock
)
1931 VFS_FIND(strict_unlock
);
1932 handle
->fns
->strict_unlock_fn(handle
, fsp
, plock
);
1935 NTSTATUS
smb_vfs_call_translate_name(struct vfs_handle_struct
*handle
,
1937 enum vfs_translate_direction direction
,
1938 TALLOC_CTX
*mem_ctx
,
1941 VFS_FIND(translate_name
);
1942 return handle
->fns
->translate_name_fn(handle
, name
, direction
, mem_ctx
,
1946 NTSTATUS
smb_vfs_call_fsctl(struct vfs_handle_struct
*handle
,
1947 struct files_struct
*fsp
,
1951 const uint8_t *in_data
,
1954 uint32_t max_out_len
,
1958 return handle
->fns
->fsctl_fn(handle
, fsp
, ctx
, function
, req_flags
,
1959 in_data
, in_len
, out_data
, max_out_len
,
1963 NTSTATUS
smb_vfs_call_fget_nt_acl(struct vfs_handle_struct
*handle
,
1964 struct files_struct
*fsp
,
1965 uint32 security_info
,
1966 struct security_descriptor
**ppdesc
)
1968 VFS_FIND(fget_nt_acl
);
1969 return handle
->fns
->fget_nt_acl_fn(handle
, fsp
, security_info
,
1973 NTSTATUS
smb_vfs_call_get_nt_acl(struct vfs_handle_struct
*handle
,
1975 uint32 security_info
,
1976 struct security_descriptor
**ppdesc
)
1978 VFS_FIND(get_nt_acl
);
1979 return handle
->fns
->get_nt_acl_fn(handle
, name
, security_info
, ppdesc
);
1982 NTSTATUS
smb_vfs_call_fset_nt_acl(struct vfs_handle_struct
*handle
,
1983 struct files_struct
*fsp
,
1984 uint32 security_info_sent
,
1985 const struct security_descriptor
*psd
)
1987 VFS_FIND(fset_nt_acl
);
1988 return handle
->fns
->fset_nt_acl_fn(handle
, fsp
, security_info_sent
,
1992 NTSTATUS
smb_vfs_call_audit_file(struct vfs_handle_struct
*handle
,
1993 struct smb_filename
*file
,
1994 struct security_acl
*sacl
,
1995 uint32_t access_requested
,
1996 uint32_t access_denied
)
1998 VFS_FIND(audit_file
);
1999 return handle
->fns
->audit_file_fn(handle
,
2006 int smb_vfs_call_chmod_acl(struct vfs_handle_struct
*handle
, const char *name
,
2009 VFS_FIND(chmod_acl
);
2010 return handle
->fns
->chmod_acl_fn(handle
, name
, mode
);
2013 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct
*handle
,
2014 struct files_struct
*fsp
, mode_t mode
)
2016 VFS_FIND(fchmod_acl
);
2017 return handle
->fns
->fchmod_acl_fn(handle
, fsp
, mode
);
2020 int smb_vfs_call_sys_acl_get_entry(struct vfs_handle_struct
*handle
,
2021 SMB_ACL_T theacl
, int entry_id
,
2022 SMB_ACL_ENTRY_T
*entry_p
)
2024 VFS_FIND(sys_acl_get_entry
);
2025 return handle
->fns
->sys_acl_get_entry_fn(handle
, theacl
, entry_id
,
2029 int smb_vfs_call_sys_acl_get_tag_type(struct vfs_handle_struct
*handle
,
2030 SMB_ACL_ENTRY_T entry_d
,
2031 SMB_ACL_TAG_T
*tag_type_p
)
2033 VFS_FIND(sys_acl_get_tag_type
);
2034 return handle
->fns
->sys_acl_get_tag_type_fn(handle
, entry_d
,
2038 int smb_vfs_call_sys_acl_get_permset(struct vfs_handle_struct
*handle
,
2039 SMB_ACL_ENTRY_T entry_d
,
2040 SMB_ACL_PERMSET_T
*permset_p
)
2042 VFS_FIND(sys_acl_get_permset
);
2043 return handle
->fns
->sys_acl_get_permset_fn(handle
, entry_d
, permset_p
);
2046 void * smb_vfs_call_sys_acl_get_qualifier(struct vfs_handle_struct
*handle
,
2047 SMB_ACL_ENTRY_T entry_d
)
2049 VFS_FIND(sys_acl_get_qualifier
);
2050 return handle
->fns
->sys_acl_get_qualifier_fn(handle
, entry_d
);
2053 SMB_ACL_T
smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct
*handle
,
2055 SMB_ACL_TYPE_T type
)
2057 VFS_FIND(sys_acl_get_file
);
2058 return handle
->fns
->sys_acl_get_file_fn(handle
, path_p
, type
);
2061 SMB_ACL_T
smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct
*handle
,
2062 struct files_struct
*fsp
)
2064 VFS_FIND(sys_acl_get_fd
);
2065 return handle
->fns
->sys_acl_get_fd_fn(handle
, fsp
);
2068 int smb_vfs_call_sys_acl_clear_perms(struct vfs_handle_struct
*handle
,
2069 SMB_ACL_PERMSET_T permset
)
2071 VFS_FIND(sys_acl_clear_perms
);
2072 return handle
->fns
->sys_acl_clear_perms_fn(handle
, permset
);
2075 int smb_vfs_call_sys_acl_add_perm(struct vfs_handle_struct
*handle
,
2076 SMB_ACL_PERMSET_T permset
,
2077 SMB_ACL_PERM_T perm
)
2079 VFS_FIND(sys_acl_add_perm
);
2080 return handle
->fns
->sys_acl_add_perm_fn(handle
, permset
, perm
);
2083 char * smb_vfs_call_sys_acl_to_text(struct vfs_handle_struct
*handle
,
2084 SMB_ACL_T theacl
, ssize_t
*plen
)
2086 VFS_FIND(sys_acl_to_text
);
2087 return handle
->fns
->sys_acl_to_text_fn(handle
, theacl
, plen
);
2090 SMB_ACL_T
smb_vfs_call_sys_acl_init(struct vfs_handle_struct
*handle
,
2093 VFS_FIND(sys_acl_init
);
2094 return handle
->fns
->sys_acl_init_fn(handle
, count
);
2097 int smb_vfs_call_sys_acl_create_entry(struct vfs_handle_struct
*handle
,
2098 SMB_ACL_T
*pacl
, SMB_ACL_ENTRY_T
*pentry
)
2100 VFS_FIND(sys_acl_create_entry
);
2101 return handle
->fns
->sys_acl_create_entry_fn(handle
, pacl
, pentry
);
2104 int smb_vfs_call_sys_acl_set_tag_type(struct vfs_handle_struct
*handle
,
2105 SMB_ACL_ENTRY_T entry
,
2106 SMB_ACL_TAG_T tagtype
)
2108 VFS_FIND(sys_acl_set_tag_type
);
2109 return handle
->fns
->sys_acl_set_tag_type_fn(handle
, entry
, tagtype
);
2112 int smb_vfs_call_sys_acl_set_qualifier(struct vfs_handle_struct
*handle
,
2113 SMB_ACL_ENTRY_T entry
, void *qual
)
2115 VFS_FIND(sys_acl_set_qualifier
);
2116 return handle
->fns
->sys_acl_set_qualifier_fn(handle
, entry
, qual
);
2119 int smb_vfs_call_sys_acl_set_permset(struct vfs_handle_struct
*handle
,
2120 SMB_ACL_ENTRY_T entry
,
2121 SMB_ACL_PERMSET_T permset
)
2123 VFS_FIND(sys_acl_set_permset
);
2124 return handle
->fns
->sys_acl_set_permset_fn(handle
, entry
, permset
);
2127 int smb_vfs_call_sys_acl_valid(struct vfs_handle_struct
*handle
,
2130 VFS_FIND(sys_acl_valid
);
2131 return handle
->fns
->sys_acl_valid_fn(handle
, theacl
);
2134 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct
*handle
,
2135 const char *name
, SMB_ACL_TYPE_T acltype
,
2138 VFS_FIND(sys_acl_set_file
);
2139 return handle
->fns
->sys_acl_set_file_fn(handle
, name
, acltype
, theacl
);
2142 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct
*handle
,
2143 struct files_struct
*fsp
, SMB_ACL_T theacl
)
2145 VFS_FIND(sys_acl_set_fd
);
2146 return handle
->fns
->sys_acl_set_fd_fn(handle
, fsp
, theacl
);
2149 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct
*handle
,
2152 VFS_FIND(sys_acl_delete_def_file
);
2153 return handle
->fns
->sys_acl_delete_def_file_fn(handle
, path
);
2156 int smb_vfs_call_sys_acl_get_perm(struct vfs_handle_struct
*handle
,
2157 SMB_ACL_PERMSET_T permset
,
2158 SMB_ACL_PERM_T perm
)
2160 VFS_FIND(sys_acl_get_perm
);
2161 return handle
->fns
->sys_acl_get_perm_fn(handle
, permset
, perm
);
2164 int smb_vfs_call_sys_acl_free_text(struct vfs_handle_struct
*handle
,
2167 VFS_FIND(sys_acl_free_text
);
2168 return handle
->fns
->sys_acl_free_text_fn(handle
, text
);
2171 int smb_vfs_call_sys_acl_free_acl(struct vfs_handle_struct
*handle
,
2172 SMB_ACL_T posix_acl
)
2174 VFS_FIND(sys_acl_free_acl
);
2175 return handle
->fns
->sys_acl_free_acl_fn(handle
, posix_acl
);
2178 int smb_vfs_call_sys_acl_free_qualifier(struct vfs_handle_struct
*handle
,
2179 void *qualifier
, SMB_ACL_TAG_T tagtype
)
2181 VFS_FIND(sys_acl_free_qualifier
);
2182 return handle
->fns
->sys_acl_free_qualifier_fn(handle
, qualifier
,
2186 ssize_t
smb_vfs_call_getxattr(struct vfs_handle_struct
*handle
,
2187 const char *path
, const char *name
, void *value
,
2191 return handle
->fns
->getxattr_fn(handle
, path
, name
, value
, size
);
2194 ssize_t
smb_vfs_call_fgetxattr(struct vfs_handle_struct
*handle
,
2195 struct files_struct
*fsp
, const char *name
,
2196 void *value
, size_t size
)
2198 VFS_FIND(fgetxattr
);
2199 return handle
->fns
->fgetxattr_fn(handle
, fsp
, name
, value
, size
);
2202 ssize_t
smb_vfs_call_listxattr(struct vfs_handle_struct
*handle
,
2203 const char *path
, char *list
, size_t size
)
2205 VFS_FIND(listxattr
);
2206 return handle
->fns
->listxattr_fn(handle
, path
, list
, size
);
2209 ssize_t
smb_vfs_call_flistxattr(struct vfs_handle_struct
*handle
,
2210 struct files_struct
*fsp
, char *list
,
2213 VFS_FIND(flistxattr
);
2214 return handle
->fns
->flistxattr_fn(handle
, fsp
, list
, size
);
2217 int smb_vfs_call_removexattr(struct vfs_handle_struct
*handle
,
2218 const char *path
, const char *name
)
2220 VFS_FIND(removexattr
);
2221 return handle
->fns
->removexattr_fn(handle
, path
, name
);
2224 int smb_vfs_call_fremovexattr(struct vfs_handle_struct
*handle
,
2225 struct files_struct
*fsp
, const char *name
)
2227 VFS_FIND(fremovexattr
);
2228 return handle
->fns
->fremovexattr_fn(handle
, fsp
, name
);
2231 int smb_vfs_call_setxattr(struct vfs_handle_struct
*handle
, const char *path
,
2232 const char *name
, const void *value
, size_t size
,
2236 return handle
->fns
->setxattr_fn(handle
, path
, name
, value
, size
, flags
);
2239 int smb_vfs_call_fsetxattr(struct vfs_handle_struct
*handle
,
2240 struct files_struct
*fsp
, const char *name
,
2241 const void *value
, size_t size
, int flags
)
2243 VFS_FIND(fsetxattr
);
2244 return handle
->fns
->fsetxattr_fn(handle
, fsp
, name
, value
, size
, flags
);
2247 int smb_vfs_call_aio_read(struct vfs_handle_struct
*handle
,
2248 struct files_struct
*fsp
, SMB_STRUCT_AIOCB
*aiocb
)
2251 return handle
->fns
->aio_read_fn(handle
, fsp
, aiocb
);
2254 int smb_vfs_call_aio_write(struct vfs_handle_struct
*handle
,
2255 struct files_struct
*fsp
, SMB_STRUCT_AIOCB
*aiocb
)
2257 VFS_FIND(aio_write
);
2258 return handle
->fns
->aio_write_fn(handle
, fsp
, aiocb
);
2261 ssize_t
smb_vfs_call_aio_return(struct vfs_handle_struct
*handle
,
2262 struct files_struct
*fsp
,
2263 SMB_STRUCT_AIOCB
*aiocb
)
2265 VFS_FIND(aio_return
);
2266 return handle
->fns
->aio_return_fn(handle
, fsp
, aiocb
);
2269 int smb_vfs_call_aio_cancel(struct vfs_handle_struct
*handle
,
2270 struct files_struct
*fsp
, SMB_STRUCT_AIOCB
*aiocb
)
2272 VFS_FIND(aio_cancel
);
2273 return handle
->fns
->aio_cancel_fn(handle
, fsp
, aiocb
);
2276 int smb_vfs_call_aio_error(struct vfs_handle_struct
*handle
,
2277 struct files_struct
*fsp
,
2278 SMB_STRUCT_AIOCB
*aiocb
)
2280 VFS_FIND(aio_error
);
2281 return handle
->fns
->aio_error_fn(handle
, fsp
, aiocb
);
2284 int smb_vfs_call_aio_fsync(struct vfs_handle_struct
*handle
,
2285 struct files_struct
*fsp
, int op
,
2286 SMB_STRUCT_AIOCB
*aiocb
)
2288 VFS_FIND(aio_fsync
);
2289 return handle
->fns
->aio_fsync_fn(handle
, fsp
, op
, aiocb
);
2292 int smb_vfs_call_aio_suspend(struct vfs_handle_struct
*handle
,
2293 struct files_struct
*fsp
,
2294 const SMB_STRUCT_AIOCB
* const aiocb
[], int n
,
2295 const struct timespec
*timeout
)
2297 VFS_FIND(aio_suspend
);
2298 return handle
->fns
->aio_suspend_fn(handle
, fsp
, aiocb
, n
, timeout
);
2301 bool smb_vfs_call_aio_force(struct vfs_handle_struct
*handle
,
2302 struct files_struct
*fsp
)
2304 VFS_FIND(aio_force
);
2305 return handle
->fns
->aio_force_fn(handle
, fsp
);
2308 bool smb_vfs_call_is_offline(struct vfs_handle_struct
*handle
,
2309 const struct smb_filename
*fname
,
2310 SMB_STRUCT_STAT
*sbuf
)
2312 VFS_FIND(is_offline
);
2313 return handle
->fns
->is_offline_fn(handle
, fname
, sbuf
);
2316 int smb_vfs_call_set_offline(struct vfs_handle_struct
*handle
,
2317 const struct smb_filename
*fname
)
2319 VFS_FIND(set_offline
);
2320 return handle
->fns
->set_offline_fn(handle
, fname
);