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"
30 #include "../lib/util/memcache.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_t *)(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 /****************************************************************************
397 Write data to a fd on the vfs.
398 ****************************************************************************/
400 ssize_t vfs_write_data(struct smb_request *req,
408 if (req && req->unread_bytes) {
409 int sockfd = req->xconn->transport.sock;
411 SMB_ASSERT(req->unread_bytes == N);
412 /* VFS_RECVFILE must drain the socket
413 * before returning. */
414 req->unread_bytes = 0;
415 /* Ensure the socket is blocking. */
416 old_flags = fcntl(sockfd, F_GETFL, 0);
417 if (set_blocking(sockfd, true) == -1) {
420 ret = SMB_VFS_RECVFILE(sockfd,
424 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
431 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
440 return (ssize_t)total;
443 ssize_t vfs_pwrite_data(struct smb_request *req,
452 if (req && req->unread_bytes) {
453 int sockfd = req->xconn->transport.sock;
454 SMB_ASSERT(req->unread_bytes == N);
455 /* VFS_RECVFILE must drain the socket
456 * before returning. */
457 req->unread_bytes = 0;
459 * Leave the socket non-blocking and
460 * use SMB_VFS_RECVFILE. If it returns
461 * EAGAIN || EWOULDBLOCK temporarily set
462 * the socket blocking and retry
466 ret = SMB_VFS_RECVFILE(sockfd,
470 if (ret == 0 || (ret == -1 &&
472 errno == EWOULDBLOCK))) {
474 /* Ensure the socket is blocking. */
475 old_flags = fcntl(sockfd, F_GETFL, 0);
476 if (set_blocking(sockfd, true) == -1) {
479 ret = SMB_VFS_RECVFILE(sockfd,
483 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
490 return (ssize_t)total;
492 /* Any other error case. */
498 return (ssize_t)total;
502 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
512 return (ssize_t)total;
514 /****************************************************************************
515 An allocate file space call using the vfs interface.
516 Allocates space for a file from a filedescriptor.
517 Returns 0 on success, -1 on failure.
518 ****************************************************************************/
520 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
523 connection_struct *conn = fsp->conn;
524 uint64_t space_avail;
525 uint64_t bsize,dfree,dsize;
529 * Actually try and commit the space on disk....
532 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
533 fsp_str_dbg(fsp), (double)len));
535 if (((off_t)len) < 0) {
536 DEBUG(0,("vfs_allocate_file_space: %s negative len "
537 "requested.\n", fsp_str_dbg(fsp)));
542 status = vfs_stat_fsp(fsp);
543 if (!NT_STATUS_IS_OK(status)) {
547 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
550 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
551 /* Shrink - use ftruncate. */
553 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
554 "size %.0f\n", fsp_str_dbg(fsp),
555 (double)fsp->fsp_name->st.st_ex_size));
557 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
559 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
560 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
561 set_filelen_write_cache(fsp, len);
564 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
569 /* Grow - we need to test if we have enough space. */
571 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
573 if (lp_strict_allocate(SNUM(fsp->conn))) {
574 /* See if we have a syscall that will allocate beyond
575 end-of-file without changing EOF. */
576 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_FL_KEEP_SIZE,
582 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
585 /* We changed the allocation size on disk, but not
586 EOF - exactly as required. We're done ! */
590 if (ret == -1 && errno == ENOSPC) {
594 len -= fsp->fsp_name->st.st_ex_size;
595 len /= 1024; /* Len is now number of 1k blocks needed. */
596 space_avail = get_dfree_info(conn, fsp->fsp_name->base_name,
597 &bsize, &dfree, &dsize);
598 if (space_avail == (uint64_t)-1) {
602 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
603 "needed blocks = %.0f, space avail = %.0f\n",
604 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
605 (double)space_avail));
607 if (len > space_avail) {
615 /****************************************************************************
616 A vfs set_filelen call.
617 set the length of a file from a filedescriptor.
618 Returns 0 on success, -1 on failure.
619 ****************************************************************************/
621 int vfs_set_filelen(files_struct *fsp, off_t len)
625 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
627 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
628 fsp_str_dbg(fsp), (double)len));
629 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
630 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
631 set_filelen_write_cache(fsp, len);
632 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
633 FILE_NOTIFY_CHANGE_SIZE
634 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
635 fsp->fsp_name->base_name);
638 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
643 /****************************************************************************
644 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
645 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
646 as this is also called from the default SMB_VFS_FTRUNCATE code.
647 Always extends the file size.
648 Returns 0 on success, -1 on failure.
649 ****************************************************************************/
651 #define SPARSE_BUF_WRITE_SIZE (32*1024)
653 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
659 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
666 while (total < len) {
667 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
669 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
670 if (pwrite_ret == -1) {
671 int saved_errno = errno;
672 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
673 "%s failed with error %s\n",
674 fsp_str_dbg(fsp), strerror(saved_errno)));
684 /****************************************************************************
685 A vfs fill sparse call.
686 Writes zeros from the end of file to len, if len is greater than EOF.
687 Used only by strict_sync.
688 Returns 0 on success, -1 on failure.
689 ****************************************************************************/
691 int vfs_fill_sparse(files_struct *fsp, off_t len)
698 status = vfs_stat_fsp(fsp);
699 if (!NT_STATUS_IS_OK(status)) {
703 if (len <= fsp->fsp_name->st.st_ex_size) {
708 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
713 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
714 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
715 (double)fsp->fsp_name->st.st_ex_size, (double)len,
716 (double)(len - fsp->fsp_name->st.st_ex_size)));
718 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
720 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
722 offset = fsp->fsp_name->st.st_ex_size;
723 num_to_write = len - fsp->fsp_name->st.st_ex_size;
725 /* Only do this on non-stream file handles. */
726 if (fsp->base_fsp == NULL) {
727 /* for allocation try fallocate first. This can fail on some
728 * platforms e.g. when the filesystem doesn't support it and no
729 * emulation is being done by the libc (like on AIX with JFS1). In that
730 * case we do our own emulation. fallocate implementations can
731 * return ENOTSUP or EINVAL in cases like that. */
732 ret = SMB_VFS_FALLOCATE(fsp, 0, offset, num_to_write);
733 if (ret == -1 && errno == ENOSPC) {
739 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
740 "error %d. Falling back to slow manual allocation\n", ret));
743 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
748 set_filelen_write_cache(fsp, len);
751 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
755 /****************************************************************************
756 Transfer some data (n bytes) between two file_struct's.
757 ****************************************************************************/
759 static ssize_t vfs_pread_fn(void *file, void *buf, size_t len, off_t offset)
761 struct files_struct *fsp = (struct files_struct *)file;
763 return SMB_VFS_PREAD(fsp, buf, len, offset);
766 static ssize_t vfs_pwrite_fn(void *file, const void *buf, size_t len, off_t offset)
768 struct files_struct *fsp = (struct files_struct *)file;
770 return SMB_VFS_PWRITE(fsp, buf, len, offset);
773 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
775 return transfer_file_internal((void *)in, (void *)out, n,
776 vfs_pread_fn, vfs_pwrite_fn);
779 /*******************************************************************
780 A vfs_readdir wrapper which just returns the file name.
781 ********************************************************************/
783 const char *vfs_readdirname(connection_struct *conn, void *p,
784 SMB_STRUCT_STAT *sbuf, char **talloced)
786 struct dirent *ptr= NULL;
794 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
806 #ifdef HAVE_BROKEN_READDIR_NAME
807 /* using /usr/ucb/cc is BAD */
811 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
812 talloc_tos(), &translated);
813 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
817 *talloced = translated;
818 if (!NT_STATUS_IS_OK(status)) {
824 /*******************************************************************
825 A wrapper for vfs_chdir().
826 ********************************************************************/
828 int vfs_ChDir(connection_struct *conn, const char *path)
833 LastDir = SMB_STRDUP("");
840 if (*path == '/' && strcsequal(LastDir,path)) {
844 DEBUG(4,("vfs_ChDir to %s\n",path));
846 ret = SMB_VFS_CHDIR(conn,path);
850 LastDir = SMB_STRDUP(path);
853 TALLOC_FREE(conn->cwd);
854 conn->cwd = vfs_GetWd(conn, conn);
855 DEBUG(4,("vfs_ChDir got %s\n",conn->cwd));
860 /*******************************************************************
861 Return the absolute current directory path - given a UNIX pathname.
862 Note that this path is returned in DOS format, not UNIX
863 format. Note this can be called with conn == NULL.
864 ********************************************************************/
866 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
868 char *current_dir = NULL;
870 DATA_BLOB cache_value;
872 struct smb_filename *smb_fname_dot = NULL;
873 struct smb_filename *smb_fname_full = NULL;
875 if (!lp_getwd_cache()) {
879 smb_fname_dot = synthetic_smb_fname(ctx, ".", NULL, NULL);
880 if (smb_fname_dot == NULL) {
885 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
887 * Known to fail for root: the directory may be NFS-mounted
888 * and exported with root_squash (so has no root access).
890 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
891 "(NFS problem ?)\n", strerror(errno) ));
895 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
897 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
898 data_blob_const(&key, sizeof(key)),
903 SMB_ASSERT((cache_value.length > 0)
904 && (cache_value.data[cache_value.length-1] == '\0'));
906 smb_fname_full = synthetic_smb_fname(ctx, (char *)cache_value.data,
908 if (smb_fname_full == NULL) {
913 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
914 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
915 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
916 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
920 result = talloc_strdup(ctx, smb_fname_full->base_name);
921 if (result == NULL) {
930 * We don't have the information to hand so rely on traditional
931 * methods. The very slow getcwd, which spawns a process on some
932 * systems, or the not quite so bad getwd.
935 current_dir = SMB_VFS_GETWD(conn);
936 if (current_dir == NULL) {
937 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
942 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
943 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
945 memcache_add(smbd_memcache(), GETWD_CACHE,
946 data_blob_const(&key, sizeof(key)),
947 data_blob_const(current_dir,
948 strlen(current_dir)+1));
951 result = talloc_strdup(ctx, current_dir);
952 if (result == NULL) {
957 TALLOC_FREE(smb_fname_dot);
958 TALLOC_FREE(smb_fname_full);
959 SAFE_FREE(current_dir);
963 /*******************************************************************
964 Reduce a file name, removing .. elements and checking that
965 it is below dir in the heirachy. This uses realpath.
966 This function must run as root, and will return names
967 and valid stat structs that can be checked on open.
968 ********************************************************************/
970 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
972 struct smb_request *smbreq)
975 TALLOC_CTX *ctx = talloc_tos();
976 const char *conn_rootdir;
978 char *dir_name = NULL;
979 const char *last_component = NULL;
980 char *resolved_name = NULL;
981 char *saved_dir = NULL;
982 struct smb_filename *smb_fname_cwd = NULL;
983 struct privilege_paths *priv_paths = NULL;
987 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
992 priv_paths = talloc_zero(smbreq, struct privilege_paths);
994 status = NT_STATUS_NO_MEMORY;
998 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
999 status = NT_STATUS_NO_MEMORY;
1003 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
1004 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
1006 if (priv_paths->parent_name.base_name == NULL ||
1007 priv_paths->file_name.base_name == NULL) {
1008 status = NT_STATUS_NO_MEMORY;
1012 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
1013 status = map_nt_error_from_unix(errno);
1016 /* Remember where we were. */
1017 saved_dir = vfs_GetWd(ctx, conn);
1019 status = map_nt_error_from_unix(errno);
1023 /* Go to the parent directory to lock in memory. */
1024 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
1025 status = map_nt_error_from_unix(errno);
1029 /* Get the absolute path of the parent directory. */
1030 resolved_name = SMB_VFS_REALPATH(conn,".");
1031 if (!resolved_name) {
1032 status = map_nt_error_from_unix(errno);
1036 if (*resolved_name != '/') {
1037 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1038 "doesn't return absolute paths !\n"));
1039 status = NT_STATUS_OBJECT_NAME_INVALID;
1043 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1044 priv_paths->parent_name.base_name,
1047 /* Now check the stat value is the same. */
1048 smb_fname_cwd = synthetic_smb_fname(talloc_tos(), ".", NULL, NULL);
1049 if (smb_fname_cwd == NULL) {
1050 status = NT_STATUS_NO_MEMORY;
1054 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1055 status = map_nt_error_from_unix(errno);
1059 /* Ensure we're pointing at the same place. */
1060 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1061 DEBUG(0,("check_reduced_name_with_privilege: "
1062 "device/inode/uid/gid on directory %s changed. "
1063 "Denying access !\n",
1064 priv_paths->parent_name.base_name));
1065 status = NT_STATUS_ACCESS_DENIED;
1069 /* Ensure we're below the connect path. */
1071 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1072 if (conn_rootdir == NULL) {
1073 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1075 status = NT_STATUS_ACCESS_DENIED;
1079 rootdir_len = strlen(conn_rootdir);
1080 matched = (strncmp(conn_rootdir, resolved_name, rootdir_len) == 0);
1082 if (!matched || (resolved_name[rootdir_len] != '/' &&
1083 resolved_name[rootdir_len] != '\0')) {
1084 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1085 "attempt: %s is a symlink outside the "
1088 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1089 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1090 status = NT_STATUS_ACCESS_DENIED;
1094 /* Now ensure that the last component either doesn't
1095 exist, or is *NOT* a symlink. */
1097 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1099 /* Errno must be ENOENT for this be ok. */
1100 if (errno != ENOENT) {
1101 status = map_nt_error_from_unix(errno);
1102 DEBUG(2, ("check_reduced_name_with_privilege: "
1103 "LSTAT on %s failed with %s\n",
1104 priv_paths->file_name.base_name,
1105 nt_errstr(status)));
1110 if (VALID_STAT(priv_paths->file_name.st) &&
1111 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1112 DEBUG(2, ("check_reduced_name_with_privilege: "
1113 "Last component %s is a symlink. Denying"
1115 priv_paths->file_name.base_name));
1116 status = NT_STATUS_ACCESS_DENIED;
1120 smbreq->priv_paths = priv_paths;
1121 status = NT_STATUS_OK;
1126 vfs_ChDir(conn, saved_dir);
1128 SAFE_FREE(resolved_name);
1129 if (!NT_STATUS_IS_OK(status)) {
1130 TALLOC_FREE(priv_paths);
1132 TALLOC_FREE(dir_name);
1136 /*******************************************************************
1137 Reduce a file name, removing .. elements and checking that
1138 it is below dir in the heirachy. This uses realpath.
1139 ********************************************************************/
1141 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1143 char *resolved_name = NULL;
1144 bool allow_symlinks = true;
1145 bool allow_widelinks = false;
1147 DBG_DEBUG("check_reduced_name [%s] [%s]\n", fname, conn->connectpath);
1149 resolved_name = SMB_VFS_REALPATH(conn,fname);
1151 if (!resolved_name) {
1154 DEBUG(3,("check_reduced_name: Component not a "
1155 "directory in getting realpath for "
1157 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1160 TALLOC_CTX *ctx = talloc_tos();
1161 char *dir_name = NULL;
1162 const char *last_component = NULL;
1163 char *new_name = NULL;
1166 /* Last component didn't exist.
1167 Remove it and try and canonicalise
1168 the directory name. */
1169 if (!parent_dirname(ctx, fname,
1172 return NT_STATUS_NO_MEMORY;
1175 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1176 if (!resolved_name) {
1177 NTSTATUS status = map_nt_error_from_unix(errno);
1179 if (errno == ENOENT || errno == ENOTDIR) {
1180 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1183 DEBUG(3,("check_reduce_name: "
1184 "couldn't get realpath for "
1187 nt_errstr(status)));
1190 ret = asprintf(&new_name, "%s/%s",
1191 resolved_name, last_component);
1192 SAFE_FREE(resolved_name);
1194 return NT_STATUS_NO_MEMORY;
1196 resolved_name = new_name;
1200 DEBUG(3,("check_reduced_name: couldn't get "
1201 "realpath for %s\n", fname));
1202 return map_nt_error_from_unix(errno);
1206 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1209 if (*resolved_name != '/') {
1210 DEBUG(0,("check_reduced_name: realpath doesn't return "
1211 "absolute paths !\n"));
1212 SAFE_FREE(resolved_name);
1213 return NT_STATUS_OBJECT_NAME_INVALID;
1216 allow_widelinks = lp_widelinks(SNUM(conn));
1217 allow_symlinks = lp_follow_symlinks(SNUM(conn));
1219 /* Common widelinks and symlinks checks. */
1220 if (!allow_widelinks || !allow_symlinks) {
1221 const char *conn_rootdir;
1225 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1226 if (conn_rootdir == NULL) {
1227 DEBUG(2, ("check_reduced_name: Could not get "
1229 SAFE_FREE(resolved_name);
1230 return NT_STATUS_ACCESS_DENIED;
1233 rootdir_len = strlen(conn_rootdir);
1234 matched = (strncmp(conn_rootdir, resolved_name,
1236 if (!matched || (resolved_name[rootdir_len] != '/' &&
1237 resolved_name[rootdir_len] != '\0')) {
1238 DEBUG(2, ("check_reduced_name: Bad access "
1239 "attempt: %s is a symlink outside the "
1240 "share path\n", fname));
1241 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1242 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1243 SAFE_FREE(resolved_name);
1244 return NT_STATUS_ACCESS_DENIED;
1247 /* Extra checks if all symlinks are disallowed. */
1248 if (!allow_symlinks) {
1249 /* fname can't have changed in resolved_path. */
1250 const char *p = &resolved_name[rootdir_len];
1252 /* *p can be '\0' if fname was "." */
1253 if (*p == '\0' && ISDOT(fname)) {
1258 DEBUG(2, ("check_reduced_name: logic error (%c) "
1259 "in resolved_name: %s\n",
1262 SAFE_FREE(resolved_name);
1263 return NT_STATUS_ACCESS_DENIED;
1267 if (strcmp(fname, p)!=0) {
1268 DEBUG(2, ("check_reduced_name: Bad access "
1269 "attempt: %s is a symlink to %s\n",
1271 SAFE_FREE(resolved_name);
1272 return NT_STATUS_ACCESS_DENIED;
1279 DBG_INFO("%s reduced to %s\n", fname, resolved_name);
1280 SAFE_FREE(resolved_name);
1281 return NT_STATUS_OK;
1285 * XXX: This is temporary and there should be no callers of this once
1286 * smb_filename is plumbed through all path based operations.
1288 * Called when we know stream name parsing has already been done.
1290 int vfs_stat_smb_basename(struct connection_struct *conn, const char *fname,
1291 SMB_STRUCT_STAT *psbuf)
1293 struct smb_filename smb_fname = {
1294 .base_name = discard_const_p(char, fname)
1298 if (lp_posix_pathnames()) {
1299 ret = SMB_VFS_LSTAT(conn, &smb_fname);
1301 ret = SMB_VFS_STAT(conn, &smb_fname);
1305 *psbuf = smb_fname.st;
1311 * Ensure LSTAT is called for POSIX paths.
1314 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1318 if(fsp->fh->fd == -1) {
1319 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1320 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1322 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1325 return map_nt_error_from_unix(errno);
1328 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1329 return map_nt_error_from_unix(errno);
1332 return NT_STATUS_OK;
1336 * Initialize num_streams and streams, then call VFS op streaminfo
1338 NTSTATUS vfs_streaminfo(connection_struct *conn,
1339 struct files_struct *fsp,
1341 TALLOC_CTX *mem_ctx,
1342 unsigned int *num_streams,
1343 struct stream_struct **streams)
1347 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1351 generate a file_id from a stat structure
1353 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1355 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1358 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1359 const char *service, const char *user)
1362 return handle->fns->connect_fn(handle, service, user);
1365 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1367 VFS_FIND(disconnect);
1368 handle->fns->disconnect_fn(handle);
1371 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1372 const char *path, uint64_t *bsize,
1373 uint64_t *dfree, uint64_t *dsize)
1375 VFS_FIND(disk_free);
1376 return handle->fns->disk_free_fn(handle, path, bsize, dfree, dsize);
1379 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1380 enum SMB_QUOTA_TYPE qtype, unid_t id,
1383 VFS_FIND(get_quota);
1384 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1387 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1388 enum SMB_QUOTA_TYPE qtype, unid_t id,
1391 VFS_FIND(set_quota);
1392 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1395 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1396 struct files_struct *fsp,
1397 struct shadow_copy_data *shadow_copy_data,
1400 VFS_FIND(get_shadow_copy_data);
1401 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1405 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1406 struct vfs_statvfs_struct *statbuf)
1409 return handle->fns->statvfs_fn(handle, path, statbuf);
1412 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1413 enum timestamp_set_resolution *p_ts_res)
1415 VFS_FIND(fs_capabilities);
1416 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1419 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1420 struct dfs_GetDFSReferral *r)
1422 VFS_FIND(get_dfs_referrals);
1423 return handle->fns->get_dfs_referrals_fn(handle, r);
1426 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1427 const char *fname, const char *mask,
1428 uint32_t attributes)
1431 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1434 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1435 struct files_struct *fsp,
1437 uint32_t attributes)
1439 VFS_FIND(fdopendir);
1440 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1443 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1445 SMB_STRUCT_STAT *sbuf)
1448 return handle->fns->readdir_fn(handle, dirp, sbuf);
1451 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1452 DIR *dirp, long offset)
1455 handle->fns->seekdir_fn(handle, dirp, offset);
1458 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1462 return handle->fns->telldir_fn(handle, dirp);
1465 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1468 VFS_FIND(rewind_dir);
1469 handle->fns->rewind_dir_fn(handle, dirp);
1472 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1476 return handle->fns->mkdir_fn(handle, path, mode);
1479 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1482 return handle->fns->rmdir_fn(handle, path);
1485 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1489 return handle->fns->closedir_fn(handle, dir);
1492 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1495 VFS_FIND(init_search_op);
1496 handle->fns->init_search_op_fn(handle, dirp);
1499 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1500 struct smb_filename *smb_fname, struct files_struct *fsp,
1501 int flags, mode_t mode)
1504 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1507 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1508 struct smb_request *req,
1509 uint16_t root_dir_fid,
1510 struct smb_filename *smb_fname,
1511 uint32_t access_mask,
1512 uint32_t share_access,
1513 uint32_t create_disposition,
1514 uint32_t create_options,
1515 uint32_t file_attributes,
1516 uint32_t oplock_request,
1517 struct smb2_lease *lease,
1518 uint64_t allocation_size,
1519 uint32_t private_flags,
1520 struct security_descriptor *sd,
1521 struct ea_list *ea_list,
1522 files_struct **result,
1524 const struct smb2_create_blobs *in_context_blobs,
1525 struct smb2_create_blobs *out_context_blobs)
1527 VFS_FIND(create_file);
1528 return handle->fns->create_file_fn(
1529 handle, req, root_dir_fid, smb_fname, access_mask,
1530 share_access, create_disposition, create_options,
1531 file_attributes, oplock_request, lease, allocation_size,
1532 private_flags, sd, ea_list,
1533 result, pinfo, in_context_blobs, out_context_blobs);
1536 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1537 struct files_struct *fsp)
1540 return handle->fns->close_fn(handle, fsp);
1543 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1544 struct files_struct *fsp, void *data, size_t n)
1547 return handle->fns->read_fn(handle, fsp, data, n);
1550 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1551 struct files_struct *fsp, void *data, size_t n,
1555 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1558 struct smb_vfs_call_pread_state {
1559 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1563 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1565 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1566 TALLOC_CTX *mem_ctx,
1567 struct tevent_context *ev,
1568 struct files_struct *fsp,
1570 size_t n, off_t offset)
1572 struct tevent_req *req, *subreq;
1573 struct smb_vfs_call_pread_state *state;
1575 req = tevent_req_create(mem_ctx, &state,
1576 struct smb_vfs_call_pread_state);
1580 VFS_FIND(pread_send);
1581 state->recv_fn = handle->fns->pread_recv_fn;
1583 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1585 if (tevent_req_nomem(subreq, req)) {
1586 return tevent_req_post(req, ev);
1588 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1592 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1594 struct tevent_req *req = tevent_req_callback_data(
1595 subreq, struct tevent_req);
1596 struct smb_vfs_call_pread_state *state = tevent_req_data(
1597 req, struct smb_vfs_call_pread_state);
1600 state->retval = state->recv_fn(subreq, &err);
1601 TALLOC_FREE(subreq);
1602 if (state->retval == -1) {
1603 tevent_req_error(req, err);
1606 tevent_req_done(req);
1609 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req, int *perrno)
1611 struct smb_vfs_call_pread_state *state = tevent_req_data(
1612 req, struct smb_vfs_call_pread_state);
1615 if (tevent_req_is_unix_error(req, &err)) {
1619 return state->retval;
1622 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1623 struct files_struct *fsp, const void *data,
1627 return handle->fns->write_fn(handle, fsp, data, n);
1630 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1631 struct files_struct *fsp, const void *data,
1632 size_t n, off_t offset)
1635 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1638 struct smb_vfs_call_pwrite_state {
1639 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1643 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1645 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1646 TALLOC_CTX *mem_ctx,
1647 struct tevent_context *ev,
1648 struct files_struct *fsp,
1650 size_t n, off_t offset)
1652 struct tevent_req *req, *subreq;
1653 struct smb_vfs_call_pwrite_state *state;
1655 req = tevent_req_create(mem_ctx, &state,
1656 struct smb_vfs_call_pwrite_state);
1660 VFS_FIND(pwrite_send);
1661 state->recv_fn = handle->fns->pwrite_recv_fn;
1663 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1665 if (tevent_req_nomem(subreq, req)) {
1666 return tevent_req_post(req, ev);
1668 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1672 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1674 struct tevent_req *req = tevent_req_callback_data(
1675 subreq, struct tevent_req);
1676 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1677 req, struct smb_vfs_call_pwrite_state);
1680 state->retval = state->recv_fn(subreq, &err);
1681 TALLOC_FREE(subreq);
1682 if (state->retval == -1) {
1683 tevent_req_error(req, err);
1686 tevent_req_done(req);
1689 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req, int *perrno)
1691 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1692 req, struct smb_vfs_call_pwrite_state);
1695 if (tevent_req_is_unix_error(req, &err)) {
1699 return state->retval;
1702 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1703 struct files_struct *fsp, off_t offset,
1707 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1710 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1711 files_struct *fromfsp, const DATA_BLOB *header,
1712 off_t offset, size_t count)
1715 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1719 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1720 files_struct *tofsp, off_t offset,
1724 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1727 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1728 const struct smb_filename *smb_fname_src,
1729 const struct smb_filename *smb_fname_dst)
1732 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1735 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1736 struct files_struct *fsp)
1739 return handle->fns->fsync_fn(handle, fsp);
1742 struct smb_vfs_call_fsync_state {
1743 int (*recv_fn)(struct tevent_req *req, int *err);
1747 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1749 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1750 TALLOC_CTX *mem_ctx,
1751 struct tevent_context *ev,
1752 struct files_struct *fsp)
1754 struct tevent_req *req, *subreq;
1755 struct smb_vfs_call_fsync_state *state;
1757 req = tevent_req_create(mem_ctx, &state,
1758 struct smb_vfs_call_fsync_state);
1762 VFS_FIND(fsync_send);
1763 state->recv_fn = handle->fns->fsync_recv_fn;
1765 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1766 if (tevent_req_nomem(subreq, req)) {
1767 return tevent_req_post(req, ev);
1769 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1773 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1775 struct tevent_req *req = tevent_req_callback_data(
1776 subreq, struct tevent_req);
1777 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1778 req, struct smb_vfs_call_fsync_state);
1781 state->retval = state->recv_fn(subreq, &err);
1782 TALLOC_FREE(subreq);
1783 if (state->retval == -1) {
1784 tevent_req_error(req, err);
1787 tevent_req_done(req);
1790 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, int *perrno)
1792 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1793 req, struct smb_vfs_call_fsync_state);
1796 if (tevent_req_is_unix_error(req, &err)) {
1800 return state->retval;
1804 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1805 struct smb_filename *smb_fname)
1808 return handle->fns->stat_fn(handle, smb_fname);
1811 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1812 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1815 return handle->fns->fstat_fn(handle, fsp, sbuf);
1818 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1819 struct smb_filename *smb_filename)
1822 return handle->fns->lstat_fn(handle, smb_filename);
1825 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1826 struct files_struct *fsp,
1827 const SMB_STRUCT_STAT *sbuf)
1829 VFS_FIND(get_alloc_size);
1830 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1833 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1834 const struct smb_filename *smb_fname)
1837 return handle->fns->unlink_fn(handle, smb_fname);
1840 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1844 return handle->fns->chmod_fn(handle, path, mode);
1847 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1848 struct files_struct *fsp, mode_t mode)
1851 return handle->fns->fchmod_fn(handle, fsp, mode);
1854 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1855 uid_t uid, gid_t gid)
1858 return handle->fns->chown_fn(handle, path, uid, gid);
1861 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1862 struct files_struct *fsp, uid_t uid, gid_t gid)
1865 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1868 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1869 uid_t uid, gid_t gid)
1872 return handle->fns->lchown_fn(handle, path, uid, gid);
1875 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1878 bool as_root = false;
1880 char *saved_dir = NULL;
1881 char *parent_dir = NULL;
1884 if (fsp->fh->fd != -1) {
1886 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1888 return NT_STATUS_OK;
1890 if (ret == -1 && errno != ENOSYS) {
1891 return map_nt_error_from_unix(errno);
1895 as_root = (geteuid() == 0);
1899 * We are being asked to chown as root. Make
1900 * sure we chdir() into the path to pin it,
1901 * and always act using lchown to ensure we
1902 * don't deref any symbolic links.
1904 const char *final_component = NULL;
1905 struct smb_filename local_fname;
1907 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1909 status = map_nt_error_from_unix(errno);
1910 DEBUG(0,("vfs_chown_fsp: failed to get "
1911 "current working directory. Error was %s\n",
1916 if (!parent_dirname(talloc_tos(),
1917 fsp->fsp_name->base_name,
1919 &final_component)) {
1920 return NT_STATUS_NO_MEMORY;
1923 /* cd into the parent dir to pin it. */
1924 ret = vfs_ChDir(fsp->conn, parent_dir);
1926 return map_nt_error_from_unix(errno);
1929 ZERO_STRUCT(local_fname);
1930 local_fname.base_name = discard_const_p(char, final_component);
1932 /* Must use lstat here. */
1933 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1935 status = map_nt_error_from_unix(errno);
1939 /* Ensure it matches the fsp stat. */
1940 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1941 status = NT_STATUS_ACCESS_DENIED;
1944 path = final_component;
1946 path = fsp->fsp_name->base_name;
1949 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || as_root) {
1950 ret = SMB_VFS_LCHOWN(fsp->conn,
1954 ret = SMB_VFS_CHOWN(fsp->conn,
1960 status = NT_STATUS_OK;
1962 status = map_nt_error_from_unix(errno);
1968 vfs_ChDir(fsp->conn,saved_dir);
1969 TALLOC_FREE(saved_dir);
1970 TALLOC_FREE(parent_dir);
1975 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1978 return handle->fns->chdir_fn(handle, path);
1981 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
1984 return handle->fns->getwd_fn(handle);
1987 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
1988 const struct smb_filename *smb_fname,
1989 struct smb_file_time *ft)
1992 return handle->fns->ntimes_fn(handle, smb_fname, ft);
1995 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
1996 struct files_struct *fsp, off_t offset)
1998 VFS_FIND(ftruncate);
1999 return handle->fns->ftruncate_fn(handle, fsp, offset);
2002 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2003 struct files_struct *fsp,
2008 VFS_FIND(fallocate);
2009 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2012 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2013 struct files_struct *fsp, uint32_t share_mode,
2014 uint32_t access_mask)
2016 VFS_FIND(kernel_flock);
2017 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2021 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2022 struct files_struct *fsp, int leasetype)
2024 VFS_FIND(linux_setlease);
2025 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2028 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
2029 const char *newpath)
2032 return handle->fns->symlink_fn(handle, oldpath, newpath);
2035 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2036 const char *path, char *buf, size_t bufsiz)
2039 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
2042 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
2043 const char *newpath)
2046 return handle->fns->link_fn(handle, oldpath, newpath);
2049 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
2050 mode_t mode, SMB_DEV_T dev)
2053 return handle->fns->mknod_fn(handle, path, mode, dev);
2056 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
2059 return handle->fns->realpath_fn(handle, path);
2062 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
2066 return handle->fns->chflags_fn(handle, path, flags);
2069 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2070 const SMB_STRUCT_STAT *sbuf)
2072 VFS_FIND(file_id_create);
2073 return handle->fns->file_id_create_fn(handle, sbuf);
2076 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2077 struct files_struct *fsp,
2079 TALLOC_CTX *mem_ctx,
2080 unsigned int *num_streams,
2081 struct stream_struct **streams)
2083 VFS_FIND(streaminfo);
2084 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
2085 num_streams, streams);
2088 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2089 const char *path, const char *name,
2090 TALLOC_CTX *mem_ctx, char **found_name)
2092 VFS_FIND(get_real_filename);
2093 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2097 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2098 const char *filename)
2100 VFS_FIND(connectpath);
2101 return handle->fns->connectpath_fn(handle, filename);
2104 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2105 struct files_struct *fsp,
2106 struct lock_struct *plock)
2108 VFS_FIND(strict_lock);
2109 return handle->fns->strict_lock_fn(handle, fsp, plock);
2112 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2113 struct files_struct *fsp,
2114 struct lock_struct *plock)
2116 VFS_FIND(strict_unlock);
2117 handle->fns->strict_unlock_fn(handle, fsp, plock);
2120 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2122 enum vfs_translate_direction direction,
2123 TALLOC_CTX *mem_ctx,
2126 VFS_FIND(translate_name);
2127 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2131 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2132 struct files_struct *fsp,
2136 const uint8_t *in_data,
2139 uint32_t max_out_len,
2143 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2144 in_data, in_len, out_data, max_out_len,
2148 struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle,
2149 TALLOC_CTX *mem_ctx,
2150 struct tevent_context *ev,
2151 struct files_struct *src_fsp,
2153 struct files_struct *dest_fsp,
2157 VFS_FIND(copy_chunk_send);
2158 return handle->fns->copy_chunk_send_fn(handle, mem_ctx, ev, src_fsp,
2159 src_off, dest_fsp, dest_off, num);
2162 NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,
2163 struct tevent_req *req,
2166 VFS_FIND(copy_chunk_recv);
2167 return handle->fns->copy_chunk_recv_fn(handle, req, copied);
2170 NTSTATUS smb_vfs_call_get_compression(vfs_handle_struct *handle,
2171 TALLOC_CTX *mem_ctx,
2172 struct files_struct *fsp,
2173 struct smb_filename *smb_fname,
2174 uint16_t *_compression_fmt)
2176 VFS_FIND(get_compression);
2177 return handle->fns->get_compression_fn(handle, mem_ctx, fsp, smb_fname,
2181 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2182 TALLOC_CTX *mem_ctx,
2183 struct files_struct *fsp,
2184 uint16_t compression_fmt)
2186 VFS_FIND(set_compression);
2187 return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2191 NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
2192 TALLOC_CTX *mem_ctx,
2193 const char *service_path,
2196 VFS_FIND(snap_check_path);
2197 return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path,
2201 NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle,
2202 TALLOC_CTX *mem_ctx,
2203 const char *base_volume,
2209 VFS_FIND(snap_create);
2210 return handle->fns->snap_create_fn(handle, mem_ctx, base_volume, tstamp,
2211 rw, base_path, snap_path);
2214 NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle,
2215 TALLOC_CTX *mem_ctx,
2219 VFS_FIND(snap_delete);
2220 return handle->fns->snap_delete_fn(handle, mem_ctx, base_path,
2224 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2225 struct files_struct *fsp,
2226 uint32_t security_info,
2227 TALLOC_CTX *mem_ctx,
2228 struct security_descriptor **ppdesc)
2230 VFS_FIND(fget_nt_acl);
2231 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2235 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2237 uint32_t security_info,
2238 TALLOC_CTX *mem_ctx,
2239 struct security_descriptor **ppdesc)
2241 VFS_FIND(get_nt_acl);
2242 return handle->fns->get_nt_acl_fn(handle, name, security_info, mem_ctx, ppdesc);
2245 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2246 struct files_struct *fsp,
2247 uint32_t security_info_sent,
2248 const struct security_descriptor *psd)
2250 VFS_FIND(fset_nt_acl);
2251 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2255 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2256 struct smb_filename *file,
2257 struct security_acl *sacl,
2258 uint32_t access_requested,
2259 uint32_t access_denied)
2261 VFS_FIND(audit_file);
2262 return handle->fns->audit_file_fn(handle,
2269 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2272 VFS_FIND(chmod_acl);
2273 return handle->fns->chmod_acl_fn(handle, name, mode);
2276 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2277 struct files_struct *fsp, mode_t mode)
2279 VFS_FIND(fchmod_acl);
2280 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2283 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2285 SMB_ACL_TYPE_T type,
2286 TALLOC_CTX *mem_ctx)
2288 VFS_FIND(sys_acl_get_file);
2289 return handle->fns->sys_acl_get_file_fn(handle, path_p, type, mem_ctx);
2292 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2293 struct files_struct *fsp,
2294 TALLOC_CTX *mem_ctx)
2296 VFS_FIND(sys_acl_get_fd);
2297 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2300 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2302 TALLOC_CTX *mem_ctx,
2303 char **blob_description,
2306 VFS_FIND(sys_acl_blob_get_file);
2307 return handle->fns->sys_acl_blob_get_file_fn(handle, path_p, mem_ctx, blob_description, blob);
2310 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2311 struct files_struct *fsp,
2312 TALLOC_CTX *mem_ctx,
2313 char **blob_description,
2316 VFS_FIND(sys_acl_blob_get_fd);
2317 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2320 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2321 const char *name, SMB_ACL_TYPE_T acltype,
2324 VFS_FIND(sys_acl_set_file);
2325 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2328 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2329 struct files_struct *fsp, SMB_ACL_T theacl)
2331 VFS_FIND(sys_acl_set_fd);
2332 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2335 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2338 VFS_FIND(sys_acl_delete_def_file);
2339 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2342 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2343 const char *path, const char *name, void *value,
2347 return handle->fns->getxattr_fn(handle, path, name, value, size);
2350 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2351 struct files_struct *fsp, const char *name,
2352 void *value, size_t size)
2354 VFS_FIND(fgetxattr);
2355 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2358 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2359 const char *path, char *list, size_t size)
2361 VFS_FIND(listxattr);
2362 return handle->fns->listxattr_fn(handle, path, list, size);
2365 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2366 struct files_struct *fsp, char *list,
2369 VFS_FIND(flistxattr);
2370 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2373 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2374 const char *path, const char *name)
2376 VFS_FIND(removexattr);
2377 return handle->fns->removexattr_fn(handle, path, name);
2380 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2381 struct files_struct *fsp, const char *name)
2383 VFS_FIND(fremovexattr);
2384 return handle->fns->fremovexattr_fn(handle, fsp, name);
2387 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2388 const char *name, const void *value, size_t size,
2392 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2395 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2396 struct files_struct *fsp, const char *name,
2397 const void *value, size_t size, int flags)
2399 VFS_FIND(fsetxattr);
2400 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2403 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2404 struct files_struct *fsp)
2406 VFS_FIND(aio_force);
2407 return handle->fns->aio_force_fn(handle, fsp);
2410 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2411 const struct smb_filename *fname,
2412 SMB_STRUCT_STAT *sbuf)
2414 VFS_FIND(is_offline);
2415 return handle->fns->is_offline_fn(handle, fname, sbuf);
2418 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2419 const struct smb_filename *fname)
2421 VFS_FIND(set_offline);
2422 return handle->fns->set_offline_fn(handle, fname);
2425 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2426 struct files_struct *fsp,
2427 TALLOC_CTX *mem_ctx,
2430 VFS_FIND(durable_cookie);
2431 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2434 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2435 struct files_struct *fsp,
2436 const DATA_BLOB old_cookie,
2437 TALLOC_CTX *mem_ctx,
2438 DATA_BLOB *new_cookie)
2440 VFS_FIND(durable_disconnect);
2441 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2442 mem_ctx, new_cookie);
2445 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2446 struct smb_request *smb1req,
2447 struct smbXsrv_open *op,
2448 const DATA_BLOB old_cookie,
2449 TALLOC_CTX *mem_ctx,
2450 struct files_struct **fsp,
2451 DATA_BLOB *new_cookie)
2453 VFS_FIND(durable_reconnect);
2454 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2455 old_cookie, mem_ctx, fsp,
2459 NTSTATUS smb_vfs_call_readdir_attr(struct vfs_handle_struct *handle,
2460 const struct smb_filename *fname,
2461 TALLOC_CTX *mem_ctx,
2462 struct readdir_attr_data **attr_data)
2464 VFS_FIND(readdir_attr);
2465 return handle->fns->readdir_attr_fn(handle, fname, mem_ctx, attr_data);