2 Unix SMB/Netbios implementation.
4 VFS initialisation and support functions
5 Copyright (C) Tim Potter 1999
6 Copyright (C) Alexander Bokovoy 2002
7 Copyright (C) James Peach 2006
8 Copyright (C) Volker Lendecke 2009
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 This work was sponsored by Optifacio Software Services, Inc.
27 #include "system/filesys.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
31 #include "transfer_file.h"
33 #include "lib/util/tevent_unix.h"
36 #define DBGC_CLASS DBGC_VFS
41 struct vfs_fsp_data *next;
42 struct vfs_handle_struct *owner;
43 void (*destroy)(void *p_data);
45 /* NOTE: This structure contains four pointers so that we can guarantee
46 * that the end of the structure is always both 4-byte and 8-byte aligned.
50 struct vfs_init_function_entry {
52 struct vfs_init_function_entry *prev, *next;
53 const struct vfs_fn_pointers *fns;
56 /****************************************************************************
57 maintain the list of available backends
58 ****************************************************************************/
60 static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
62 struct vfs_init_function_entry *entry = backends;
64 DEBUG(10, ("vfs_find_backend_entry called for %s\n", name));
67 if (strcmp(entry->name, name)==0) return entry;
74 NTSTATUS smb_register_vfs(int version, const char *name,
75 const struct vfs_fn_pointers *fns)
77 struct vfs_init_function_entry *entry = backends;
79 if ((version != SMB_VFS_INTERFACE_VERSION)) {
80 DEBUG(0, ("Failed to register vfs module.\n"
81 "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
82 "current SMB_VFS_INTERFACE_VERSION is %d.\n"
83 "Please recompile against the current Samba Version!\n",
84 version, SMB_VFS_INTERFACE_VERSION));
85 return NT_STATUS_OBJECT_TYPE_MISMATCH;
88 if (!name || !name[0]) {
89 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
90 return NT_STATUS_INVALID_PARAMETER;
93 if (vfs_find_backend_entry(name)) {
94 DEBUG(0,("VFS module %s already loaded!\n", name));
95 return NT_STATUS_OBJECT_NAME_COLLISION;
98 entry = SMB_XMALLOC_P(struct vfs_init_function_entry);
99 entry->name = smb_xstrdup(name);
102 DLIST_ADD(backends, entry);
103 DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
107 /****************************************************************************
108 initialise default vfs hooks
109 ****************************************************************************/
111 static void vfs_init_default(connection_struct *conn)
113 DEBUG(3, ("Initialising default vfs hooks\n"));
114 vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME);
117 /****************************************************************************
118 initialise custom vfs hooks
119 ****************************************************************************/
121 bool vfs_init_custom(connection_struct *conn, const char *vfs_object)
123 char *module_path = NULL;
124 char *module_name = NULL;
125 char *module_param = NULL, *p;
126 vfs_handle_struct *handle;
127 const struct vfs_init_function_entry *entry;
129 if (!conn||!vfs_object||!vfs_object[0]) {
130 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
131 "empty vfs_object!\n"));
139 DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
141 module_path = smb_xstrdup(vfs_object);
143 p = strchr_m(module_path, ':');
148 trim_char(module_param, ' ', ' ');
151 trim_char(module_path, ' ', ' ');
153 module_name = smb_xstrdup(module_path);
155 if ((module_name[0] == '/') &&
156 (strcmp(module_path, DEFAULT_VFS_MODULE_NAME) != 0)) {
159 * Extract the module name from the path. Just use the base
160 * name of the last path component.
163 SAFE_FREE(module_name);
164 module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
166 p = strchr_m(module_name, '.');
173 /* First, try to load the module with the new module system */
174 entry = vfs_find_backend_entry(module_name);
178 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
181 status = smb_load_module("vfs", module_path);
182 if (!NT_STATUS_IS_OK(status)) {
183 DEBUG(0, ("error probing vfs module '%s': %s\n",
184 module_path, nt_errstr(status)));
188 entry = vfs_find_backend_entry(module_name);
190 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
195 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
197 handle = talloc_zero(conn, vfs_handle_struct);
199 DEBUG(0,("TALLOC_ZERO() failed!\n"));
203 handle->fns = entry->fns;
205 handle->param = talloc_strdup(conn, module_param);
207 DLIST_ADD(conn->vfs_handles, handle);
209 SAFE_FREE(module_path);
210 SAFE_FREE(module_name);
214 SAFE_FREE(module_path);
215 SAFE_FREE(module_name);
219 /*****************************************************************
220 Allow VFS modules to extend files_struct with VFS-specific state.
221 This will be ok for small numbers of extensions, but might need to
222 be refactored if it becomes more widely used.
223 ******************************************************************/
225 #define EXT_DATA_AREA(e) ((uint8 *)(e) + sizeof(struct vfs_fsp_data))
227 void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle,
228 files_struct *fsp, size_t ext_size,
229 void (*destroy_fn)(void *p_data))
231 struct vfs_fsp_data *ext;
234 /* Prevent VFS modules adding multiple extensions. */
235 if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
239 ext = (struct vfs_fsp_data *)TALLOC_ZERO(
240 handle->conn, sizeof(struct vfs_fsp_data) + ext_size);
246 ext->next = fsp->vfs_extension;
247 ext->destroy = destroy_fn;
248 fsp->vfs_extension = ext;
249 return EXT_DATA_AREA(ext);
252 void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
254 struct vfs_fsp_data *curr;
255 struct vfs_fsp_data *prev;
257 for (curr = fsp->vfs_extension, prev = NULL;
259 prev = curr, curr = curr->next) {
260 if (curr->owner == handle) {
262 prev->next = curr->next;
264 fsp->vfs_extension = curr->next;
267 curr->destroy(EXT_DATA_AREA(curr));
275 void vfs_remove_all_fsp_extensions(files_struct *fsp)
277 struct vfs_fsp_data *curr;
278 struct vfs_fsp_data *next;
280 for (curr = fsp->vfs_extension; curr; curr = next) {
283 fsp->vfs_extension = next;
286 curr->destroy(EXT_DATA_AREA(curr));
292 void *vfs_memctx_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
294 struct vfs_fsp_data *head;
296 for (head = fsp->vfs_extension; head; head = head->next) {
297 if (head->owner == handle) {
305 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
307 struct vfs_fsp_data *head;
309 head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
311 return EXT_DATA_AREA(head);
319 /*****************************************************************
321 ******************************************************************/
323 bool smbd_vfs_init(connection_struct *conn)
325 const char **vfs_objects;
329 /* Normal share - initialise with disk access functions */
330 vfs_init_default(conn);
332 /* No need to load vfs modules for printer connections */
337 vfs_objects = lp_vfs_objects(SNUM(conn));
339 /* Override VFS functions if 'vfs object' was not specified*/
340 if (!vfs_objects || !vfs_objects[0])
343 for (i=0; vfs_objects[i] ;) {
347 for (j=i-1; j >= 0; j--) {
348 if (!vfs_init_custom(conn, vfs_objects[j])) {
349 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
356 /*******************************************************************
357 Check if a file exists in the vfs.
358 ********************************************************************/
360 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
362 /* Only return OK if stat was successful and S_ISREG */
363 if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
364 S_ISREG(smb_fname->st.st_ex_mode)) {
368 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
371 /****************************************************************************
372 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
373 ****************************************************************************/
375 ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
379 while (total < byte_count)
381 ssize_t ret = SMB_VFS_READ(fsp, buf + total,
384 if (ret == 0) return total;
393 return (ssize_t)total;
396 ssize_t vfs_pread_data(files_struct *fsp, char *buf,
397 size_t byte_count, off_t offset)
401 while (total < byte_count)
403 ssize_t ret = SMB_VFS_PREAD(fsp, buf + total,
404 byte_count - total, offset + total);
406 if (ret == 0) return total;
415 return (ssize_t)total;
418 /****************************************************************************
419 Write data to a fd on the vfs.
420 ****************************************************************************/
422 ssize_t vfs_write_data(struct smb_request *req,
430 if (req && req->unread_bytes) {
431 int sockfd = req->sconn->sock;
433 SMB_ASSERT(req->unread_bytes == N);
434 /* VFS_RECVFILE must drain the socket
435 * before returning. */
436 req->unread_bytes = 0;
437 /* Ensure the socket is blocking. */
438 old_flags = fcntl(sockfd, F_GETFL, 0);
439 if (set_blocking(sockfd, true) == -1) {
442 ret = SMB_VFS_RECVFILE(sockfd,
446 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
453 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
462 return (ssize_t)total;
465 ssize_t vfs_pwrite_data(struct smb_request *req,
474 if (req && req->unread_bytes) {
475 int sockfd = req->sconn->sock;
476 SMB_ASSERT(req->unread_bytes == N);
477 /* VFS_RECVFILE must drain the socket
478 * before returning. */
479 req->unread_bytes = 0;
481 * Leave the socket non-blocking and
482 * use SMB_VFS_RECVFILE. If it returns
483 * EAGAIN || EWOULDBLOCK temporarily set
484 * the socket blocking and retry
488 ret = SMB_VFS_RECVFILE(sockfd,
492 #if defined(EWOULDBLOCK)
493 if (ret == 0 || (ret == -1 &&
494 (errno == EAGAIN || errno == EWOULDBLOCK))) {
495 #else /* EWOULDBLOCK */
496 if (ret == 0 || (ret == -1 && errno == EAGAIN)) {
497 #endif /* EWOULDBLOCK */
499 /* Ensure the socket is blocking. */
500 old_flags = fcntl(sockfd, F_GETFL, 0);
501 if (set_blocking(sockfd, true) == -1) {
504 ret = SMB_VFS_RECVFILE(sockfd,
508 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
515 return (ssize_t)total;
517 /* Any other error case. */
523 return (ssize_t)total;
527 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
537 return (ssize_t)total;
539 /****************************************************************************
540 An allocate file space call using the vfs interface.
541 Allocates space for a file from a filedescriptor.
542 Returns 0 on success, -1 on failure.
543 ****************************************************************************/
545 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
548 connection_struct *conn = fsp->conn;
549 uint64_t space_avail;
550 uint64_t bsize,dfree,dsize;
554 * Actually try and commit the space on disk....
557 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
558 fsp_str_dbg(fsp), (double)len));
560 if (((off_t)len) < 0) {
561 DEBUG(0,("vfs_allocate_file_space: %s negative len "
562 "requested.\n", fsp_str_dbg(fsp)));
567 status = vfs_stat_fsp(fsp);
568 if (!NT_STATUS_IS_OK(status)) {
572 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
575 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
576 /* Shrink - use ftruncate. */
578 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
579 "size %.0f\n", fsp_str_dbg(fsp),
580 (double)fsp->fsp_name->st.st_ex_size));
582 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
584 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
585 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
586 set_filelen_write_cache(fsp, len);
589 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
594 /* Grow - we need to test if we have enough space. */
596 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
598 if (lp_strict_allocate(SNUM(fsp->conn))) {
599 /* See if we have a syscall that will allocate beyond
600 end-of-file without changing EOF. */
601 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
606 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
609 /* We changed the allocation size on disk, but not
610 EOF - exactly as required. We're done ! */
614 len -= fsp->fsp_name->st.st_ex_size;
615 len /= 1024; /* Len is now number of 1k blocks needed. */
616 space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
617 &bsize, &dfree, &dsize);
618 if (space_avail == (uint64_t)-1) {
622 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
623 "needed blocks = %.0f, space avail = %.0f\n",
624 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
625 (double)space_avail));
627 if (len > space_avail) {
635 /****************************************************************************
636 A vfs set_filelen call.
637 set the length of a file from a filedescriptor.
638 Returns 0 on success, -1 on failure.
639 ****************************************************************************/
641 int vfs_set_filelen(files_struct *fsp, off_t len)
645 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
647 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
648 fsp_str_dbg(fsp), (double)len));
649 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
650 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
651 set_filelen_write_cache(fsp, len);
652 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
653 FILE_NOTIFY_CHANGE_SIZE
654 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
655 fsp->fsp_name->base_name);
658 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
663 /****************************************************************************
664 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
665 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
666 as this is also called from the default SMB_VFS_FTRUNCATE code.
667 Always extends the file size.
668 Returns 0 on success, errno on failure.
669 ****************************************************************************/
671 #define SPARSE_BUF_WRITE_SIZE (32*1024)
673 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
679 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
686 while (total < len) {
687 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
689 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
690 if (pwrite_ret == -1) {
691 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
692 "%s failed with error %s\n",
693 fsp_str_dbg(fsp), strerror(errno)));
702 /****************************************************************************
703 A vfs fill sparse call.
704 Writes zeros from the end of file to len, if len is greater than EOF.
705 Used only by strict_sync.
706 Returns 0 on success, -1 on failure.
707 ****************************************************************************/
709 int vfs_fill_sparse(files_struct *fsp, off_t len)
716 status = vfs_stat_fsp(fsp);
717 if (!NT_STATUS_IS_OK(status)) {
721 if (len <= fsp->fsp_name->st.st_ex_size) {
726 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
731 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
732 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
733 (double)fsp->fsp_name->st.st_ex_size, (double)len,
734 (double)(len - fsp->fsp_name->st.st_ex_size)));
736 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
738 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
740 offset = fsp->fsp_name->st.st_ex_size;
741 num_to_write = len - fsp->fsp_name->st.st_ex_size;
743 /* Only do this on non-stream file handles. */
744 if (fsp->base_fsp == NULL) {
745 /* for allocation try fallocate first. This can fail on some
746 * platforms e.g. when the filesystem doesn't support it and no
747 * emulation is being done by the libc (like on AIX with JFS1). In that
748 * case we do our own emulation. fallocate implementations can
749 * return ENOTSUP or EINVAL in cases like that. */
750 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
751 offset, num_to_write);
760 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
761 "error %d. Falling back to slow manual allocation\n", ret));
764 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
773 set_filelen_write_cache(fsp, len);
776 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
780 /****************************************************************************
781 Transfer some data (n bytes) between two file_struct's.
782 ****************************************************************************/
784 static ssize_t vfs_read_fn(void *file, void *buf, size_t len)
786 struct files_struct *fsp = (struct files_struct *)file;
788 return SMB_VFS_READ(fsp, buf, len);
791 static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
793 struct files_struct *fsp = (struct files_struct *)file;
795 return SMB_VFS_WRITE(fsp, buf, len);
798 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
800 return transfer_file_internal((void *)in, (void *)out, n,
801 vfs_read_fn, vfs_write_fn);
804 /*******************************************************************
805 A vfs_readdir wrapper which just returns the file name.
806 ********************************************************************/
808 const char *vfs_readdirname(connection_struct *conn, void *p,
809 SMB_STRUCT_STAT *sbuf, char **talloced)
811 struct dirent *ptr= NULL;
819 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
831 #ifdef HAVE_BROKEN_READDIR_NAME
832 /* using /usr/ucb/cc is BAD */
836 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
837 talloc_tos(), &translated);
838 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
842 *talloced = translated;
843 if (!NT_STATUS_IS_OK(status)) {
849 /*******************************************************************
850 A wrapper for vfs_chdir().
851 ********************************************************************/
853 int vfs_ChDir(connection_struct *conn, const char *path)
858 LastDir = SMB_STRDUP("");
865 if (*path == '/' && strcsequal(LastDir,path)) {
869 DEBUG(4,("vfs_ChDir to %s\n",path));
871 ret = SMB_VFS_CHDIR(conn,path);
875 LastDir = SMB_STRDUP(path);
878 TALLOC_FREE(conn->cwd);
879 conn->cwd = vfs_GetWd(conn, conn);
880 DEBUG(4,("vfs_ChDir got %s\n",conn->cwd));
885 /*******************************************************************
886 Return the absolute current directory path - given a UNIX pathname.
887 Note that this path is returned in DOS format, not UNIX
888 format. Note this can be called with conn == NULL.
889 ********************************************************************/
891 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
893 char *current_dir = NULL;
895 DATA_BLOB cache_value;
897 struct smb_filename *smb_fname_dot = NULL;
898 struct smb_filename *smb_fname_full = NULL;
900 if (!lp_getwd_cache()) {
904 smb_fname_dot = synthetic_smb_fname(ctx, ".", NULL, NULL);
905 if (smb_fname_dot == NULL) {
910 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
912 * Known to fail for root: the directory may be NFS-mounted
913 * and exported with root_squash (so has no root access).
915 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
916 "(NFS problem ?)\n", strerror(errno) ));
920 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
922 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
923 data_blob_const(&key, sizeof(key)),
928 SMB_ASSERT((cache_value.length > 0)
929 && (cache_value.data[cache_value.length-1] == '\0'));
931 smb_fname_full = synthetic_smb_fname(ctx, (char *)cache_value.data,
933 if (smb_fname_full == NULL) {
938 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
939 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
940 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
941 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
945 result = talloc_strdup(ctx, smb_fname_full->base_name);
946 if (result == NULL) {
955 * We don't have the information to hand so rely on traditional
956 * methods. The very slow getcwd, which spawns a process on some
957 * systems, or the not quite so bad getwd.
960 current_dir = SMB_VFS_GETWD(conn);
961 if (current_dir == NULL) {
962 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
967 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
968 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
970 memcache_add(smbd_memcache(), GETWD_CACHE,
971 data_blob_const(&key, sizeof(key)),
972 data_blob_const(current_dir,
973 strlen(current_dir)+1));
976 result = talloc_strdup(ctx, current_dir);
977 if (result == NULL) {
982 TALLOC_FREE(smb_fname_dot);
983 TALLOC_FREE(smb_fname_full);
984 SAFE_FREE(current_dir);
988 /*******************************************************************
989 Reduce a file name, removing .. elements and checking that
990 it is below dir in the heirachy. This uses realpath.
991 This function must run as root, and will return names
992 and valid stat structs that can be checked on open.
993 ********************************************************************/
995 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
997 struct smb_request *smbreq)
1000 TALLOC_CTX *ctx = talloc_tos();
1001 const char *conn_rootdir;
1003 char *dir_name = NULL;
1004 const char *last_component = NULL;
1005 char *resolved_name = NULL;
1006 char *saved_dir = NULL;
1007 struct smb_filename *smb_fname_cwd = NULL;
1008 struct privilege_paths *priv_paths = NULL;
1011 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
1013 conn->connectpath));
1016 priv_paths = talloc_zero(smbreq, struct privilege_paths);
1018 status = NT_STATUS_NO_MEMORY;
1022 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
1023 status = NT_STATUS_NO_MEMORY;
1027 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
1028 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
1030 if (priv_paths->parent_name.base_name == NULL ||
1031 priv_paths->file_name.base_name == NULL) {
1032 status = NT_STATUS_NO_MEMORY;
1036 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
1037 status = map_nt_error_from_unix(errno);
1040 /* Remember where we were. */
1041 saved_dir = vfs_GetWd(ctx, conn);
1043 status = map_nt_error_from_unix(errno);
1047 /* Go to the parent directory to lock in memory. */
1048 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
1049 status = map_nt_error_from_unix(errno);
1053 /* Get the absolute path of the parent directory. */
1054 resolved_name = SMB_VFS_REALPATH(conn,".");
1055 if (!resolved_name) {
1056 status = map_nt_error_from_unix(errno);
1060 if (*resolved_name != '/') {
1061 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1062 "doesn't return absolute paths !\n"));
1063 status = NT_STATUS_OBJECT_NAME_INVALID;
1067 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1068 priv_paths->parent_name.base_name,
1071 /* Now check the stat value is the same. */
1072 smb_fname_cwd = synthetic_smb_fname(talloc_tos(), ".", NULL, NULL);
1073 if (smb_fname_cwd == NULL) {
1074 status = NT_STATUS_NO_MEMORY;
1078 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1079 status = map_nt_error_from_unix(errno);
1083 /* Ensure we're pointing at the same place. */
1084 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1085 DEBUG(0,("check_reduced_name_with_privilege: "
1086 "device/inode/uid/gid on directory %s changed. "
1087 "Denying access !\n",
1088 priv_paths->parent_name.base_name));
1089 status = NT_STATUS_ACCESS_DENIED;
1093 /* Ensure we're below the connect path. */
1095 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1096 if (conn_rootdir == NULL) {
1097 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1099 status = NT_STATUS_ACCESS_DENIED;
1103 rootdir_len = strlen(conn_rootdir);
1104 if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1105 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1106 "attempt: %s is a symlink outside the "
1109 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1110 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1111 status = NT_STATUS_ACCESS_DENIED;
1115 /* Now ensure that the last component either doesn't
1116 exist, or is *NOT* a symlink. */
1118 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1120 /* Errno must be ENOENT for this be ok. */
1121 if (errno != ENOENT) {
1122 status = map_nt_error_from_unix(errno);
1123 DEBUG(2, ("check_reduced_name_with_privilege: "
1124 "LSTAT on %s failed with %s\n",
1125 priv_paths->file_name.base_name,
1126 nt_errstr(status)));
1131 if (VALID_STAT(priv_paths->file_name.st) &&
1132 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1133 DEBUG(2, ("check_reduced_name_with_privilege: "
1134 "Last component %s is a symlink. Denying"
1136 priv_paths->file_name.base_name));
1137 status = NT_STATUS_ACCESS_DENIED;
1141 smbreq->priv_paths = priv_paths;
1142 status = NT_STATUS_OK;
1147 vfs_ChDir(conn, saved_dir);
1149 SAFE_FREE(resolved_name);
1150 if (!NT_STATUS_IS_OK(status)) {
1151 TALLOC_FREE(priv_paths);
1153 TALLOC_FREE(dir_name);
1157 /*******************************************************************
1158 Reduce a file name, removing .. elements and checking that
1159 it is below dir in the heirachy. This uses realpath.
1160 ********************************************************************/
1162 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1164 char *resolved_name = NULL;
1165 bool allow_symlinks = true;
1166 bool allow_widelinks = false;
1168 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1170 resolved_name = SMB_VFS_REALPATH(conn,fname);
1172 if (!resolved_name) {
1175 DEBUG(3,("check_reduced_name: Component not a "
1176 "directory in getting realpath for "
1178 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1181 TALLOC_CTX *ctx = talloc_tos();
1182 char *dir_name = NULL;
1183 const char *last_component = NULL;
1184 char *new_name = NULL;
1187 /* Last component didn't exist.
1188 Remove it and try and canonicalise
1189 the directory name. */
1190 if (!parent_dirname(ctx, fname,
1193 return NT_STATUS_NO_MEMORY;
1196 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1197 if (!resolved_name) {
1198 NTSTATUS status = map_nt_error_from_unix(errno);
1200 if (errno == ENOENT || errno == ENOTDIR) {
1201 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1204 DEBUG(3,("check_reduce_name: "
1205 "couldn't get realpath for "
1208 nt_errstr(status)));
1211 ret = asprintf(&new_name, "%s/%s",
1212 resolved_name, last_component);
1213 SAFE_FREE(resolved_name);
1215 return NT_STATUS_NO_MEMORY;
1217 resolved_name = new_name;
1221 DEBUG(3,("check_reduced_name: couldn't get "
1222 "realpath for %s\n", fname));
1223 return map_nt_error_from_unix(errno);
1227 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1230 if (*resolved_name != '/') {
1231 DEBUG(0,("check_reduced_name: realpath doesn't return "
1232 "absolute paths !\n"));
1233 SAFE_FREE(resolved_name);
1234 return NT_STATUS_OBJECT_NAME_INVALID;
1237 allow_widelinks = lp_widelinks(SNUM(conn));
1238 allow_symlinks = lp_follow_symlinks(SNUM(conn));
1240 /* Common widelinks and symlinks checks. */
1241 if (!allow_widelinks || !allow_symlinks) {
1242 const char *conn_rootdir;
1245 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1246 if (conn_rootdir == NULL) {
1247 DEBUG(2, ("check_reduced_name: Could not get "
1249 SAFE_FREE(resolved_name);
1250 return NT_STATUS_ACCESS_DENIED;
1253 rootdir_len = strlen(conn_rootdir);
1254 if (strncmp(conn_rootdir, resolved_name,
1255 rootdir_len) != 0) {
1256 DEBUG(2, ("check_reduced_name: Bad access "
1257 "attempt: %s is a symlink outside the "
1258 "share path\n", fname));
1259 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1260 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1261 SAFE_FREE(resolved_name);
1262 return NT_STATUS_ACCESS_DENIED;
1265 /* Extra checks if all symlinks are disallowed. */
1266 if (!allow_symlinks) {
1267 /* fname can't have changed in resolved_path. */
1268 const char *p = &resolved_name[rootdir_len];
1270 /* *p can be '\0' if fname was "." */
1271 if (*p == '\0' && ISDOT(fname)) {
1276 DEBUG(2, ("check_reduced_name: logic error (%c) "
1277 "in resolved_name: %s\n",
1280 SAFE_FREE(resolved_name);
1281 return NT_STATUS_ACCESS_DENIED;
1285 if (strcmp(fname, p)!=0) {
1286 DEBUG(2, ("check_reduced_name: Bad access "
1287 "attempt: %s is a symlink to %s\n",
1289 SAFE_FREE(resolved_name);
1290 return NT_STATUS_ACCESS_DENIED;
1297 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1299 SAFE_FREE(resolved_name);
1300 return NT_STATUS_OK;
1304 * XXX: This is temporary and there should be no callers of this once
1305 * smb_filename is plumbed through all path based operations.
1307 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1308 SMB_STRUCT_STAT *psbuf)
1310 struct smb_filename *smb_fname;
1313 smb_fname = synthetic_smb_fname_split(talloc_tos(), fname, NULL);
1314 if (smb_fname == NULL) {
1319 if (lp_posix_pathnames()) {
1320 ret = SMB_VFS_LSTAT(conn, smb_fname);
1322 ret = SMB_VFS_STAT(conn, smb_fname);
1326 *psbuf = smb_fname->st;
1329 TALLOC_FREE(smb_fname);
1334 * XXX: This is temporary and there should be no callers of this once
1335 * smb_filename is plumbed through all path based operations.
1337 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1338 SMB_STRUCT_STAT *psbuf)
1340 struct smb_filename *smb_fname;
1343 smb_fname = synthetic_smb_fname_split(talloc_tos(), fname, NULL);
1344 if (smb_fname == NULL) {
1349 ret = SMB_VFS_LSTAT(conn, smb_fname);
1351 *psbuf = smb_fname->st;
1354 TALLOC_FREE(smb_fname);
1359 * Ensure LSTAT is called for POSIX paths.
1362 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1366 if(fsp->fh->fd == -1) {
1367 if (fsp->posix_open) {
1368 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1370 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1373 return map_nt_error_from_unix(errno);
1376 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1377 return map_nt_error_from_unix(errno);
1380 return NT_STATUS_OK;
1384 * Initialize num_streams and streams, then call VFS op streaminfo
1386 NTSTATUS vfs_streaminfo(connection_struct *conn,
1387 struct files_struct *fsp,
1389 TALLOC_CTX *mem_ctx,
1390 unsigned int *num_streams,
1391 struct stream_struct **streams)
1395 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1399 generate a file_id from a stat structure
1401 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1403 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1406 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1407 const char *service, const char *user)
1410 return handle->fns->connect_fn(handle, service, user);
1413 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1415 VFS_FIND(disconnect);
1416 handle->fns->disconnect_fn(handle);
1419 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1420 const char *path, bool small_query,
1421 uint64_t *bsize, uint64_t *dfree,
1424 VFS_FIND(disk_free);
1425 return handle->fns->disk_free_fn(handle, path, small_query, bsize,
1429 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1430 enum SMB_QUOTA_TYPE qtype, unid_t id,
1433 VFS_FIND(get_quota);
1434 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1437 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1438 enum SMB_QUOTA_TYPE qtype, unid_t id,
1441 VFS_FIND(set_quota);
1442 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1445 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1446 struct files_struct *fsp,
1447 struct shadow_copy_data *shadow_copy_data,
1450 VFS_FIND(get_shadow_copy_data);
1451 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1455 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1456 struct vfs_statvfs_struct *statbuf)
1459 return handle->fns->statvfs_fn(handle, path, statbuf);
1462 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1463 enum timestamp_set_resolution *p_ts_res)
1465 VFS_FIND(fs_capabilities);
1466 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1469 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1470 struct dfs_GetDFSReferral *r)
1472 VFS_FIND(get_dfs_referrals);
1473 return handle->fns->get_dfs_referrals_fn(handle, r);
1476 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1477 const char *fname, const char *mask,
1481 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1484 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1485 struct files_struct *fsp,
1489 VFS_FIND(fdopendir);
1490 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1493 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1495 SMB_STRUCT_STAT *sbuf)
1498 return handle->fns->readdir_fn(handle, dirp, sbuf);
1501 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1502 DIR *dirp, long offset)
1505 handle->fns->seekdir_fn(handle, dirp, offset);
1508 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1512 return handle->fns->telldir_fn(handle, dirp);
1515 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1518 VFS_FIND(rewind_dir);
1519 handle->fns->rewind_dir_fn(handle, dirp);
1522 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1526 return handle->fns->mkdir_fn(handle, path, mode);
1529 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1532 return handle->fns->rmdir_fn(handle, path);
1535 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1539 return handle->fns->closedir_fn(handle, dir);
1542 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1545 VFS_FIND(init_search_op);
1546 handle->fns->init_search_op_fn(handle, dirp);
1549 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1550 struct smb_filename *smb_fname, struct files_struct *fsp,
1551 int flags, mode_t mode)
1554 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1557 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1558 struct smb_request *req,
1559 uint16_t root_dir_fid,
1560 struct smb_filename *smb_fname,
1561 uint32_t access_mask,
1562 uint32_t share_access,
1563 uint32_t create_disposition,
1564 uint32_t create_options,
1565 uint32_t file_attributes,
1566 uint32_t oplock_request,
1567 uint64_t allocation_size,
1568 uint32_t private_flags,
1569 struct security_descriptor *sd,
1570 struct ea_list *ea_list,
1571 files_struct **result,
1574 VFS_FIND(create_file);
1575 return handle->fns->create_file_fn(
1576 handle, req, root_dir_fid, smb_fname, access_mask,
1577 share_access, create_disposition, create_options,
1578 file_attributes, oplock_request, allocation_size,
1579 private_flags, sd, ea_list,
1583 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1584 struct files_struct *fsp)
1587 return handle->fns->close_fn(handle, fsp);
1590 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1591 struct files_struct *fsp, void *data, size_t n)
1594 return handle->fns->read_fn(handle, fsp, data, n);
1597 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1598 struct files_struct *fsp, void *data, size_t n,
1602 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1605 struct smb_vfs_call_pread_state {
1606 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1610 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1612 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1613 TALLOC_CTX *mem_ctx,
1614 struct tevent_context *ev,
1615 struct files_struct *fsp,
1617 size_t n, off_t offset)
1619 struct tevent_req *req, *subreq;
1620 struct smb_vfs_call_pread_state *state;
1622 req = tevent_req_create(mem_ctx, &state,
1623 struct smb_vfs_call_pread_state);
1627 VFS_FIND(pread_send);
1628 state->recv_fn = handle->fns->pread_recv_fn;
1630 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1632 if (tevent_req_nomem(subreq, req)) {
1633 return tevent_req_post(req, ev);
1635 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1639 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1641 struct tevent_req *req = tevent_req_callback_data(
1642 subreq, struct tevent_req);
1643 struct smb_vfs_call_pread_state *state = tevent_req_data(
1644 req, struct smb_vfs_call_pread_state);
1647 state->retval = state->recv_fn(subreq, &err);
1648 TALLOC_FREE(subreq);
1649 if (state->retval == -1) {
1650 tevent_req_error(req, err);
1653 tevent_req_done(req);
1656 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req, int *perrno)
1658 struct smb_vfs_call_pread_state *state = tevent_req_data(
1659 req, struct smb_vfs_call_pread_state);
1662 if (tevent_req_is_unix_error(req, &err)) {
1666 return state->retval;
1669 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1670 struct files_struct *fsp, const void *data,
1674 return handle->fns->write_fn(handle, fsp, data, n);
1677 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1678 struct files_struct *fsp, const void *data,
1679 size_t n, off_t offset)
1682 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1685 struct smb_vfs_call_pwrite_state {
1686 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1690 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1692 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1693 TALLOC_CTX *mem_ctx,
1694 struct tevent_context *ev,
1695 struct files_struct *fsp,
1697 size_t n, off_t offset)
1699 struct tevent_req *req, *subreq;
1700 struct smb_vfs_call_pwrite_state *state;
1702 req = tevent_req_create(mem_ctx, &state,
1703 struct smb_vfs_call_pwrite_state);
1707 VFS_FIND(pwrite_send);
1708 state->recv_fn = handle->fns->pwrite_recv_fn;
1710 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1712 if (tevent_req_nomem(subreq, req)) {
1713 return tevent_req_post(req, ev);
1715 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1719 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1721 struct tevent_req *req = tevent_req_callback_data(
1722 subreq, struct tevent_req);
1723 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1724 req, struct smb_vfs_call_pwrite_state);
1727 state->retval = state->recv_fn(subreq, &err);
1728 TALLOC_FREE(subreq);
1729 if (state->retval == -1) {
1730 tevent_req_error(req, err);
1733 tevent_req_done(req);
1736 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req, int *perrno)
1738 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1739 req, struct smb_vfs_call_pwrite_state);
1742 if (tevent_req_is_unix_error(req, &err)) {
1746 return state->retval;
1749 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1750 struct files_struct *fsp, off_t offset,
1754 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1757 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1758 files_struct *fromfsp, const DATA_BLOB *header,
1759 off_t offset, size_t count)
1762 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1766 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1767 files_struct *tofsp, off_t offset,
1771 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1774 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1775 const struct smb_filename *smb_fname_src,
1776 const struct smb_filename *smb_fname_dst)
1779 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1782 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1783 struct files_struct *fsp)
1786 return handle->fns->fsync_fn(handle, fsp);
1789 struct smb_vfs_call_fsync_state {
1790 int (*recv_fn)(struct tevent_req *req, int *err);
1794 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1796 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1797 TALLOC_CTX *mem_ctx,
1798 struct tevent_context *ev,
1799 struct files_struct *fsp)
1801 struct tevent_req *req, *subreq;
1802 struct smb_vfs_call_fsync_state *state;
1804 req = tevent_req_create(mem_ctx, &state,
1805 struct smb_vfs_call_fsync_state);
1809 VFS_FIND(fsync_send);
1810 state->recv_fn = handle->fns->fsync_recv_fn;
1812 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1813 if (tevent_req_nomem(subreq, req)) {
1814 return tevent_req_post(req, ev);
1816 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1820 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1822 struct tevent_req *req = tevent_req_callback_data(
1823 subreq, struct tevent_req);
1824 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1825 req, struct smb_vfs_call_fsync_state);
1828 state->retval = state->recv_fn(subreq, &err);
1829 TALLOC_FREE(subreq);
1830 if (state->retval == -1) {
1831 tevent_req_error(req, err);
1834 tevent_req_done(req);
1837 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, int *perrno)
1839 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1840 req, struct smb_vfs_call_fsync_state);
1843 if (tevent_req_is_unix_error(req, &err)) {
1847 return state->retval;
1851 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1852 struct smb_filename *smb_fname)
1855 return handle->fns->stat_fn(handle, smb_fname);
1858 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1859 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1862 return handle->fns->fstat_fn(handle, fsp, sbuf);
1865 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1866 struct smb_filename *smb_filename)
1869 return handle->fns->lstat_fn(handle, smb_filename);
1872 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1873 struct files_struct *fsp,
1874 const SMB_STRUCT_STAT *sbuf)
1876 VFS_FIND(get_alloc_size);
1877 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1880 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1881 const struct smb_filename *smb_fname)
1884 return handle->fns->unlink_fn(handle, smb_fname);
1887 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1891 return handle->fns->chmod_fn(handle, path, mode);
1894 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1895 struct files_struct *fsp, mode_t mode)
1898 return handle->fns->fchmod_fn(handle, fsp, mode);
1901 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1902 uid_t uid, gid_t gid)
1905 return handle->fns->chown_fn(handle, path, uid, gid);
1908 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1909 struct files_struct *fsp, uid_t uid, gid_t gid)
1912 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1915 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1916 uid_t uid, gid_t gid)
1919 return handle->fns->lchown_fn(handle, path, uid, gid);
1922 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1925 bool as_root = false;
1927 char *saved_dir = NULL;
1928 char *parent_dir = NULL;
1931 if (fsp->fh->fd != -1) {
1933 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1935 return NT_STATUS_OK;
1937 if (ret == -1 && errno != ENOSYS) {
1938 return map_nt_error_from_unix(errno);
1942 as_root = (geteuid() == 0);
1946 * We are being asked to chown as root. Make
1947 * sure we chdir() into the path to pin it,
1948 * and always act using lchown to ensure we
1949 * don't deref any symbolic links.
1951 const char *final_component = NULL;
1952 struct smb_filename local_fname;
1954 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1956 status = map_nt_error_from_unix(errno);
1957 DEBUG(0,("vfs_chown_fsp: failed to get "
1958 "current working directory. Error was %s\n",
1963 if (!parent_dirname(talloc_tos(),
1964 fsp->fsp_name->base_name,
1966 &final_component)) {
1967 return NT_STATUS_NO_MEMORY;
1970 /* cd into the parent dir to pin it. */
1971 ret = vfs_ChDir(fsp->conn, parent_dir);
1973 return map_nt_error_from_unix(errno);
1976 ZERO_STRUCT(local_fname);
1977 local_fname.base_name = discard_const_p(char, final_component);
1979 /* Must use lstat here. */
1980 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1982 status = map_nt_error_from_unix(errno);
1986 /* Ensure it matches the fsp stat. */
1987 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1988 status = NT_STATUS_ACCESS_DENIED;
1991 path = final_component;
1993 path = fsp->fsp_name->base_name;
1996 if (fsp->posix_open || as_root) {
1997 ret = SMB_VFS_LCHOWN(fsp->conn,
2001 ret = SMB_VFS_CHOWN(fsp->conn,
2007 status = NT_STATUS_OK;
2009 status = map_nt_error_from_unix(errno);
2015 vfs_ChDir(fsp->conn,saved_dir);
2016 TALLOC_FREE(saved_dir);
2017 TALLOC_FREE(parent_dir);
2022 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
2025 return handle->fns->chdir_fn(handle, path);
2028 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
2031 return handle->fns->getwd_fn(handle);
2034 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
2035 const struct smb_filename *smb_fname,
2036 struct smb_file_time *ft)
2039 return handle->fns->ntimes_fn(handle, smb_fname, ft);
2042 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2043 struct files_struct *fsp, off_t offset)
2045 VFS_FIND(ftruncate);
2046 return handle->fns->ftruncate_fn(handle, fsp, offset);
2049 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2050 struct files_struct *fsp,
2051 enum vfs_fallocate_mode mode,
2055 VFS_FIND(fallocate);
2056 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2059 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2060 struct files_struct *fsp, uint32 share_mode,
2061 uint32_t access_mask)
2063 VFS_FIND(kernel_flock);
2064 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2068 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2069 struct files_struct *fsp, int leasetype)
2071 VFS_FIND(linux_setlease);
2072 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2075 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
2076 const char *newpath)
2079 return handle->fns->symlink_fn(handle, oldpath, newpath);
2082 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2083 const char *path, char *buf, size_t bufsiz)
2086 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
2089 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
2090 const char *newpath)
2093 return handle->fns->link_fn(handle, oldpath, newpath);
2096 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
2097 mode_t mode, SMB_DEV_T dev)
2100 return handle->fns->mknod_fn(handle, path, mode, dev);
2103 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
2106 return handle->fns->realpath_fn(handle, path);
2109 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
2110 struct sys_notify_context *ctx,
2113 uint32_t *subdir_filter,
2114 void (*callback)(struct sys_notify_context *ctx,
2116 struct notify_event *ev),
2117 void *private_data, void *handle_p)
2119 VFS_FIND(notify_watch);
2120 return handle->fns->notify_watch_fn(handle, ctx, path,
2121 filter, subdir_filter, callback,
2122 private_data, handle_p);
2125 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
2129 return handle->fns->chflags_fn(handle, path, flags);
2132 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2133 const SMB_STRUCT_STAT *sbuf)
2135 VFS_FIND(file_id_create);
2136 return handle->fns->file_id_create_fn(handle, sbuf);
2139 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2140 struct files_struct *fsp,
2142 TALLOC_CTX *mem_ctx,
2143 unsigned int *num_streams,
2144 struct stream_struct **streams)
2146 VFS_FIND(streaminfo);
2147 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
2148 num_streams, streams);
2151 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2152 const char *path, const char *name,
2153 TALLOC_CTX *mem_ctx, char **found_name)
2155 VFS_FIND(get_real_filename);
2156 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2160 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2161 const char *filename)
2163 VFS_FIND(connectpath);
2164 return handle->fns->connectpath_fn(handle, filename);
2167 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2168 struct files_struct *fsp,
2169 struct lock_struct *plock)
2171 VFS_FIND(strict_lock);
2172 return handle->fns->strict_lock_fn(handle, fsp, plock);
2175 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2176 struct files_struct *fsp,
2177 struct lock_struct *plock)
2179 VFS_FIND(strict_unlock);
2180 handle->fns->strict_unlock_fn(handle, fsp, plock);
2183 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2185 enum vfs_translate_direction direction,
2186 TALLOC_CTX *mem_ctx,
2189 VFS_FIND(translate_name);
2190 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2194 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2195 struct files_struct *fsp,
2199 const uint8_t *in_data,
2202 uint32_t max_out_len,
2206 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2207 in_data, in_len, out_data, max_out_len,
2211 struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle,
2212 TALLOC_CTX *mem_ctx,
2213 struct tevent_context *ev,
2214 struct files_struct *src_fsp,
2216 struct files_struct *dest_fsp,
2220 VFS_FIND(copy_chunk_send);
2221 return handle->fns->copy_chunk_send_fn(handle, mem_ctx, ev, src_fsp,
2222 src_off, dest_fsp, dest_off, num);
2225 NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,
2226 struct tevent_req *req,
2229 VFS_FIND(copy_chunk_recv);
2230 return handle->fns->copy_chunk_recv_fn(handle, req, copied);
2233 NTSTATUS smb_vfs_call_get_compression(vfs_handle_struct *handle,
2234 TALLOC_CTX *mem_ctx,
2235 struct files_struct *fsp,
2236 struct smb_filename *smb_fname,
2237 uint16_t *_compression_fmt)
2239 VFS_FIND(get_compression);
2240 return handle->fns->get_compression_fn(handle, mem_ctx, fsp, smb_fname,
2244 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2245 TALLOC_CTX *mem_ctx,
2246 struct files_struct *fsp,
2247 uint16_t compression_fmt)
2249 VFS_FIND(set_compression);
2250 return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2254 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2255 struct files_struct *fsp,
2256 uint32 security_info,
2257 TALLOC_CTX *mem_ctx,
2258 struct security_descriptor **ppdesc)
2260 VFS_FIND(fget_nt_acl);
2261 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2265 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2267 uint32 security_info,
2268 TALLOC_CTX *mem_ctx,
2269 struct security_descriptor **ppdesc)
2271 VFS_FIND(get_nt_acl);
2272 return handle->fns->get_nt_acl_fn(handle, name, security_info, mem_ctx, ppdesc);
2275 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2276 struct files_struct *fsp,
2277 uint32 security_info_sent,
2278 const struct security_descriptor *psd)
2280 VFS_FIND(fset_nt_acl);
2281 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2285 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2286 struct smb_filename *file,
2287 struct security_acl *sacl,
2288 uint32_t access_requested,
2289 uint32_t access_denied)
2291 VFS_FIND(audit_file);
2292 return handle->fns->audit_file_fn(handle,
2299 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2302 VFS_FIND(chmod_acl);
2303 return handle->fns->chmod_acl_fn(handle, name, mode);
2306 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2307 struct files_struct *fsp, mode_t mode)
2309 VFS_FIND(fchmod_acl);
2310 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2313 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2315 SMB_ACL_TYPE_T type,
2316 TALLOC_CTX *mem_ctx)
2318 VFS_FIND(sys_acl_get_file);
2319 return handle->fns->sys_acl_get_file_fn(handle, path_p, type, mem_ctx);
2322 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2323 struct files_struct *fsp,
2324 TALLOC_CTX *mem_ctx)
2326 VFS_FIND(sys_acl_get_fd);
2327 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2330 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2332 TALLOC_CTX *mem_ctx,
2333 char **blob_description,
2336 VFS_FIND(sys_acl_blob_get_file);
2337 return handle->fns->sys_acl_blob_get_file_fn(handle, path_p, mem_ctx, blob_description, blob);
2340 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2341 struct files_struct *fsp,
2342 TALLOC_CTX *mem_ctx,
2343 char **blob_description,
2346 VFS_FIND(sys_acl_blob_get_fd);
2347 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2350 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2351 const char *name, SMB_ACL_TYPE_T acltype,
2354 VFS_FIND(sys_acl_set_file);
2355 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2358 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2359 struct files_struct *fsp, SMB_ACL_T theacl)
2361 VFS_FIND(sys_acl_set_fd);
2362 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2365 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2368 VFS_FIND(sys_acl_delete_def_file);
2369 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2372 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2373 const char *path, const char *name, void *value,
2377 return handle->fns->getxattr_fn(handle, path, name, value, size);
2380 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2381 struct files_struct *fsp, const char *name,
2382 void *value, size_t size)
2384 VFS_FIND(fgetxattr);
2385 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2388 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2389 const char *path, char *list, size_t size)
2391 VFS_FIND(listxattr);
2392 return handle->fns->listxattr_fn(handle, path, list, size);
2395 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2396 struct files_struct *fsp, char *list,
2399 VFS_FIND(flistxattr);
2400 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2403 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2404 const char *path, const char *name)
2406 VFS_FIND(removexattr);
2407 return handle->fns->removexattr_fn(handle, path, name);
2410 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2411 struct files_struct *fsp, const char *name)
2413 VFS_FIND(fremovexattr);
2414 return handle->fns->fremovexattr_fn(handle, fsp, name);
2417 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2418 const char *name, const void *value, size_t size,
2422 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2425 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2426 struct files_struct *fsp, const char *name,
2427 const void *value, size_t size, int flags)
2429 VFS_FIND(fsetxattr);
2430 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2433 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2434 struct files_struct *fsp)
2436 VFS_FIND(aio_force);
2437 return handle->fns->aio_force_fn(handle, fsp);
2440 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2441 const struct smb_filename *fname,
2442 SMB_STRUCT_STAT *sbuf)
2444 VFS_FIND(is_offline);
2445 return handle->fns->is_offline_fn(handle, fname, sbuf);
2448 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2449 const struct smb_filename *fname)
2451 VFS_FIND(set_offline);
2452 return handle->fns->set_offline_fn(handle, fname);
2455 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2456 struct files_struct *fsp,
2457 TALLOC_CTX *mem_ctx,
2460 VFS_FIND(durable_cookie);
2461 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2464 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2465 struct files_struct *fsp,
2466 const DATA_BLOB old_cookie,
2467 TALLOC_CTX *mem_ctx,
2468 DATA_BLOB *new_cookie)
2470 VFS_FIND(durable_disconnect);
2471 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2472 mem_ctx, new_cookie);
2475 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2476 struct smb_request *smb1req,
2477 struct smbXsrv_open *op,
2478 const DATA_BLOB old_cookie,
2479 TALLOC_CTX *mem_ctx,
2480 struct files_struct **fsp,
2481 DATA_BLOB *new_cookie)
2483 VFS_FIND(durable_reconnect);
2484 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2485 old_cookie, mem_ctx, fsp,