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);
331 vfs_objects = lp_vfs_objects(SNUM(conn));
333 /* Override VFS functions if 'vfs object' was not specified*/
334 if (!vfs_objects || !vfs_objects[0])
337 for (i=0; vfs_objects[i] ;) {
341 for (j=i-1; j >= 0; j--) {
342 if (!vfs_init_custom(conn, vfs_objects[j])) {
343 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
350 /*******************************************************************
351 Check if a file exists in the vfs.
352 ********************************************************************/
354 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
356 /* Only return OK if stat was successful and S_ISREG */
357 if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
358 S_ISREG(smb_fname->st.st_ex_mode)) {
362 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
365 /****************************************************************************
366 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
367 ****************************************************************************/
369 ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
373 while (total < byte_count)
375 ssize_t ret = SMB_VFS_READ(fsp, buf + total,
378 if (ret == 0) return total;
387 return (ssize_t)total;
390 ssize_t vfs_pread_data(files_struct *fsp, char *buf,
391 size_t byte_count, off_t offset)
395 while (total < byte_count)
397 ssize_t ret = SMB_VFS_PREAD(fsp, buf + total,
398 byte_count - total, offset + total);
400 if (ret == 0) return total;
409 return (ssize_t)total;
412 /****************************************************************************
413 Write data to a fd on the vfs.
414 ****************************************************************************/
416 ssize_t vfs_write_data(struct smb_request *req,
424 if (req && req->unread_bytes) {
425 SMB_ASSERT(req->unread_bytes == N);
426 /* VFS_RECVFILE must drain the socket
427 * before returning. */
428 req->unread_bytes = 0;
429 return SMB_VFS_RECVFILE(req->sconn->sock,
436 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
445 return (ssize_t)total;
448 ssize_t vfs_pwrite_data(struct smb_request *req,
457 if (req && req->unread_bytes) {
458 SMB_ASSERT(req->unread_bytes == N);
459 /* VFS_RECVFILE must drain the socket
460 * before returning. */
461 req->unread_bytes = 0;
462 return SMB_VFS_RECVFILE(req->sconn->sock,
469 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
479 return (ssize_t)total;
481 /****************************************************************************
482 An allocate file space call using the vfs interface.
483 Allocates space for a file from a filedescriptor.
484 Returns 0 on success, -1 on failure.
485 ****************************************************************************/
487 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
490 connection_struct *conn = fsp->conn;
491 uint64_t space_avail;
492 uint64_t bsize,dfree,dsize;
496 * Actually try and commit the space on disk....
499 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
500 fsp_str_dbg(fsp), (double)len));
502 if (((off_t)len) < 0) {
503 DEBUG(0,("vfs_allocate_file_space: %s negative len "
504 "requested.\n", fsp_str_dbg(fsp)));
509 status = vfs_stat_fsp(fsp);
510 if (!NT_STATUS_IS_OK(status)) {
514 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
517 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
518 /* Shrink - use ftruncate. */
520 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
521 "size %.0f\n", fsp_str_dbg(fsp),
522 (double)fsp->fsp_name->st.st_ex_size));
524 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
526 flush_write_cache(fsp, SIZECHANGE_FLUSH);
527 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
528 set_filelen_write_cache(fsp, len);
531 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
536 if (!lp_strict_allocate(SNUM(fsp->conn)))
539 /* Grow - we need to test if we have enough space. */
541 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
543 /* See if we have a syscall that will allocate beyond end-of-file
544 without changing EOF. */
545 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
547 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
550 /* We changed the allocation size on disk, but not
551 EOF - exactly as required. We're done ! */
555 len -= fsp->fsp_name->st.st_ex_size;
556 len /= 1024; /* Len is now number of 1k blocks needed. */
557 space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
558 &bsize, &dfree, &dsize);
559 if (space_avail == (uint64_t)-1) {
563 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
564 "needed blocks = %.0f, space avail = %.0f\n",
565 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
566 (double)space_avail));
568 if (len > space_avail) {
576 /****************************************************************************
577 A vfs set_filelen call.
578 set the length of a file from a filedescriptor.
579 Returns 0 on success, -1 on failure.
580 ****************************************************************************/
582 int vfs_set_filelen(files_struct *fsp, off_t len)
586 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
588 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
589 fsp_str_dbg(fsp), (double)len));
590 flush_write_cache(fsp, SIZECHANGE_FLUSH);
591 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
592 set_filelen_write_cache(fsp, len);
593 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
594 FILE_NOTIFY_CHANGE_SIZE
595 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
596 fsp->fsp_name->base_name);
599 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
604 /****************************************************************************
605 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
606 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
607 as this is also called from the default SMB_VFS_FTRUNCATE code.
608 Always extends the file size.
609 Returns 0 on success, errno on failure.
610 ****************************************************************************/
612 #define SPARSE_BUF_WRITE_SIZE (32*1024)
614 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
620 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
627 while (total < len) {
628 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
630 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
631 if (pwrite_ret == -1) {
632 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
633 "%s failed with error %s\n",
634 fsp_str_dbg(fsp), strerror(errno)));
643 /****************************************************************************
644 A vfs fill sparse call.
645 Writes zeros from the end of file to len, if len is greater than EOF.
646 Used only by strict_sync.
647 Returns 0 on success, -1 on failure.
648 ****************************************************************************/
650 int vfs_fill_sparse(files_struct *fsp, off_t len)
657 status = vfs_stat_fsp(fsp);
658 if (!NT_STATUS_IS_OK(status)) {
662 if (len <= fsp->fsp_name->st.st_ex_size) {
667 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
672 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
673 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
674 (double)fsp->fsp_name->st.st_ex_size, (double)len,
675 (double)(len - fsp->fsp_name->st.st_ex_size)));
677 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
679 flush_write_cache(fsp, SIZECHANGE_FLUSH);
681 offset = fsp->fsp_name->st.st_ex_size;
682 num_to_write = len - fsp->fsp_name->st.st_ex_size;
684 /* Only do this on non-stream file handles. */
685 if (fsp->base_fsp == NULL) {
686 /* for allocation try fallocate first. This can fail on some
687 * platforms e.g. when the filesystem doesn't support it and no
688 * emulation is being done by the libc (like on AIX with JFS1). In that
689 * case we do our own emulation. fallocate implementations can
690 * return ENOTSUP or EINVAL in cases like that. */
691 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
692 offset, num_to_write);
701 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
702 "error %d. Falling back to slow manual allocation\n", ret));
705 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
714 set_filelen_write_cache(fsp, len);
717 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
721 /****************************************************************************
722 Transfer some data (n bytes) between two file_struct's.
723 ****************************************************************************/
725 static ssize_t vfs_read_fn(void *file, void *buf, size_t len)
727 struct files_struct *fsp = (struct files_struct *)file;
729 return SMB_VFS_READ(fsp, buf, len);
732 static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
734 struct files_struct *fsp = (struct files_struct *)file;
736 return SMB_VFS_WRITE(fsp, buf, len);
739 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
741 return transfer_file_internal((void *)in, (void *)out, n,
742 vfs_read_fn, vfs_write_fn);
745 /*******************************************************************
746 A vfs_readdir wrapper which just returns the file name.
747 ********************************************************************/
749 const char *vfs_readdirname(connection_struct *conn, void *p,
750 SMB_STRUCT_STAT *sbuf, char **talloced)
752 struct dirent *ptr= NULL;
760 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
772 #ifdef HAVE_BROKEN_READDIR_NAME
773 /* using /usr/ucb/cc is BAD */
777 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
778 talloc_tos(), &translated);
779 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
783 *talloced = translated;
784 if (!NT_STATUS_IS_OK(status)) {
790 /*******************************************************************
791 A wrapper for vfs_chdir().
792 ********************************************************************/
794 int vfs_ChDir(connection_struct *conn, const char *path)
799 LastDir = SMB_STRDUP("");
802 if (strcsequal(path,"."))
805 if (*path == '/' && strcsequal(LastDir,path))
808 DEBUG(4,("vfs_ChDir to %s\n",path));
810 res = SMB_VFS_CHDIR(conn,path);
813 LastDir = SMB_STRDUP(path);
818 /*******************************************************************
819 Return the absolute current directory path - given a UNIX pathname.
820 Note that this path is returned in DOS format, not UNIX
821 format. Note this can be called with conn == NULL.
822 ********************************************************************/
824 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
826 char *current_dir = NULL;
828 DATA_BLOB cache_value;
830 struct smb_filename *smb_fname_dot = NULL;
831 struct smb_filename *smb_fname_full = NULL;
834 if (!lp_getwd_cache()) {
838 status = create_synthetic_smb_fname(ctx, ".", NULL, NULL,
840 if (!NT_STATUS_IS_OK(status)) {
841 errno = map_errno_from_nt_status(status);
845 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
847 * Known to fail for root: the directory may be NFS-mounted
848 * and exported with root_squash (so has no root access).
850 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
851 "(NFS problem ?)\n", strerror(errno) ));
855 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
857 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
858 data_blob_const(&key, sizeof(key)),
863 SMB_ASSERT((cache_value.length > 0)
864 && (cache_value.data[cache_value.length-1] == '\0'));
866 status = create_synthetic_smb_fname(ctx, (char *)cache_value.data,
867 NULL, NULL, &smb_fname_full);
868 if (!NT_STATUS_IS_OK(status)) {
869 errno = map_errno_from_nt_status(status);
873 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
874 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
875 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
876 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
880 result = talloc_strdup(ctx, smb_fname_full->base_name);
881 if (result == NULL) {
890 * We don't have the information to hand so rely on traditional
891 * methods. The very slow getcwd, which spawns a process on some
892 * systems, or the not quite so bad getwd.
895 current_dir = SMB_VFS_GETWD(conn);
896 if (current_dir == NULL) {
897 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
902 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
903 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
905 memcache_add(smbd_memcache(), GETWD_CACHE,
906 data_blob_const(&key, sizeof(key)),
907 data_blob_const(current_dir,
908 strlen(current_dir)+1));
911 result = talloc_strdup(ctx, current_dir);
912 if (result == NULL) {
917 TALLOC_FREE(smb_fname_dot);
918 TALLOC_FREE(smb_fname_full);
919 SAFE_FREE(current_dir);
923 /*******************************************************************
924 Reduce a file name, removing .. elements and checking that
925 it is below dir in the heirachy. This uses realpath.
926 This function must run as root, and will return names
927 and valid stat structs that can be checked on open.
928 ********************************************************************/
930 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
932 struct smb_request *smbreq)
935 TALLOC_CTX *ctx = talloc_tos();
936 const char *conn_rootdir;
938 char *dir_name = NULL;
939 const char *last_component = NULL;
940 char *resolved_name = NULL;
941 char *saved_dir = NULL;
942 struct smb_filename *smb_fname_cwd = NULL;
943 struct privilege_paths *priv_paths = NULL;
946 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
951 priv_paths = talloc_zero(smbreq, struct privilege_paths);
953 status = NT_STATUS_NO_MEMORY;
957 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
958 status = NT_STATUS_NO_MEMORY;
962 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
963 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
965 if (priv_paths->parent_name.base_name == NULL ||
966 priv_paths->file_name.base_name == NULL) {
967 status = NT_STATUS_NO_MEMORY;
971 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
972 status = map_nt_error_from_unix(errno);
975 /* Remember where we were. */
976 saved_dir = vfs_GetWd(ctx, conn);
978 status = map_nt_error_from_unix(errno);
982 /* Go to the parent directory to lock in memory. */
983 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
984 status = map_nt_error_from_unix(errno);
988 /* Get the absolute path of the parent directory. */
989 resolved_name = SMB_VFS_REALPATH(conn,".");
990 if (!resolved_name) {
991 status = map_nt_error_from_unix(errno);
995 if (*resolved_name != '/') {
996 DEBUG(0,("check_reduced_name_with_privilege: realpath "
997 "doesn't return absolute paths !\n"));
998 status = NT_STATUS_OBJECT_NAME_INVALID;
1002 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1003 priv_paths->parent_name.base_name,
1006 /* Now check the stat value is the same. */
1007 status = create_synthetic_smb_fname(talloc_tos(), ".",
1010 if (!NT_STATUS_IS_OK(status)) {
1014 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1015 status = map_nt_error_from_unix(errno);
1019 /* Ensure we're pointing at the same place. */
1020 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1021 DEBUG(0,("check_reduced_name_with_privilege: "
1022 "device/inode/uid/gid on directory %s changed. "
1023 "Denying access !\n",
1024 priv_paths->parent_name.base_name));
1025 status = NT_STATUS_ACCESS_DENIED;
1029 /* Ensure we're below the connect path. */
1031 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1032 if (conn_rootdir == NULL) {
1033 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1035 status = NT_STATUS_ACCESS_DENIED;
1039 rootdir_len = strlen(conn_rootdir);
1040 if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1041 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1042 "attempt: %s is a symlink outside the "
1045 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1046 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1047 status = NT_STATUS_ACCESS_DENIED;
1051 /* Now ensure that the last component either doesn't
1052 exist, or is *NOT* a symlink. */
1054 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1056 /* Errno must be ENOENT for this be ok. */
1057 if (errno != ENOENT) {
1058 status = map_nt_error_from_unix(errno);
1059 DEBUG(2, ("check_reduced_name_with_privilege: "
1060 "LSTAT on %s failed with %s\n",
1061 priv_paths->file_name.base_name,
1062 nt_errstr(status)));
1067 if (VALID_STAT(priv_paths->file_name.st) &&
1068 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1069 DEBUG(2, ("check_reduced_name_with_privilege: "
1070 "Last component %s is a symlink. Denying"
1072 priv_paths->file_name.base_name));
1073 status = NT_STATUS_ACCESS_DENIED;
1077 smbreq->priv_paths = priv_paths;
1078 status = NT_STATUS_OK;
1083 vfs_ChDir(conn, saved_dir);
1085 SAFE_FREE(resolved_name);
1086 if (!NT_STATUS_IS_OK(status)) {
1087 TALLOC_FREE(priv_paths);
1092 /*******************************************************************
1093 Reduce a file name, removing .. elements and checking that
1094 it is below dir in the heirachy. This uses realpath.
1095 ********************************************************************/
1097 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1099 char *resolved_name = NULL;
1100 bool allow_symlinks = true;
1101 bool allow_widelinks = false;
1103 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1105 resolved_name = SMB_VFS_REALPATH(conn,fname);
1107 if (!resolved_name) {
1110 DEBUG(3,("check_reduced_name: Component not a "
1111 "directory in getting realpath for "
1113 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1116 TALLOC_CTX *ctx = talloc_tos();
1117 char *dir_name = NULL;
1118 const char *last_component = NULL;
1119 char *new_name = NULL;
1122 /* Last component didn't exist.
1123 Remove it and try and canonicalise
1124 the directory name. */
1125 if (!parent_dirname(ctx, fname,
1128 return NT_STATUS_NO_MEMORY;
1131 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1132 if (!resolved_name) {
1133 NTSTATUS status = map_nt_error_from_unix(errno);
1135 if (errno == ENOENT || errno == ENOTDIR) {
1136 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1139 DEBUG(3,("check_reduce_name: "
1140 "couldn't get realpath for "
1143 nt_errstr(status)));
1146 ret = asprintf(&new_name, "%s/%s",
1147 resolved_name, last_component);
1148 SAFE_FREE(resolved_name);
1150 return NT_STATUS_NO_MEMORY;
1152 resolved_name = new_name;
1156 DEBUG(3,("check_reduced_name: couldn't get "
1157 "realpath for %s\n", fname));
1158 return map_nt_error_from_unix(errno);
1162 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1165 if (*resolved_name != '/') {
1166 DEBUG(0,("check_reduced_name: realpath doesn't return "
1167 "absolute paths !\n"));
1168 SAFE_FREE(resolved_name);
1169 return NT_STATUS_OBJECT_NAME_INVALID;
1172 allow_widelinks = lp_widelinks(SNUM(conn));
1173 allow_symlinks = lp_symlinks(SNUM(conn));
1175 /* Common widelinks and symlinks checks. */
1176 if (!allow_widelinks || !allow_symlinks) {
1177 const char *conn_rootdir;
1180 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1181 if (conn_rootdir == NULL) {
1182 DEBUG(2, ("check_reduced_name: Could not get "
1184 SAFE_FREE(resolved_name);
1185 return NT_STATUS_ACCESS_DENIED;
1188 rootdir_len = strlen(conn_rootdir);
1189 if (strncmp(conn_rootdir, resolved_name,
1190 rootdir_len) != 0) {
1191 DEBUG(2, ("check_reduced_name: Bad access "
1192 "attempt: %s is a symlink outside the "
1193 "share path\n", fname));
1194 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1195 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1196 SAFE_FREE(resolved_name);
1197 return NT_STATUS_ACCESS_DENIED;
1200 /* Extra checks if all symlinks are disallowed. */
1201 if (!allow_symlinks) {
1202 /* fname can't have changed in resolved_path. */
1203 const char *p = &resolved_name[rootdir_len];
1205 /* *p can be '\0' if fname was "." */
1206 if (*p == '\0' && ISDOT(fname)) {
1211 DEBUG(2, ("check_reduced_name: logic error (%c) "
1212 "in resolved_name: %s\n",
1215 SAFE_FREE(resolved_name);
1216 return NT_STATUS_ACCESS_DENIED;
1220 if (strcmp(fname, p)!=0) {
1221 DEBUG(2, ("check_reduced_name: Bad access "
1222 "attempt: %s is a symlink\n",
1224 SAFE_FREE(resolved_name);
1225 return NT_STATUS_ACCESS_DENIED;
1232 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1234 SAFE_FREE(resolved_name);
1235 return NT_STATUS_OK;
1239 * XXX: This is temporary and there should be no callers of this once
1240 * smb_filename is plumbed through all path based operations.
1242 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1243 SMB_STRUCT_STAT *psbuf)
1245 struct smb_filename *smb_fname = NULL;
1249 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1251 if (!NT_STATUS_IS_OK(status)) {
1252 errno = map_errno_from_nt_status(status);
1256 if (lp_posix_pathnames()) {
1257 ret = SMB_VFS_LSTAT(conn, smb_fname);
1259 ret = SMB_VFS_STAT(conn, smb_fname);
1263 *psbuf = smb_fname->st;
1266 TALLOC_FREE(smb_fname);
1271 * XXX: This is temporary and there should be no callers of this once
1272 * smb_filename is plumbed through all path based operations.
1274 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1275 SMB_STRUCT_STAT *psbuf)
1277 struct smb_filename *smb_fname = NULL;
1281 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1283 if (!NT_STATUS_IS_OK(status)) {
1284 errno = map_errno_from_nt_status(status);
1288 ret = SMB_VFS_LSTAT(conn, smb_fname);
1290 *psbuf = smb_fname->st;
1293 TALLOC_FREE(smb_fname);
1298 * Ensure LSTAT is called for POSIX paths.
1301 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1305 if(fsp->fh->fd == -1) {
1306 if (fsp->posix_open) {
1307 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1309 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1312 return map_nt_error_from_unix(errno);
1315 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1316 return map_nt_error_from_unix(errno);
1319 return NT_STATUS_OK;
1323 * Initialize num_streams and streams, then call VFS op streaminfo
1325 NTSTATUS vfs_streaminfo(connection_struct *conn,
1326 struct files_struct *fsp,
1328 TALLOC_CTX *mem_ctx,
1329 unsigned int *num_streams,
1330 struct stream_struct **streams)
1334 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1338 generate a file_id from a stat structure
1340 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1342 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1345 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1346 const char *service, const char *user)
1349 return handle->fns->connect_fn(handle, service, user);
1352 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1354 VFS_FIND(disconnect);
1355 handle->fns->disconnect_fn(handle);
1358 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1359 const char *path, bool small_query,
1360 uint64_t *bsize, uint64_t *dfree,
1363 VFS_FIND(disk_free);
1364 return handle->fns->disk_free_fn(handle, path, small_query, bsize,
1368 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1369 enum SMB_QUOTA_TYPE qtype, unid_t id,
1372 VFS_FIND(get_quota);
1373 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1376 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1377 enum SMB_QUOTA_TYPE qtype, unid_t id,
1380 VFS_FIND(set_quota);
1381 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1384 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1385 struct files_struct *fsp,
1386 struct shadow_copy_data *shadow_copy_data,
1389 VFS_FIND(get_shadow_copy_data);
1390 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1394 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1395 struct vfs_statvfs_struct *statbuf)
1398 return handle->fns->statvfs_fn(handle, path, statbuf);
1401 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1402 enum timestamp_set_resolution *p_ts_res)
1404 VFS_FIND(fs_capabilities);
1405 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1408 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1409 struct dfs_GetDFSReferral *r)
1411 VFS_FIND(get_dfs_referrals);
1412 return handle->fns->get_dfs_referrals_fn(handle, r);
1415 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1416 const char *fname, const char *mask,
1420 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1423 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1424 struct files_struct *fsp,
1428 VFS_FIND(fdopendir);
1429 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1432 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1434 SMB_STRUCT_STAT *sbuf)
1437 return handle->fns->readdir_fn(handle, dirp, sbuf);
1440 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1441 DIR *dirp, long offset)
1444 handle->fns->seekdir_fn(handle, dirp, offset);
1447 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1451 return handle->fns->telldir_fn(handle, dirp);
1454 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1457 VFS_FIND(rewind_dir);
1458 handle->fns->rewind_dir_fn(handle, dirp);
1461 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1465 return handle->fns->mkdir_fn(handle, path, mode);
1468 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1471 return handle->fns->rmdir_fn(handle, path);
1474 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1478 return handle->fns->closedir_fn(handle, dir);
1481 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1484 VFS_FIND(init_search_op);
1485 handle->fns->init_search_op_fn(handle, dirp);
1488 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1489 struct smb_filename *smb_fname, struct files_struct *fsp,
1490 int flags, mode_t mode)
1493 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1496 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1497 struct smb_request *req,
1498 uint16_t root_dir_fid,
1499 struct smb_filename *smb_fname,
1500 uint32_t access_mask,
1501 uint32_t share_access,
1502 uint32_t create_disposition,
1503 uint32_t create_options,
1504 uint32_t file_attributes,
1505 uint32_t oplock_request,
1506 uint64_t allocation_size,
1507 uint32_t private_flags,
1508 struct security_descriptor *sd,
1509 struct ea_list *ea_list,
1510 files_struct **result,
1513 VFS_FIND(create_file);
1514 return handle->fns->create_file_fn(
1515 handle, req, root_dir_fid, smb_fname, access_mask,
1516 share_access, create_disposition, create_options,
1517 file_attributes, oplock_request, allocation_size,
1518 private_flags, sd, ea_list,
1522 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1523 struct files_struct *fsp)
1526 return handle->fns->close_fn(handle, fsp);
1529 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1530 struct files_struct *fsp, void *data, size_t n)
1533 return handle->fns->read_fn(handle, fsp, data, n);
1536 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1537 struct files_struct *fsp, void *data, size_t n,
1541 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1544 struct smb_vfs_call_pread_state {
1545 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1549 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1551 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1552 TALLOC_CTX *mem_ctx,
1553 struct tevent_context *ev,
1554 struct files_struct *fsp,
1556 size_t n, off_t offset)
1558 struct tevent_req *req, *subreq;
1559 struct smb_vfs_call_pread_state *state;
1561 req = tevent_req_create(mem_ctx, &state,
1562 struct smb_vfs_call_pread_state);
1566 VFS_FIND(pread_send);
1567 state->recv_fn = handle->fns->pread_recv_fn;
1569 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1571 if (tevent_req_nomem(subreq, req)) {
1572 return tevent_req_post(req, ev);
1574 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1578 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1580 struct tevent_req *req = tevent_req_callback_data(
1581 subreq, struct tevent_req);
1582 struct smb_vfs_call_pread_state *state = tevent_req_data(
1583 req, struct smb_vfs_call_pread_state);
1586 state->retval = state->recv_fn(subreq, &err);
1587 TALLOC_FREE(subreq);
1588 if (state->retval == -1) {
1589 tevent_req_error(req, err);
1592 tevent_req_done(req);
1595 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req, int *perrno)
1597 struct smb_vfs_call_pread_state *state = tevent_req_data(
1598 req, struct smb_vfs_call_pread_state);
1601 if (tevent_req_is_unix_error(req, &err)) {
1605 return state->retval;
1608 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1609 struct files_struct *fsp, const void *data,
1613 return handle->fns->write_fn(handle, fsp, data, n);
1616 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1617 struct files_struct *fsp, const void *data,
1618 size_t n, off_t offset)
1621 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1624 struct smb_vfs_call_pwrite_state {
1625 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1629 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1631 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1632 TALLOC_CTX *mem_ctx,
1633 struct tevent_context *ev,
1634 struct files_struct *fsp,
1636 size_t n, off_t offset)
1638 struct tevent_req *req, *subreq;
1639 struct smb_vfs_call_pwrite_state *state;
1641 req = tevent_req_create(mem_ctx, &state,
1642 struct smb_vfs_call_pwrite_state);
1646 VFS_FIND(pwrite_send);
1647 state->recv_fn = handle->fns->pwrite_recv_fn;
1649 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1651 if (tevent_req_nomem(subreq, req)) {
1652 return tevent_req_post(req, ev);
1654 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1658 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1660 struct tevent_req *req = tevent_req_callback_data(
1661 subreq, struct tevent_req);
1662 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1663 req, struct smb_vfs_call_pwrite_state);
1666 state->retval = state->recv_fn(subreq, &err);
1667 TALLOC_FREE(subreq);
1668 if (state->retval == -1) {
1669 tevent_req_error(req, err);
1672 tevent_req_done(req);
1675 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req, int *perrno)
1677 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1678 req, struct smb_vfs_call_pwrite_state);
1681 if (tevent_req_is_unix_error(req, &err)) {
1685 return state->retval;
1688 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1689 struct files_struct *fsp, off_t offset,
1693 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1696 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1697 files_struct *fromfsp, const DATA_BLOB *header,
1698 off_t offset, size_t count)
1701 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1705 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1706 files_struct *tofsp, off_t offset,
1710 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1713 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1714 const struct smb_filename *smb_fname_src,
1715 const struct smb_filename *smb_fname_dst)
1718 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1721 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1722 struct files_struct *fsp)
1725 return handle->fns->fsync_fn(handle, fsp);
1728 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1729 struct smb_filename *smb_fname)
1732 return handle->fns->stat_fn(handle, smb_fname);
1735 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1736 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1739 return handle->fns->fstat_fn(handle, fsp, sbuf);
1742 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1743 struct smb_filename *smb_filename)
1746 return handle->fns->lstat_fn(handle, smb_filename);
1749 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1750 struct files_struct *fsp,
1751 const SMB_STRUCT_STAT *sbuf)
1753 VFS_FIND(get_alloc_size);
1754 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1757 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1758 const struct smb_filename *smb_fname)
1761 return handle->fns->unlink_fn(handle, smb_fname);
1764 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1768 return handle->fns->chmod_fn(handle, path, mode);
1771 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1772 struct files_struct *fsp, mode_t mode)
1775 return handle->fns->fchmod_fn(handle, fsp, mode);
1778 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1779 uid_t uid, gid_t gid)
1782 return handle->fns->chown_fn(handle, path, uid, gid);
1785 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1786 struct files_struct *fsp, uid_t uid, gid_t gid)
1789 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1792 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1793 uid_t uid, gid_t gid)
1796 return handle->fns->lchown_fn(handle, path, uid, gid);
1799 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1802 bool as_root = false;
1804 char *saved_dir = NULL;
1805 char *parent_dir = NULL;
1808 if (fsp->fh->fd != -1) {
1810 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1812 return NT_STATUS_OK;
1814 if (ret == -1 && errno != ENOSYS) {
1815 return map_nt_error_from_unix(errno);
1819 as_root = (geteuid() == 0);
1823 * We are being asked to chown as root. Make
1824 * sure we chdir() into the path to pin it,
1825 * and always act using lchown to ensure we
1826 * don't deref any symbolic links.
1828 const char *final_component = NULL;
1829 struct smb_filename local_fname;
1831 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1833 status = map_nt_error_from_unix(errno);
1834 DEBUG(0,("vfs_chown_fsp: failed to get "
1835 "current working directory. Error was %s\n",
1840 if (!parent_dirname(talloc_tos(),
1841 fsp->fsp_name->base_name,
1843 &final_component)) {
1844 return NT_STATUS_NO_MEMORY;
1847 /* cd into the parent dir to pin it. */
1848 ret = vfs_ChDir(fsp->conn, parent_dir);
1850 return map_nt_error_from_unix(errno);
1853 ZERO_STRUCT(local_fname);
1854 local_fname.base_name = discard_const_p(char, final_component);
1856 /* Must use lstat here. */
1857 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1859 status = map_nt_error_from_unix(errno);
1863 /* Ensure it matches the fsp stat. */
1864 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1865 status = NT_STATUS_ACCESS_DENIED;
1868 path = final_component;
1870 path = fsp->fsp_name->base_name;
1873 if (fsp->posix_open || as_root) {
1874 ret = SMB_VFS_LCHOWN(fsp->conn,
1878 ret = SMB_VFS_CHOWN(fsp->conn,
1884 status = NT_STATUS_OK;
1886 status = map_nt_error_from_unix(errno);
1892 vfs_ChDir(fsp->conn,saved_dir);
1893 TALLOC_FREE(saved_dir);
1894 TALLOC_FREE(parent_dir);
1899 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1902 return handle->fns->chdir_fn(handle, path);
1905 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
1908 return handle->fns->getwd_fn(handle);
1911 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
1912 const struct smb_filename *smb_fname,
1913 struct smb_file_time *ft)
1916 return handle->fns->ntimes_fn(handle, smb_fname, ft);
1919 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
1920 struct files_struct *fsp, off_t offset)
1922 VFS_FIND(ftruncate);
1923 return handle->fns->ftruncate_fn(handle, fsp, offset);
1926 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
1927 struct files_struct *fsp,
1928 enum vfs_fallocate_mode mode,
1932 VFS_FIND(fallocate);
1933 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
1936 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
1937 struct files_struct *fsp, uint32 share_mode,
1938 uint32_t access_mask)
1940 VFS_FIND(kernel_flock);
1941 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
1945 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
1946 struct files_struct *fsp, int leasetype)
1948 VFS_FIND(linux_setlease);
1949 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
1952 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
1953 const char *newpath)
1956 return handle->fns->symlink_fn(handle, oldpath, newpath);
1959 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
1960 const char *path, char *buf, size_t bufsiz)
1963 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
1966 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
1967 const char *newpath)
1970 return handle->fns->link_fn(handle, oldpath, newpath);
1973 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
1974 mode_t mode, SMB_DEV_T dev)
1977 return handle->fns->mknod_fn(handle, path, mode, dev);
1980 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
1983 return handle->fns->realpath_fn(handle, path);
1986 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
1987 struct sys_notify_context *ctx,
1990 uint32_t *subdir_filter,
1991 void (*callback)(struct sys_notify_context *ctx,
1993 struct notify_event *ev),
1994 void *private_data, void *handle_p)
1996 VFS_FIND(notify_watch);
1997 return handle->fns->notify_watch_fn(handle, ctx, path,
1998 filter, subdir_filter, callback,
1999 private_data, handle_p);
2002 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
2006 return handle->fns->chflags_fn(handle, path, flags);
2009 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2010 const SMB_STRUCT_STAT *sbuf)
2012 VFS_FIND(file_id_create);
2013 return handle->fns->file_id_create_fn(handle, sbuf);
2016 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2017 struct files_struct *fsp,
2019 TALLOC_CTX *mem_ctx,
2020 unsigned int *num_streams,
2021 struct stream_struct **streams)
2023 VFS_FIND(streaminfo);
2024 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
2025 num_streams, streams);
2028 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2029 const char *path, const char *name,
2030 TALLOC_CTX *mem_ctx, char **found_name)
2032 VFS_FIND(get_real_filename);
2033 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2037 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2038 const char *filename)
2040 VFS_FIND(connectpath);
2041 return handle->fns->connectpath_fn(handle, filename);
2044 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2045 struct files_struct *fsp,
2046 struct lock_struct *plock)
2048 VFS_FIND(strict_lock);
2049 return handle->fns->strict_lock_fn(handle, fsp, plock);
2052 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2053 struct files_struct *fsp,
2054 struct lock_struct *plock)
2056 VFS_FIND(strict_unlock);
2057 handle->fns->strict_unlock_fn(handle, fsp, plock);
2060 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2062 enum vfs_translate_direction direction,
2063 TALLOC_CTX *mem_ctx,
2066 VFS_FIND(translate_name);
2067 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2071 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2072 struct files_struct *fsp,
2076 const uint8_t *in_data,
2079 uint32_t max_out_len,
2083 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2084 in_data, in_len, out_data, max_out_len,
2088 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2089 struct files_struct *fsp,
2090 uint32 security_info,
2091 struct security_descriptor **ppdesc)
2093 VFS_FIND(fget_nt_acl);
2094 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2098 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2100 uint32 security_info,
2101 struct security_descriptor **ppdesc)
2103 VFS_FIND(get_nt_acl);
2104 return handle->fns->get_nt_acl_fn(handle, name, security_info, ppdesc);
2107 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2108 struct files_struct *fsp,
2109 uint32 security_info_sent,
2110 const struct security_descriptor *psd)
2112 VFS_FIND(fset_nt_acl);
2113 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2117 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2118 struct smb_filename *file,
2119 struct security_acl *sacl,
2120 uint32_t access_requested,
2121 uint32_t access_denied)
2123 VFS_FIND(audit_file);
2124 return handle->fns->audit_file_fn(handle,
2131 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2134 VFS_FIND(chmod_acl);
2135 return handle->fns->chmod_acl_fn(handle, name, mode);
2138 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2139 struct files_struct *fsp, mode_t mode)
2141 VFS_FIND(fchmod_acl);
2142 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2145 int smb_vfs_call_sys_acl_get_entry(struct vfs_handle_struct *handle,
2146 SMB_ACL_T theacl, int entry_id,
2147 SMB_ACL_ENTRY_T *entry_p)
2149 VFS_FIND(sys_acl_get_entry);
2150 return handle->fns->sys_acl_get_entry_fn(handle, theacl, entry_id,
2154 int smb_vfs_call_sys_acl_get_tag_type(struct vfs_handle_struct *handle,
2155 SMB_ACL_ENTRY_T entry_d,
2156 SMB_ACL_TAG_T *tag_type_p)
2158 VFS_FIND(sys_acl_get_tag_type);
2159 return handle->fns->sys_acl_get_tag_type_fn(handle, entry_d,
2163 int smb_vfs_call_sys_acl_get_permset(struct vfs_handle_struct *handle,
2164 SMB_ACL_ENTRY_T entry_d,
2165 SMB_ACL_PERMSET_T *permset_p)
2167 VFS_FIND(sys_acl_get_permset);
2168 return handle->fns->sys_acl_get_permset_fn(handle, entry_d, permset_p);
2171 void * smb_vfs_call_sys_acl_get_qualifier(struct vfs_handle_struct *handle,
2172 SMB_ACL_ENTRY_T entry_d)
2174 VFS_FIND(sys_acl_get_qualifier);
2175 return handle->fns->sys_acl_get_qualifier_fn(handle, entry_d);
2178 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2180 SMB_ACL_TYPE_T type)
2182 VFS_FIND(sys_acl_get_file);
2183 return handle->fns->sys_acl_get_file_fn(handle, path_p, type);
2186 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2187 struct files_struct *fsp)
2189 VFS_FIND(sys_acl_get_fd);
2190 return handle->fns->sys_acl_get_fd_fn(handle, fsp);
2193 int smb_vfs_call_sys_acl_clear_perms(struct vfs_handle_struct *handle,
2194 SMB_ACL_PERMSET_T permset)
2196 VFS_FIND(sys_acl_clear_perms);
2197 return handle->fns->sys_acl_clear_perms_fn(handle, permset);
2200 int smb_vfs_call_sys_acl_add_perm(struct vfs_handle_struct *handle,
2201 SMB_ACL_PERMSET_T permset,
2202 SMB_ACL_PERM_T perm)
2204 VFS_FIND(sys_acl_add_perm);
2205 return handle->fns->sys_acl_add_perm_fn(handle, permset, perm);
2208 char * smb_vfs_call_sys_acl_to_text(struct vfs_handle_struct *handle,
2209 SMB_ACL_T theacl, ssize_t *plen)
2211 VFS_FIND(sys_acl_to_text);
2212 return handle->fns->sys_acl_to_text_fn(handle, theacl, plen);
2215 SMB_ACL_T smb_vfs_call_sys_acl_init(struct vfs_handle_struct *handle,
2218 VFS_FIND(sys_acl_init);
2219 return handle->fns->sys_acl_init_fn(handle, count);
2222 int smb_vfs_call_sys_acl_create_entry(struct vfs_handle_struct *handle,
2223 SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2225 VFS_FIND(sys_acl_create_entry);
2226 return handle->fns->sys_acl_create_entry_fn(handle, pacl, pentry);
2229 int smb_vfs_call_sys_acl_set_tag_type(struct vfs_handle_struct *handle,
2230 SMB_ACL_ENTRY_T entry,
2231 SMB_ACL_TAG_T tagtype)
2233 VFS_FIND(sys_acl_set_tag_type);
2234 return handle->fns->sys_acl_set_tag_type_fn(handle, entry, tagtype);
2237 int smb_vfs_call_sys_acl_set_qualifier(struct vfs_handle_struct *handle,
2238 SMB_ACL_ENTRY_T entry, void *qual)
2240 VFS_FIND(sys_acl_set_qualifier);
2241 return handle->fns->sys_acl_set_qualifier_fn(handle, entry, qual);
2244 int smb_vfs_call_sys_acl_set_permset(struct vfs_handle_struct *handle,
2245 SMB_ACL_ENTRY_T entry,
2246 SMB_ACL_PERMSET_T permset)
2248 VFS_FIND(sys_acl_set_permset);
2249 return handle->fns->sys_acl_set_permset_fn(handle, entry, permset);
2252 int smb_vfs_call_sys_acl_valid(struct vfs_handle_struct *handle,
2255 VFS_FIND(sys_acl_valid);
2256 return handle->fns->sys_acl_valid_fn(handle, theacl);
2259 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2260 const char *name, SMB_ACL_TYPE_T acltype,
2263 VFS_FIND(sys_acl_set_file);
2264 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2267 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2268 struct files_struct *fsp, SMB_ACL_T theacl)
2270 VFS_FIND(sys_acl_set_fd);
2271 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2274 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2277 VFS_FIND(sys_acl_delete_def_file);
2278 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2281 int smb_vfs_call_sys_acl_get_perm(struct vfs_handle_struct *handle,
2282 SMB_ACL_PERMSET_T permset,
2283 SMB_ACL_PERM_T perm)
2285 VFS_FIND(sys_acl_get_perm);
2286 return handle->fns->sys_acl_get_perm_fn(handle, permset, perm);
2289 int smb_vfs_call_sys_acl_free_text(struct vfs_handle_struct *handle,
2292 VFS_FIND(sys_acl_free_text);
2293 return handle->fns->sys_acl_free_text_fn(handle, text);
2296 int smb_vfs_call_sys_acl_free_acl(struct vfs_handle_struct *handle,
2297 SMB_ACL_T posix_acl)
2299 VFS_FIND(sys_acl_free_acl);
2300 return handle->fns->sys_acl_free_acl_fn(handle, posix_acl);
2303 int smb_vfs_call_sys_acl_free_qualifier(struct vfs_handle_struct *handle,
2304 void *qualifier, SMB_ACL_TAG_T tagtype)
2306 VFS_FIND(sys_acl_free_qualifier);
2307 return handle->fns->sys_acl_free_qualifier_fn(handle, qualifier,
2311 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2312 const char *path, const char *name, void *value,
2316 return handle->fns->getxattr_fn(handle, path, name, value, size);
2319 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2320 struct files_struct *fsp, const char *name,
2321 void *value, size_t size)
2323 VFS_FIND(fgetxattr);
2324 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2327 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2328 const char *path, char *list, size_t size)
2330 VFS_FIND(listxattr);
2331 return handle->fns->listxattr_fn(handle, path, list, size);
2334 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2335 struct files_struct *fsp, char *list,
2338 VFS_FIND(flistxattr);
2339 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2342 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2343 const char *path, const char *name)
2345 VFS_FIND(removexattr);
2346 return handle->fns->removexattr_fn(handle, path, name);
2349 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2350 struct files_struct *fsp, const char *name)
2352 VFS_FIND(fremovexattr);
2353 return handle->fns->fremovexattr_fn(handle, fsp, name);
2356 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2357 const char *name, const void *value, size_t size,
2361 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2364 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2365 struct files_struct *fsp, const char *name,
2366 const void *value, size_t size, int flags)
2368 VFS_FIND(fsetxattr);
2369 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2372 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2373 struct files_struct *fsp)
2375 VFS_FIND(aio_force);
2376 return handle->fns->aio_force_fn(handle, fsp);
2379 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2380 const struct smb_filename *fname,
2381 SMB_STRUCT_STAT *sbuf)
2383 VFS_FIND(is_offline);
2384 return handle->fns->is_offline_fn(handle, fname, sbuf);
2387 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2388 const struct smb_filename *fname)
2390 VFS_FIND(set_offline);
2391 return handle->fns->set_offline_fn(handle, fname);