2 Unix SMB/Netbios implementation.
4 VFS initialisation and support functions
5 Copyright (C) Tim Potter 1999
6 Copyright (C) Alexander Bokovoy 2002
7 Copyright (C) James Peach 2006
8 Copyright (C) Volker Lendecke 2009
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 This work was sponsored by Optifacio Software Services, Inc.
27 #include "system/filesys.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
31 #include "transfer_file.h"
33 #include "lib/util/tevent_unix.h"
36 #define DBGC_CLASS DBGC_VFS
41 struct vfs_fsp_data *next;
42 struct vfs_handle_struct *owner;
43 void (*destroy)(void *p_data);
45 /* NOTE: This structure contains four pointers so that we can guarantee
46 * that the end of the structure is always both 4-byte and 8-byte aligned.
50 struct vfs_init_function_entry {
52 struct vfs_init_function_entry *prev, *next;
53 const struct vfs_fn_pointers *fns;
56 /****************************************************************************
57 maintain the list of available backends
58 ****************************************************************************/
60 static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
62 struct vfs_init_function_entry *entry = backends;
64 DEBUG(10, ("vfs_find_backend_entry called for %s\n", name));
67 if (strcmp(entry->name, name)==0) return entry;
74 NTSTATUS smb_register_vfs(int version, const char *name,
75 const struct vfs_fn_pointers *fns)
77 struct vfs_init_function_entry *entry = backends;
79 if ((version != SMB_VFS_INTERFACE_VERSION)) {
80 DEBUG(0, ("Failed to register vfs module.\n"
81 "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
82 "current SMB_VFS_INTERFACE_VERSION is %d.\n"
83 "Please recompile against the current Samba Version!\n",
84 version, SMB_VFS_INTERFACE_VERSION));
85 return NT_STATUS_OBJECT_TYPE_MISMATCH;
88 if (!name || !name[0]) {
89 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
90 return NT_STATUS_INVALID_PARAMETER;
93 if (vfs_find_backend_entry(name)) {
94 DEBUG(0,("VFS module %s already loaded!\n", name));
95 return NT_STATUS_OBJECT_NAME_COLLISION;
98 entry = SMB_XMALLOC_P(struct vfs_init_function_entry);
99 entry->name = smb_xstrdup(name);
102 DLIST_ADD(backends, entry);
103 DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
107 /****************************************************************************
108 initialise default vfs hooks
109 ****************************************************************************/
111 static void vfs_init_default(connection_struct *conn)
113 DEBUG(3, ("Initialising default vfs hooks\n"));
114 vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME);
117 /****************************************************************************
118 initialise custom vfs hooks
119 ****************************************************************************/
121 bool vfs_init_custom(connection_struct *conn, const char *vfs_object)
123 char *module_path = NULL;
124 char *module_name = NULL;
125 char *module_param = NULL, *p;
126 vfs_handle_struct *handle;
127 const struct vfs_init_function_entry *entry;
129 if (!conn||!vfs_object||!vfs_object[0]) {
130 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
131 "empty vfs_object!\n"));
139 DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
141 module_path = smb_xstrdup(vfs_object);
143 p = strchr_m(module_path, ':');
148 trim_char(module_param, ' ', ' ');
151 trim_char(module_path, ' ', ' ');
153 module_name = smb_xstrdup(module_path);
155 if ((module_name[0] == '/') &&
156 (strcmp(module_path, DEFAULT_VFS_MODULE_NAME) != 0)) {
159 * Extract the module name from the path. Just use the base
160 * name of the last path component.
163 SAFE_FREE(module_name);
164 module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
166 p = strchr_m(module_name, '.');
173 /* First, try to load the module with the new module system */
174 entry = vfs_find_backend_entry(module_name);
178 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
181 status = smb_load_module("vfs", module_path);
182 if (!NT_STATUS_IS_OK(status)) {
183 DEBUG(0, ("error probing vfs module '%s': %s\n",
184 module_path, nt_errstr(status)));
188 entry = vfs_find_backend_entry(module_name);
190 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
195 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
197 handle = talloc_zero(conn, vfs_handle_struct);
199 DEBUG(0,("TALLOC_ZERO() failed!\n"));
203 handle->fns = entry->fns;
205 handle->param = talloc_strdup(conn, module_param);
207 DLIST_ADD(conn->vfs_handles, handle);
209 SAFE_FREE(module_path);
210 SAFE_FREE(module_name);
214 SAFE_FREE(module_path);
215 SAFE_FREE(module_name);
219 /*****************************************************************
220 Allow VFS modules to extend files_struct with VFS-specific state.
221 This will be ok for small numbers of extensions, but might need to
222 be refactored if it becomes more widely used.
223 ******************************************************************/
225 #define EXT_DATA_AREA(e) ((uint8 *)(e) + sizeof(struct vfs_fsp_data))
227 void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle,
228 files_struct *fsp, size_t ext_size,
229 void (*destroy_fn)(void *p_data))
231 struct vfs_fsp_data *ext;
234 /* Prevent VFS modules adding multiple extensions. */
235 if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
239 ext = (struct vfs_fsp_data *)TALLOC_ZERO(
240 handle->conn, sizeof(struct vfs_fsp_data) + ext_size);
246 ext->next = fsp->vfs_extension;
247 ext->destroy = destroy_fn;
248 fsp->vfs_extension = ext;
249 return EXT_DATA_AREA(ext);
252 void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
254 struct vfs_fsp_data *curr;
255 struct vfs_fsp_data *prev;
257 for (curr = fsp->vfs_extension, prev = NULL;
259 prev = curr, curr = curr->next) {
260 if (curr->owner == handle) {
262 prev->next = curr->next;
264 fsp->vfs_extension = curr->next;
267 curr->destroy(EXT_DATA_AREA(curr));
275 void vfs_remove_all_fsp_extensions(files_struct *fsp)
277 struct vfs_fsp_data *curr;
278 struct vfs_fsp_data *next;
280 for (curr = fsp->vfs_extension; curr; curr = next) {
283 fsp->vfs_extension = next;
286 curr->destroy(EXT_DATA_AREA(curr));
292 void *vfs_memctx_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
294 struct vfs_fsp_data *head;
296 for (head = fsp->vfs_extension; head; head = head->next) {
297 if (head->owner == handle) {
305 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
307 struct vfs_fsp_data *head;
309 head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
311 return EXT_DATA_AREA(head);
319 /*****************************************************************
321 ******************************************************************/
323 bool smbd_vfs_init(connection_struct *conn)
325 const char **vfs_objects;
329 /* Normal share - initialise with disk access functions */
330 vfs_init_default(conn);
332 /* No need to load vfs modules for printer connections */
337 vfs_objects = lp_vfs_objects(SNUM(conn));
339 /* Override VFS functions if 'vfs object' was not specified*/
340 if (!vfs_objects || !vfs_objects[0])
343 for (i=0; vfs_objects[i] ;) {
347 for (j=i-1; j >= 0; j--) {
348 if (!vfs_init_custom(conn, vfs_objects[j])) {
349 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
356 /*******************************************************************
357 Check if a file exists in the vfs.
358 ********************************************************************/
360 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
362 /* Only return OK if stat was successful and S_ISREG */
363 if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
364 S_ISREG(smb_fname->st.st_ex_mode)) {
368 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
371 /****************************************************************************
372 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
373 ****************************************************************************/
375 ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
379 while (total < byte_count)
381 ssize_t ret = SMB_VFS_READ(fsp, buf + total,
384 if (ret == 0) return total;
393 return (ssize_t)total;
396 ssize_t vfs_pread_data(files_struct *fsp, char *buf,
397 size_t byte_count, off_t offset)
401 while (total < byte_count)
403 ssize_t ret = SMB_VFS_PREAD(fsp, buf + total,
404 byte_count - total, offset + total);
406 if (ret == 0) return total;
415 return (ssize_t)total;
418 /****************************************************************************
419 Write data to a fd on the vfs.
420 ****************************************************************************/
422 ssize_t vfs_write_data(struct smb_request *req,
430 if (req && req->unread_bytes) {
431 SMB_ASSERT(req->unread_bytes == N);
432 /* VFS_RECVFILE must drain the socket
433 * before returning. */
434 req->unread_bytes = 0;
435 return SMB_VFS_RECVFILE(req->sconn->sock,
442 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
451 return (ssize_t)total;
454 ssize_t vfs_pwrite_data(struct smb_request *req,
463 if (req && req->unread_bytes) {
464 SMB_ASSERT(req->unread_bytes == N);
465 /* VFS_RECVFILE must drain the socket
466 * before returning. */
467 req->unread_bytes = 0;
468 return SMB_VFS_RECVFILE(req->sconn->sock,
475 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
485 return (ssize_t)total;
487 /****************************************************************************
488 An allocate file space call using the vfs interface.
489 Allocates space for a file from a filedescriptor.
490 Returns 0 on success, -1 on failure.
491 ****************************************************************************/
493 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
496 connection_struct *conn = fsp->conn;
497 uint64_t space_avail;
498 uint64_t bsize,dfree,dsize;
502 * Actually try and commit the space on disk....
505 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
506 fsp_str_dbg(fsp), (double)len));
508 if (((off_t)len) < 0) {
509 DEBUG(0,("vfs_allocate_file_space: %s negative len "
510 "requested.\n", fsp_str_dbg(fsp)));
515 status = vfs_stat_fsp(fsp);
516 if (!NT_STATUS_IS_OK(status)) {
520 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
523 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
524 /* Shrink - use ftruncate. */
526 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
527 "size %.0f\n", fsp_str_dbg(fsp),
528 (double)fsp->fsp_name->st.st_ex_size));
530 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
532 flush_write_cache(fsp, SIZECHANGE_FLUSH);
533 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
534 set_filelen_write_cache(fsp, len);
537 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
542 if (!lp_strict_allocate(SNUM(fsp->conn)))
545 /* Grow - we need to test if we have enough space. */
547 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
549 /* See if we have a syscall that will allocate beyond end-of-file
550 without changing EOF. */
551 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
553 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
556 /* We changed the allocation size on disk, but not
557 EOF - exactly as required. We're done ! */
561 len -= fsp->fsp_name->st.st_ex_size;
562 len /= 1024; /* Len is now number of 1k blocks needed. */
563 space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
564 &bsize, &dfree, &dsize);
565 if (space_avail == (uint64_t)-1) {
569 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
570 "needed blocks = %.0f, space avail = %.0f\n",
571 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
572 (double)space_avail));
574 if (len > space_avail) {
582 /****************************************************************************
583 A vfs set_filelen call.
584 set the length of a file from a filedescriptor.
585 Returns 0 on success, -1 on failure.
586 ****************************************************************************/
588 int vfs_set_filelen(files_struct *fsp, off_t len)
592 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
594 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
595 fsp_str_dbg(fsp), (double)len));
596 flush_write_cache(fsp, SIZECHANGE_FLUSH);
597 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
598 set_filelen_write_cache(fsp, len);
599 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
600 FILE_NOTIFY_CHANGE_SIZE
601 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
602 fsp->fsp_name->base_name);
605 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
610 /****************************************************************************
611 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
612 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
613 as this is also called from the default SMB_VFS_FTRUNCATE code.
614 Always extends the file size.
615 Returns 0 on success, errno on failure.
616 ****************************************************************************/
618 #define SPARSE_BUF_WRITE_SIZE (32*1024)
620 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
626 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
633 while (total < len) {
634 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
636 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
637 if (pwrite_ret == -1) {
638 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
639 "%s failed with error %s\n",
640 fsp_str_dbg(fsp), strerror(errno)));
649 /****************************************************************************
650 A vfs fill sparse call.
651 Writes zeros from the end of file to len, if len is greater than EOF.
652 Used only by strict_sync.
653 Returns 0 on success, -1 on failure.
654 ****************************************************************************/
656 int vfs_fill_sparse(files_struct *fsp, off_t len)
663 status = vfs_stat_fsp(fsp);
664 if (!NT_STATUS_IS_OK(status)) {
668 if (len <= fsp->fsp_name->st.st_ex_size) {
673 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
678 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
679 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
680 (double)fsp->fsp_name->st.st_ex_size, (double)len,
681 (double)(len - fsp->fsp_name->st.st_ex_size)));
683 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
685 flush_write_cache(fsp, SIZECHANGE_FLUSH);
687 offset = fsp->fsp_name->st.st_ex_size;
688 num_to_write = len - fsp->fsp_name->st.st_ex_size;
690 /* Only do this on non-stream file handles. */
691 if (fsp->base_fsp == NULL) {
692 /* for allocation try fallocate first. This can fail on some
693 * platforms e.g. when the filesystem doesn't support it and no
694 * emulation is being done by the libc (like on AIX with JFS1). In that
695 * case we do our own emulation. fallocate implementations can
696 * return ENOTSUP or EINVAL in cases like that. */
697 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
698 offset, num_to_write);
707 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
708 "error %d. Falling back to slow manual allocation\n", ret));
711 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
720 set_filelen_write_cache(fsp, len);
723 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
727 /****************************************************************************
728 Transfer some data (n bytes) between two file_struct's.
729 ****************************************************************************/
731 static ssize_t vfs_read_fn(void *file, void *buf, size_t len)
733 struct files_struct *fsp = (struct files_struct *)file;
735 return SMB_VFS_READ(fsp, buf, len);
738 static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
740 struct files_struct *fsp = (struct files_struct *)file;
742 return SMB_VFS_WRITE(fsp, buf, len);
745 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
747 return transfer_file_internal((void *)in, (void *)out, n,
748 vfs_read_fn, vfs_write_fn);
751 /*******************************************************************
752 A vfs_readdir wrapper which just returns the file name.
753 ********************************************************************/
755 const char *vfs_readdirname(connection_struct *conn, void *p,
756 SMB_STRUCT_STAT *sbuf, char **talloced)
758 struct dirent *ptr= NULL;
766 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
778 #ifdef HAVE_BROKEN_READDIR_NAME
779 /* using /usr/ucb/cc is BAD */
783 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
784 talloc_tos(), &translated);
785 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
789 *talloced = translated;
790 if (!NT_STATUS_IS_OK(status)) {
796 /*******************************************************************
797 A wrapper for vfs_chdir().
798 ********************************************************************/
800 int vfs_ChDir(connection_struct *conn, const char *path)
802 if (strcsequal(path,".")) {
806 DEBUG(4,("vfs_ChDir to %s\n",path));
808 return SMB_VFS_CHDIR(conn,path);
811 /*******************************************************************
812 Return the absolute current directory path - given a UNIX pathname.
813 Note that this path is returned in DOS format, not UNIX
814 format. Note this can be called with conn == NULL.
815 ********************************************************************/
817 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
819 char *current_dir = NULL;
821 DATA_BLOB cache_value;
823 struct smb_filename *smb_fname_dot = NULL;
824 struct smb_filename *smb_fname_full = NULL;
827 if (!lp_getwd_cache()) {
831 status = create_synthetic_smb_fname(ctx, ".", NULL, NULL,
833 if (!NT_STATUS_IS_OK(status)) {
834 errno = map_errno_from_nt_status(status);
838 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
840 * Known to fail for root: the directory may be NFS-mounted
841 * and exported with root_squash (so has no root access).
843 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
844 "(NFS problem ?)\n", strerror(errno) ));
848 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
850 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
851 data_blob_const(&key, sizeof(key)),
856 SMB_ASSERT((cache_value.length > 0)
857 && (cache_value.data[cache_value.length-1] == '\0'));
859 status = create_synthetic_smb_fname(ctx, (char *)cache_value.data,
860 NULL, NULL, &smb_fname_full);
861 if (!NT_STATUS_IS_OK(status)) {
862 errno = map_errno_from_nt_status(status);
866 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
867 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
868 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
869 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
873 result = talloc_strdup(ctx, smb_fname_full->base_name);
874 if (result == NULL) {
883 * We don't have the information to hand so rely on traditional
884 * methods. The very slow getcwd, which spawns a process on some
885 * systems, or the not quite so bad getwd.
888 current_dir = SMB_VFS_GETWD(conn);
889 if (current_dir == NULL) {
890 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
895 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
896 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
898 memcache_add(smbd_memcache(), GETWD_CACHE,
899 data_blob_const(&key, sizeof(key)),
900 data_blob_const(current_dir,
901 strlen(current_dir)+1));
904 result = talloc_strdup(ctx, current_dir);
905 if (result == NULL) {
910 TALLOC_FREE(smb_fname_dot);
911 TALLOC_FREE(smb_fname_full);
912 SAFE_FREE(current_dir);
916 /*******************************************************************
917 Reduce a file name, removing .. elements and checking that
918 it is below dir in the heirachy. This uses realpath.
919 This function must run as root, and will return names
920 and valid stat structs that can be checked on open.
921 ********************************************************************/
923 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
925 struct smb_request *smbreq)
928 TALLOC_CTX *ctx = talloc_tos();
929 const char *conn_rootdir;
931 char *dir_name = NULL;
932 const char *last_component = NULL;
933 char *resolved_name = NULL;
934 char *saved_dir = NULL;
935 struct smb_filename *smb_fname_cwd = NULL;
936 struct privilege_paths *priv_paths = NULL;
939 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
944 priv_paths = talloc_zero(smbreq, struct privilege_paths);
946 status = NT_STATUS_NO_MEMORY;
950 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
951 status = NT_STATUS_NO_MEMORY;
955 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
956 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
958 if (priv_paths->parent_name.base_name == NULL ||
959 priv_paths->file_name.base_name == NULL) {
960 status = NT_STATUS_NO_MEMORY;
964 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
965 status = map_nt_error_from_unix(errno);
968 /* Remember where we were. */
969 saved_dir = vfs_GetWd(ctx, conn);
971 status = map_nt_error_from_unix(errno);
975 /* Go to the parent directory to lock in memory. */
976 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
977 status = map_nt_error_from_unix(errno);
981 /* Get the absolute path of the parent directory. */
982 resolved_name = SMB_VFS_REALPATH(conn,".");
983 if (!resolved_name) {
984 status = map_nt_error_from_unix(errno);
988 if (*resolved_name != '/') {
989 DEBUG(0,("check_reduced_name_with_privilege: realpath "
990 "doesn't return absolute paths !\n"));
991 status = NT_STATUS_OBJECT_NAME_INVALID;
995 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
996 priv_paths->parent_name.base_name,
999 /* Now check the stat value is the same. */
1000 status = create_synthetic_smb_fname(talloc_tos(), ".",
1003 if (!NT_STATUS_IS_OK(status)) {
1007 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1008 status = map_nt_error_from_unix(errno);
1012 /* Ensure we're pointing at the same place. */
1013 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1014 DEBUG(0,("check_reduced_name_with_privilege: "
1015 "device/inode/uid/gid on directory %s changed. "
1016 "Denying access !\n",
1017 priv_paths->parent_name.base_name));
1018 status = NT_STATUS_ACCESS_DENIED;
1022 /* Ensure we're below the connect path. */
1024 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1025 if (conn_rootdir == NULL) {
1026 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1028 status = NT_STATUS_ACCESS_DENIED;
1032 rootdir_len = strlen(conn_rootdir);
1033 if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1034 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1035 "attempt: %s is a symlink outside the "
1038 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1039 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1040 status = NT_STATUS_ACCESS_DENIED;
1044 /* Now ensure that the last component either doesn't
1045 exist, or is *NOT* a symlink. */
1047 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1049 /* Errno must be ENOENT for this be ok. */
1050 if (errno != ENOENT) {
1051 status = map_nt_error_from_unix(errno);
1052 DEBUG(2, ("check_reduced_name_with_privilege: "
1053 "LSTAT on %s failed with %s\n",
1054 priv_paths->file_name.base_name,
1055 nt_errstr(status)));
1060 if (VALID_STAT(priv_paths->file_name.st) &&
1061 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1062 DEBUG(2, ("check_reduced_name_with_privilege: "
1063 "Last component %s is a symlink. Denying"
1065 priv_paths->file_name.base_name));
1066 status = NT_STATUS_ACCESS_DENIED;
1070 smbreq->priv_paths = priv_paths;
1071 status = NT_STATUS_OK;
1076 vfs_ChDir(conn, saved_dir);
1078 SAFE_FREE(resolved_name);
1079 if (!NT_STATUS_IS_OK(status)) {
1080 TALLOC_FREE(priv_paths);
1082 TALLOC_FREE(dir_name);
1086 /*******************************************************************
1087 Reduce a file name, removing .. elements and checking that
1088 it is below dir in the heirachy. This uses realpath.
1089 ********************************************************************/
1091 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1093 char *resolved_name = NULL;
1094 bool allow_symlinks = true;
1095 bool allow_widelinks = false;
1097 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1099 resolved_name = SMB_VFS_REALPATH(conn,fname);
1101 if (!resolved_name) {
1104 DEBUG(3,("check_reduced_name: Component not a "
1105 "directory in getting realpath for "
1107 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1110 TALLOC_CTX *ctx = talloc_tos();
1111 char *dir_name = NULL;
1112 const char *last_component = NULL;
1113 char *new_name = NULL;
1116 /* Last component didn't exist.
1117 Remove it and try and canonicalise
1118 the directory name. */
1119 if (!parent_dirname(ctx, fname,
1122 return NT_STATUS_NO_MEMORY;
1125 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1126 if (!resolved_name) {
1127 NTSTATUS status = map_nt_error_from_unix(errno);
1129 if (errno == ENOENT || errno == ENOTDIR) {
1130 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1133 DEBUG(3,("check_reduce_name: "
1134 "couldn't get realpath for "
1137 nt_errstr(status)));
1140 ret = asprintf(&new_name, "%s/%s",
1141 resolved_name, last_component);
1142 SAFE_FREE(resolved_name);
1144 return NT_STATUS_NO_MEMORY;
1146 resolved_name = new_name;
1150 DEBUG(3,("check_reduced_name: couldn't get "
1151 "realpath for %s\n", fname));
1152 return map_nt_error_from_unix(errno);
1156 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1159 if (*resolved_name != '/') {
1160 DEBUG(0,("check_reduced_name: realpath doesn't return "
1161 "absolute paths !\n"));
1162 SAFE_FREE(resolved_name);
1163 return NT_STATUS_OBJECT_NAME_INVALID;
1166 allow_widelinks = lp_widelinks(SNUM(conn));
1167 allow_symlinks = lp_symlinks(SNUM(conn));
1169 /* Common widelinks and symlinks checks. */
1170 if (!allow_widelinks || !allow_symlinks) {
1171 const char *conn_rootdir;
1174 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1175 if (conn_rootdir == NULL) {
1176 DEBUG(2, ("check_reduced_name: Could not get "
1178 SAFE_FREE(resolved_name);
1179 return NT_STATUS_ACCESS_DENIED;
1182 rootdir_len = strlen(conn_rootdir);
1183 if (strncmp(conn_rootdir, resolved_name,
1184 rootdir_len) != 0) {
1185 DEBUG(2, ("check_reduced_name: Bad access "
1186 "attempt: %s is a symlink outside the "
1187 "share path\n", fname));
1188 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1189 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1190 SAFE_FREE(resolved_name);
1191 return NT_STATUS_ACCESS_DENIED;
1194 /* Extra checks if all symlinks are disallowed. */
1195 if (!allow_symlinks) {
1196 /* fname can't have changed in resolved_path. */
1197 const char *p = &resolved_name[rootdir_len];
1199 /* *p can be '\0' if fname was "." */
1200 if (*p == '\0' && ISDOT(fname)) {
1205 DEBUG(2, ("check_reduced_name: logic error (%c) "
1206 "in resolved_name: %s\n",
1209 SAFE_FREE(resolved_name);
1210 return NT_STATUS_ACCESS_DENIED;
1214 if (strcmp(fname, p)!=0) {
1215 DEBUG(2, ("check_reduced_name: Bad access "
1216 "attempt: %s is a symlink to %s\n",
1218 SAFE_FREE(resolved_name);
1219 return NT_STATUS_ACCESS_DENIED;
1226 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1228 SAFE_FREE(resolved_name);
1229 return NT_STATUS_OK;
1233 * XXX: This is temporary and there should be no callers of this once
1234 * smb_filename is plumbed through all path based operations.
1236 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1237 SMB_STRUCT_STAT *psbuf)
1239 struct smb_filename *smb_fname = NULL;
1243 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1245 if (!NT_STATUS_IS_OK(status)) {
1246 errno = map_errno_from_nt_status(status);
1250 if (lp_posix_pathnames()) {
1251 ret = SMB_VFS_LSTAT(conn, smb_fname);
1253 ret = SMB_VFS_STAT(conn, smb_fname);
1257 *psbuf = smb_fname->st;
1260 TALLOC_FREE(smb_fname);
1265 * XXX: This is temporary and there should be no callers of this once
1266 * smb_filename is plumbed through all path based operations.
1268 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1269 SMB_STRUCT_STAT *psbuf)
1271 struct smb_filename *smb_fname = NULL;
1275 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1277 if (!NT_STATUS_IS_OK(status)) {
1278 errno = map_errno_from_nt_status(status);
1282 ret = SMB_VFS_LSTAT(conn, smb_fname);
1284 *psbuf = smb_fname->st;
1287 TALLOC_FREE(smb_fname);
1292 * Ensure LSTAT is called for POSIX paths.
1295 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1299 if(fsp->fh->fd == -1) {
1300 if (fsp->posix_open) {
1301 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1303 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1306 return map_nt_error_from_unix(errno);
1309 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1310 return map_nt_error_from_unix(errno);
1313 return NT_STATUS_OK;
1317 * Initialize num_streams and streams, then call VFS op streaminfo
1319 NTSTATUS vfs_streaminfo(connection_struct *conn,
1320 struct files_struct *fsp,
1322 TALLOC_CTX *mem_ctx,
1323 unsigned int *num_streams,
1324 struct stream_struct **streams)
1328 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1332 generate a file_id from a stat structure
1334 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1336 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1339 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1340 const char *service, const char *user)
1343 return handle->fns->connect_fn(handle, service, user);
1346 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1348 VFS_FIND(disconnect);
1349 handle->fns->disconnect_fn(handle);
1352 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1353 const char *path, bool small_query,
1354 uint64_t *bsize, uint64_t *dfree,
1357 VFS_FIND(disk_free);
1358 return handle->fns->disk_free_fn(handle, path, small_query, bsize,
1362 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1363 enum SMB_QUOTA_TYPE qtype, unid_t id,
1366 VFS_FIND(get_quota);
1367 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1370 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1371 enum SMB_QUOTA_TYPE qtype, unid_t id,
1374 VFS_FIND(set_quota);
1375 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1378 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1379 struct files_struct *fsp,
1380 struct shadow_copy_data *shadow_copy_data,
1383 VFS_FIND(get_shadow_copy_data);
1384 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1388 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1389 struct vfs_statvfs_struct *statbuf)
1392 return handle->fns->statvfs_fn(handle, path, statbuf);
1395 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1396 enum timestamp_set_resolution *p_ts_res)
1398 VFS_FIND(fs_capabilities);
1399 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1402 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1403 struct dfs_GetDFSReferral *r)
1405 VFS_FIND(get_dfs_referrals);
1406 return handle->fns->get_dfs_referrals_fn(handle, r);
1409 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1410 const char *fname, const char *mask,
1414 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1417 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1418 struct files_struct *fsp,
1422 VFS_FIND(fdopendir);
1423 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1426 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1428 SMB_STRUCT_STAT *sbuf)
1431 return handle->fns->readdir_fn(handle, dirp, sbuf);
1434 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1435 DIR *dirp, long offset)
1438 handle->fns->seekdir_fn(handle, dirp, offset);
1441 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1445 return handle->fns->telldir_fn(handle, dirp);
1448 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1451 VFS_FIND(rewind_dir);
1452 handle->fns->rewind_dir_fn(handle, dirp);
1455 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1459 return handle->fns->mkdir_fn(handle, path, mode);
1462 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1465 return handle->fns->rmdir_fn(handle, path);
1468 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1472 return handle->fns->closedir_fn(handle, dir);
1475 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1478 VFS_FIND(init_search_op);
1479 handle->fns->init_search_op_fn(handle, dirp);
1482 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1483 struct smb_filename *smb_fname, struct files_struct *fsp,
1484 int flags, mode_t mode)
1487 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1490 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1491 struct smb_request *req,
1492 uint16_t root_dir_fid,
1493 struct smb_filename *smb_fname,
1494 uint32_t access_mask,
1495 uint32_t share_access,
1496 uint32_t create_disposition,
1497 uint32_t create_options,
1498 uint32_t file_attributes,
1499 uint32_t oplock_request,
1500 uint64_t allocation_size,
1501 uint32_t private_flags,
1502 struct security_descriptor *sd,
1503 struct ea_list *ea_list,
1504 files_struct **result,
1507 VFS_FIND(create_file);
1508 return handle->fns->create_file_fn(
1509 handle, req, root_dir_fid, smb_fname, access_mask,
1510 share_access, create_disposition, create_options,
1511 file_attributes, oplock_request, allocation_size,
1512 private_flags, sd, ea_list,
1516 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1517 struct files_struct *fsp)
1520 return handle->fns->close_fn(handle, fsp);
1523 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1524 struct files_struct *fsp, void *data, size_t n)
1527 return handle->fns->read_fn(handle, fsp, data, n);
1530 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1531 struct files_struct *fsp, void *data, size_t n,
1535 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1538 struct smb_vfs_call_pread_state {
1539 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1543 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1545 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1546 TALLOC_CTX *mem_ctx,
1547 struct tevent_context *ev,
1548 struct files_struct *fsp,
1550 size_t n, off_t offset)
1552 struct tevent_req *req, *subreq;
1553 struct smb_vfs_call_pread_state *state;
1555 req = tevent_req_create(mem_ctx, &state,
1556 struct smb_vfs_call_pread_state);
1560 VFS_FIND(pread_send);
1561 state->recv_fn = handle->fns->pread_recv_fn;
1563 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1565 if (tevent_req_nomem(subreq, req)) {
1566 return tevent_req_post(req, ev);
1568 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1572 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1574 struct tevent_req *req = tevent_req_callback_data(
1575 subreq, struct tevent_req);
1576 struct smb_vfs_call_pread_state *state = tevent_req_data(
1577 req, struct smb_vfs_call_pread_state);
1580 state->retval = state->recv_fn(subreq, &err);
1581 TALLOC_FREE(subreq);
1582 if (state->retval == -1) {
1583 tevent_req_error(req, err);
1586 tevent_req_done(req);
1589 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req, int *perrno)
1591 struct smb_vfs_call_pread_state *state = tevent_req_data(
1592 req, struct smb_vfs_call_pread_state);
1595 if (tevent_req_is_unix_error(req, &err)) {
1599 return state->retval;
1602 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1603 struct files_struct *fsp, const void *data,
1607 return handle->fns->write_fn(handle, fsp, data, n);
1610 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1611 struct files_struct *fsp, const void *data,
1612 size_t n, off_t offset)
1615 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1618 struct smb_vfs_call_pwrite_state {
1619 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1623 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1625 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1626 TALLOC_CTX *mem_ctx,
1627 struct tevent_context *ev,
1628 struct files_struct *fsp,
1630 size_t n, off_t offset)
1632 struct tevent_req *req, *subreq;
1633 struct smb_vfs_call_pwrite_state *state;
1635 req = tevent_req_create(mem_ctx, &state,
1636 struct smb_vfs_call_pwrite_state);
1640 VFS_FIND(pwrite_send);
1641 state->recv_fn = handle->fns->pwrite_recv_fn;
1643 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1645 if (tevent_req_nomem(subreq, req)) {
1646 return tevent_req_post(req, ev);
1648 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1652 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1654 struct tevent_req *req = tevent_req_callback_data(
1655 subreq, struct tevent_req);
1656 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1657 req, struct smb_vfs_call_pwrite_state);
1660 state->retval = state->recv_fn(subreq, &err);
1661 TALLOC_FREE(subreq);
1662 if (state->retval == -1) {
1663 tevent_req_error(req, err);
1666 tevent_req_done(req);
1669 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req, int *perrno)
1671 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1672 req, struct smb_vfs_call_pwrite_state);
1675 if (tevent_req_is_unix_error(req, &err)) {
1679 return state->retval;
1682 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1683 struct files_struct *fsp, off_t offset,
1687 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1690 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1691 files_struct *fromfsp, const DATA_BLOB *header,
1692 off_t offset, size_t count)
1695 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1699 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1700 files_struct *tofsp, off_t offset,
1704 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1707 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1708 const struct smb_filename *smb_fname_src,
1709 const struct smb_filename *smb_fname_dst)
1712 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1715 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1716 struct files_struct *fsp)
1719 return handle->fns->fsync_fn(handle, fsp);
1722 struct smb_vfs_call_fsync_state {
1723 int (*recv_fn)(struct tevent_req *req, int *err);
1727 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1729 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1730 TALLOC_CTX *mem_ctx,
1731 struct tevent_context *ev,
1732 struct files_struct *fsp)
1734 struct tevent_req *req, *subreq;
1735 struct smb_vfs_call_fsync_state *state;
1737 req = tevent_req_create(mem_ctx, &state,
1738 struct smb_vfs_call_fsync_state);
1742 VFS_FIND(fsync_send);
1743 state->recv_fn = handle->fns->fsync_recv_fn;
1745 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1746 if (tevent_req_nomem(subreq, req)) {
1747 return tevent_req_post(req, ev);
1749 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1753 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1755 struct tevent_req *req = tevent_req_callback_data(
1756 subreq, struct tevent_req);
1757 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1758 req, struct smb_vfs_call_fsync_state);
1761 state->retval = state->recv_fn(subreq, &err);
1762 TALLOC_FREE(subreq);
1763 if (state->retval == -1) {
1764 tevent_req_error(req, err);
1767 tevent_req_done(req);
1770 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, int *perrno)
1772 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1773 req, struct smb_vfs_call_fsync_state);
1776 if (tevent_req_is_unix_error(req, &err)) {
1780 return state->retval;
1784 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1785 struct smb_filename *smb_fname)
1788 return handle->fns->stat_fn(handle, smb_fname);
1791 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1792 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1795 return handle->fns->fstat_fn(handle, fsp, sbuf);
1798 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1799 struct smb_filename *smb_filename)
1802 return handle->fns->lstat_fn(handle, smb_filename);
1805 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1806 struct files_struct *fsp,
1807 const SMB_STRUCT_STAT *sbuf)
1809 VFS_FIND(get_alloc_size);
1810 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1813 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1814 const struct smb_filename *smb_fname)
1817 return handle->fns->unlink_fn(handle, smb_fname);
1820 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1824 return handle->fns->chmod_fn(handle, path, mode);
1827 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1828 struct files_struct *fsp, mode_t mode)
1831 return handle->fns->fchmod_fn(handle, fsp, mode);
1834 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1835 uid_t uid, gid_t gid)
1838 return handle->fns->chown_fn(handle, path, uid, gid);
1841 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1842 struct files_struct *fsp, uid_t uid, gid_t gid)
1845 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1848 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1849 uid_t uid, gid_t gid)
1852 return handle->fns->lchown_fn(handle, path, uid, gid);
1855 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1858 bool as_root = false;
1860 char *saved_dir = NULL;
1861 char *parent_dir = NULL;
1864 if (fsp->fh->fd != -1) {
1866 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1868 return NT_STATUS_OK;
1870 if (ret == -1 && errno != ENOSYS) {
1871 return map_nt_error_from_unix(errno);
1875 as_root = (geteuid() == 0);
1879 * We are being asked to chown as root. Make
1880 * sure we chdir() into the path to pin it,
1881 * and always act using lchown to ensure we
1882 * don't deref any symbolic links.
1884 const char *final_component = NULL;
1885 struct smb_filename local_fname;
1887 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1889 status = map_nt_error_from_unix(errno);
1890 DEBUG(0,("vfs_chown_fsp: failed to get "
1891 "current working directory. Error was %s\n",
1896 if (!parent_dirname(talloc_tos(),
1897 fsp->fsp_name->base_name,
1899 &final_component)) {
1900 return NT_STATUS_NO_MEMORY;
1903 /* cd into the parent dir to pin it. */
1904 ret = vfs_ChDir(fsp->conn, parent_dir);
1906 return map_nt_error_from_unix(errno);
1909 ZERO_STRUCT(local_fname);
1910 local_fname.base_name = discard_const_p(char, final_component);
1912 /* Must use lstat here. */
1913 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1915 status = map_nt_error_from_unix(errno);
1919 /* Ensure it matches the fsp stat. */
1920 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1921 status = NT_STATUS_ACCESS_DENIED;
1924 path = final_component;
1926 path = fsp->fsp_name->base_name;
1929 if (fsp->posix_open || as_root) {
1930 ret = SMB_VFS_LCHOWN(fsp->conn,
1934 ret = SMB_VFS_CHOWN(fsp->conn,
1940 status = NT_STATUS_OK;
1942 status = map_nt_error_from_unix(errno);
1948 vfs_ChDir(fsp->conn,saved_dir);
1949 TALLOC_FREE(saved_dir);
1950 TALLOC_FREE(parent_dir);
1955 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1958 return handle->fns->chdir_fn(handle, path);
1961 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
1964 return handle->fns->getwd_fn(handle);
1967 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
1968 const struct smb_filename *smb_fname,
1969 struct smb_file_time *ft)
1972 return handle->fns->ntimes_fn(handle, smb_fname, ft);
1975 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
1976 struct files_struct *fsp, off_t offset)
1978 VFS_FIND(ftruncate);
1979 return handle->fns->ftruncate_fn(handle, fsp, offset);
1982 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
1983 struct files_struct *fsp,
1984 enum vfs_fallocate_mode mode,
1988 VFS_FIND(fallocate);
1989 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
1992 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
1993 struct files_struct *fsp, uint32 share_mode,
1994 uint32_t access_mask)
1996 VFS_FIND(kernel_flock);
1997 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2001 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2002 struct files_struct *fsp, int leasetype)
2004 VFS_FIND(linux_setlease);
2005 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2008 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
2009 const char *newpath)
2012 return handle->fns->symlink_fn(handle, oldpath, newpath);
2015 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2016 const char *path, char *buf, size_t bufsiz)
2019 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
2022 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
2023 const char *newpath)
2026 return handle->fns->link_fn(handle, oldpath, newpath);
2029 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
2030 mode_t mode, SMB_DEV_T dev)
2033 return handle->fns->mknod_fn(handle, path, mode, dev);
2036 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
2039 return handle->fns->realpath_fn(handle, path);
2042 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
2043 struct sys_notify_context *ctx,
2046 uint32_t *subdir_filter,
2047 void (*callback)(struct sys_notify_context *ctx,
2049 struct notify_event *ev),
2050 void *private_data, void *handle_p)
2052 VFS_FIND(notify_watch);
2053 return handle->fns->notify_watch_fn(handle, ctx, path,
2054 filter, subdir_filter, callback,
2055 private_data, handle_p);
2058 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
2062 return handle->fns->chflags_fn(handle, path, flags);
2065 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2066 const SMB_STRUCT_STAT *sbuf)
2068 VFS_FIND(file_id_create);
2069 return handle->fns->file_id_create_fn(handle, sbuf);
2072 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2073 struct files_struct *fsp,
2075 TALLOC_CTX *mem_ctx,
2076 unsigned int *num_streams,
2077 struct stream_struct **streams)
2079 VFS_FIND(streaminfo);
2080 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
2081 num_streams, streams);
2084 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2085 const char *path, const char *name,
2086 TALLOC_CTX *mem_ctx, char **found_name)
2088 VFS_FIND(get_real_filename);
2089 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2093 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2094 const char *filename)
2096 VFS_FIND(connectpath);
2097 return handle->fns->connectpath_fn(handle, filename);
2100 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2101 struct files_struct *fsp,
2102 struct lock_struct *plock)
2104 VFS_FIND(strict_lock);
2105 return handle->fns->strict_lock_fn(handle, fsp, plock);
2108 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2109 struct files_struct *fsp,
2110 struct lock_struct *plock)
2112 VFS_FIND(strict_unlock);
2113 handle->fns->strict_unlock_fn(handle, fsp, plock);
2116 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2118 enum vfs_translate_direction direction,
2119 TALLOC_CTX *mem_ctx,
2122 VFS_FIND(translate_name);
2123 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2127 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2128 struct files_struct *fsp,
2132 const uint8_t *in_data,
2135 uint32_t max_out_len,
2139 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2140 in_data, in_len, out_data, max_out_len,
2144 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2145 struct files_struct *fsp,
2146 uint32 security_info,
2147 struct security_descriptor **ppdesc)
2149 VFS_FIND(fget_nt_acl);
2150 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2154 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2156 uint32 security_info,
2157 struct security_descriptor **ppdesc)
2159 VFS_FIND(get_nt_acl);
2160 return handle->fns->get_nt_acl_fn(handle, name, security_info, ppdesc);
2163 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2164 struct files_struct *fsp,
2165 uint32 security_info_sent,
2166 const struct security_descriptor *psd)
2168 VFS_FIND(fset_nt_acl);
2169 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2173 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2174 struct smb_filename *file,
2175 struct security_acl *sacl,
2176 uint32_t access_requested,
2177 uint32_t access_denied)
2179 VFS_FIND(audit_file);
2180 return handle->fns->audit_file_fn(handle,
2187 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2190 VFS_FIND(chmod_acl);
2191 return handle->fns->chmod_acl_fn(handle, name, mode);
2194 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2195 struct files_struct *fsp, mode_t mode)
2197 VFS_FIND(fchmod_acl);
2198 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2201 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2203 SMB_ACL_TYPE_T type)
2205 VFS_FIND(sys_acl_get_file);
2206 return handle->fns->sys_acl_get_file_fn(handle, path_p, type);
2209 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2210 struct files_struct *fsp)
2212 VFS_FIND(sys_acl_get_fd);
2213 return handle->fns->sys_acl_get_fd_fn(handle, fsp);
2216 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2218 SMB_ACL_TYPE_T type,
2219 TALLOC_CTX *mem_ctx,
2220 char **blob_description,
2223 VFS_FIND(sys_acl_blob_get_file);
2224 return handle->fns->sys_acl_blob_get_file_fn(handle, path_p, type, mem_ctx, blob_description, blob);
2227 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2228 struct files_struct *fsp,
2229 TALLOC_CTX *mem_ctx,
2230 char **blob_description,
2233 VFS_FIND(sys_acl_blob_get_fd);
2234 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2237 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2238 const char *name, SMB_ACL_TYPE_T acltype,
2241 VFS_FIND(sys_acl_set_file);
2242 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2245 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2246 struct files_struct *fsp, SMB_ACL_T theacl)
2248 VFS_FIND(sys_acl_set_fd);
2249 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2252 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2255 VFS_FIND(sys_acl_delete_def_file);
2256 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2259 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2260 const char *path, const char *name, void *value,
2264 return handle->fns->getxattr_fn(handle, path, name, value, size);
2267 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2268 struct files_struct *fsp, const char *name,
2269 void *value, size_t size)
2271 VFS_FIND(fgetxattr);
2272 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2275 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2276 const char *path, char *list, size_t size)
2278 VFS_FIND(listxattr);
2279 return handle->fns->listxattr_fn(handle, path, list, size);
2282 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2283 struct files_struct *fsp, char *list,
2286 VFS_FIND(flistxattr);
2287 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2290 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2291 const char *path, const char *name)
2293 VFS_FIND(removexattr);
2294 return handle->fns->removexattr_fn(handle, path, name);
2297 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2298 struct files_struct *fsp, const char *name)
2300 VFS_FIND(fremovexattr);
2301 return handle->fns->fremovexattr_fn(handle, fsp, name);
2304 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2305 const char *name, const void *value, size_t size,
2309 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2312 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2313 struct files_struct *fsp, const char *name,
2314 const void *value, size_t size, int flags)
2316 VFS_FIND(fsetxattr);
2317 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2320 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2321 struct files_struct *fsp)
2323 VFS_FIND(aio_force);
2324 return handle->fns->aio_force_fn(handle, fsp);
2327 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2328 const struct smb_filename *fname,
2329 SMB_STRUCT_STAT *sbuf)
2331 VFS_FIND(is_offline);
2332 return handle->fns->is_offline_fn(handle, fname, sbuf);
2335 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2336 const struct smb_filename *fname)
2338 VFS_FIND(set_offline);
2339 return handle->fns->set_offline_fn(handle, fname);
2342 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2343 struct files_struct *fsp,
2344 TALLOC_CTX *mem_ctx,
2347 VFS_FIND(durable_cookie);
2348 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2351 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2352 struct files_struct *fsp,
2353 const DATA_BLOB old_cookie,
2354 TALLOC_CTX *mem_ctx,
2355 DATA_BLOB *new_cookie)
2357 VFS_FIND(durable_disconnect);
2358 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2359 mem_ctx, new_cookie);
2362 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2363 struct smb_request *smb1req,
2364 struct smbXsrv_open *op,
2365 const DATA_BLOB old_cookie,
2366 TALLOC_CTX *mem_ctx,
2367 struct files_struct **fsp,
2368 DATA_BLOB *new_cookie)
2370 VFS_FIND(durable_reconnect);
2371 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2372 old_cookie, mem_ctx, fsp,