Move cached cwd onto conn struct.
[Samba/gebeck_regimport.git] / source3 / smbd / vfs.c
blob7d194404f4738e37620def3269bfece9df93566b
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
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.
26 #include "includes.h"
27 #include "system/filesys.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "memcache.h"
31 #include "transfer_file.h"
32 #include "ntioctl.h"
33 #include "lib/util/tevent_unix.h"
35 #undef DBGC_CLASS
36 #define DBGC_CLASS DBGC_VFS
38 static_decl_vfs;
40 struct vfs_fsp_data {
41 struct vfs_fsp_data *next;
42 struct vfs_handle_struct *owner;
43 void (*destroy)(void *p_data);
44 void *_dummy_;
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 {
51 char *name;
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));
66 while(entry) {
67 if (strcmp(entry->name, name)==0) return entry;
68 entry = entry->next;
71 return NULL;
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);
100 entry->fns = fns;
102 DLIST_ADD(backends, entry);
103 DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
104 return NT_STATUS_OK;
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"));
132 return False;
135 if(!backends) {
136 static_init_vfs;
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, ':');
145 if (p) {
146 *p = 0;
147 module_param = p+1;
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, '.');
168 if (p != NULL) {
169 *p = '\0';
173 /* First, try to load the module with the new module system */
174 entry = vfs_find_backend_entry(module_name);
175 if (!entry) {
176 NTSTATUS status;
178 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
179 vfs_object));
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)));
185 goto fail;
188 entry = vfs_find_backend_entry(module_name);
189 if (!entry) {
190 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
191 goto fail;
195 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
197 handle = talloc_zero(conn, vfs_handle_struct);
198 if (!handle) {
199 DEBUG(0,("TALLOC_ZERO() failed!\n"));
200 goto fail;
202 handle->conn = conn;
203 handle->fns = entry->fns;
204 if (module_param) {
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);
211 return True;
213 fail:
214 SAFE_FREE(module_path);
215 SAFE_FREE(module_name);
216 return False;
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;
232 void * ext_data;
234 /* Prevent VFS modules adding multiple extensions. */
235 if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
236 return ext_data;
239 ext = (struct vfs_fsp_data *)TALLOC_ZERO(
240 handle->conn, sizeof(struct vfs_fsp_data) + ext_size);
241 if (ext == NULL) {
242 return NULL;
245 ext->owner = handle;
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;
258 curr;
259 prev = curr, curr = curr->next) {
260 if (curr->owner == handle) {
261 if (prev) {
262 prev->next = curr->next;
263 } else {
264 fsp->vfs_extension = curr->next;
266 if (curr->destroy) {
267 curr->destroy(EXT_DATA_AREA(curr));
269 TALLOC_FREE(curr);
270 return;
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) {
282 next = curr->next;
283 fsp->vfs_extension = next;
285 if (curr->destroy) {
286 curr->destroy(EXT_DATA_AREA(curr));
288 TALLOC_FREE(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) {
298 return head;
302 return NULL;
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);
310 if (head != NULL) {
311 return EXT_DATA_AREA(head);
314 return NULL;
317 #undef EXT_DATA_AREA
319 /*****************************************************************
320 Generic VFS init.
321 ******************************************************************/
323 bool smbd_vfs_init(connection_struct *conn)
325 const char **vfs_objects;
326 unsigned int i = 0;
327 int j = 0;
329 /* Normal share - initialise with disk access functions */
330 vfs_init_default(conn);
332 /* No need to load vfs modules for printer connections */
333 if (conn->printer) {
334 return True;
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])
341 return True;
343 for (i=0; vfs_objects[i] ;) {
344 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]));
350 return False;
353 return True;
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)) {
365 return NT_STATUS_OK;
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)
377 size_t total=0;
379 while (total < byte_count)
381 ssize_t ret = SMB_VFS_READ(fsp, buf + total,
382 byte_count - total);
384 if (ret == 0) return total;
385 if (ret == -1) {
386 if (errno == EINTR)
387 continue;
388 else
389 return -1;
391 total += ret;
393 return (ssize_t)total;
396 ssize_t vfs_pread_data(files_struct *fsp, char *buf,
397 size_t byte_count, off_t offset)
399 size_t total=0;
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;
407 if (ret == -1) {
408 if (errno == EINTR)
409 continue;
410 else
411 return -1;
413 total += ret;
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,
423 files_struct *fsp,
424 const char *buffer,
425 size_t N)
427 size_t total=0;
428 ssize_t ret;
430 if (req && req->unread_bytes) {
431 SMB_ASSERT(req->unread_bytes == N);
432 /* VFS_RECVFILE must drain the socket
433 * before returning. */
434 req->unread_bytes = 0;
435 return SMB_VFS_RECVFILE(req->sconn->sock,
436 fsp,
437 (off_t)-1,
441 while (total < N) {
442 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
444 if (ret == -1)
445 return -1;
446 if (ret == 0)
447 return total;
449 total += ret;
451 return (ssize_t)total;
454 ssize_t vfs_pwrite_data(struct smb_request *req,
455 files_struct *fsp,
456 const char *buffer,
457 size_t N,
458 off_t offset)
460 size_t total=0;
461 ssize_t ret;
463 if (req && req->unread_bytes) {
464 SMB_ASSERT(req->unread_bytes == N);
465 /* VFS_RECVFILE must drain the socket
466 * before returning. */
467 req->unread_bytes = 0;
468 return SMB_VFS_RECVFILE(req->sconn->sock,
469 fsp,
470 offset,
474 while (total < N) {
475 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
476 offset + total);
478 if (ret == -1)
479 return -1;
480 if (ret == 0)
481 return total;
483 total += ret;
485 return (ssize_t)total;
487 /****************************************************************************
488 An allocate file space call using the vfs interface.
489 Allocates space for a file from a filedescriptor.
490 Returns 0 on success, -1 on failure.
491 ****************************************************************************/
493 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
495 int ret;
496 connection_struct *conn = fsp->conn;
497 uint64_t space_avail;
498 uint64_t bsize,dfree,dsize;
499 NTSTATUS status;
502 * Actually try and commit the space on disk....
505 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
506 fsp_str_dbg(fsp), (double)len));
508 if (((off_t)len) < 0) {
509 DEBUG(0,("vfs_allocate_file_space: %s negative len "
510 "requested.\n", fsp_str_dbg(fsp)));
511 errno = EINVAL;
512 return -1;
515 status = vfs_stat_fsp(fsp);
516 if (!NT_STATUS_IS_OK(status)) {
517 return -1;
520 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
521 return 0;
523 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
524 /* Shrink - use ftruncate. */
526 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
527 "size %.0f\n", fsp_str_dbg(fsp),
528 (double)fsp->fsp_name->st.st_ex_size));
530 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
532 flush_write_cache(fsp, SIZECHANGE_FLUSH);
533 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
534 set_filelen_write_cache(fsp, len);
537 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
539 return ret;
542 if (!lp_strict_allocate(SNUM(fsp->conn)))
543 return 0;
545 /* Grow - we need to test if we have enough space. */
547 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
549 /* See if we have a syscall that will allocate beyond end-of-file
550 without changing EOF. */
551 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
553 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
555 if (ret == 0) {
556 /* We changed the allocation size on disk, but not
557 EOF - exactly as required. We're done ! */
558 return 0;
561 len -= fsp->fsp_name->st.st_ex_size;
562 len /= 1024; /* Len is now number of 1k blocks needed. */
563 space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
564 &bsize, &dfree, &dsize);
565 if (space_avail == (uint64_t)-1) {
566 return -1;
569 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
570 "needed blocks = %.0f, space avail = %.0f\n",
571 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
572 (double)space_avail));
574 if (len > space_avail) {
575 errno = ENOSPC;
576 return -1;
579 return 0;
582 /****************************************************************************
583 A vfs set_filelen call.
584 set the length of a file from a filedescriptor.
585 Returns 0 on success, -1 on failure.
586 ****************************************************************************/
588 int vfs_set_filelen(files_struct *fsp, off_t len)
590 int ret;
592 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
594 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
595 fsp_str_dbg(fsp), (double)len));
596 flush_write_cache(fsp, SIZECHANGE_FLUSH);
597 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
598 set_filelen_write_cache(fsp, len);
599 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
600 FILE_NOTIFY_CHANGE_SIZE
601 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
602 fsp->fsp_name->base_name);
605 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
607 return ret;
610 /****************************************************************************
611 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
612 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
613 as this is also called from the default SMB_VFS_FTRUNCATE code.
614 Always extends the file size.
615 Returns 0 on success, errno on failure.
616 ****************************************************************************/
618 #define SPARSE_BUF_WRITE_SIZE (32*1024)
620 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
622 ssize_t pwrite_ret;
623 size_t total = 0;
625 if (!sparse_buf) {
626 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
627 if (!sparse_buf) {
628 errno = ENOMEM;
629 return ENOMEM;
633 while (total < len) {
634 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
636 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
637 if (pwrite_ret == -1) {
638 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
639 "%s failed with error %s\n",
640 fsp_str_dbg(fsp), strerror(errno)));
641 return errno;
643 total += pwrite_ret;
646 return 0;
649 /****************************************************************************
650 A vfs fill sparse call.
651 Writes zeros from the end of file to len, if len is greater than EOF.
652 Used only by strict_sync.
653 Returns 0 on success, -1 on failure.
654 ****************************************************************************/
656 int vfs_fill_sparse(files_struct *fsp, off_t len)
658 int ret;
659 NTSTATUS status;
660 off_t offset;
661 size_t num_to_write;
663 status = vfs_stat_fsp(fsp);
664 if (!NT_STATUS_IS_OK(status)) {
665 return -1;
668 if (len <= fsp->fsp_name->st.st_ex_size) {
669 return 0;
672 #ifdef S_ISFIFO
673 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
674 return 0;
676 #endif
678 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
679 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
680 (double)fsp->fsp_name->st.st_ex_size, (double)len,
681 (double)(len - fsp->fsp_name->st.st_ex_size)));
683 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
685 flush_write_cache(fsp, SIZECHANGE_FLUSH);
687 offset = fsp->fsp_name->st.st_ex_size;
688 num_to_write = len - fsp->fsp_name->st.st_ex_size;
690 /* Only do this on non-stream file handles. */
691 if (fsp->base_fsp == NULL) {
692 /* for allocation try fallocate first. This can fail on some
693 * platforms e.g. when the filesystem doesn't support it and no
694 * emulation is being done by the libc (like on AIX with JFS1). In that
695 * case we do our own emulation. fallocate implementations can
696 * return ENOTSUP or EINVAL in cases like that. */
697 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
698 offset, num_to_write);
699 if (ret == ENOSPC) {
700 errno = ENOSPC;
701 ret = -1;
702 goto out;
704 if (ret == 0) {
705 goto out;
707 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
708 "error %d. Falling back to slow manual allocation\n", ret));
711 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
712 if (ret != 0) {
713 errno = ret;
714 ret = -1;
717 out:
719 if (ret == 0) {
720 set_filelen_write_cache(fsp, len);
723 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
724 return ret;
727 /****************************************************************************
728 Transfer some data (n bytes) between two file_struct's.
729 ****************************************************************************/
731 static ssize_t vfs_read_fn(void *file, void *buf, size_t len)
733 struct files_struct *fsp = (struct files_struct *)file;
735 return SMB_VFS_READ(fsp, buf, len);
738 static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
740 struct files_struct *fsp = (struct files_struct *)file;
742 return SMB_VFS_WRITE(fsp, buf, len);
745 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
747 return transfer_file_internal((void *)in, (void *)out, n,
748 vfs_read_fn, vfs_write_fn);
751 /*******************************************************************
752 A vfs_readdir wrapper which just returns the file name.
753 ********************************************************************/
755 const char *vfs_readdirname(connection_struct *conn, void *p,
756 SMB_STRUCT_STAT *sbuf, char **talloced)
758 struct dirent *ptr= NULL;
759 const char *dname;
760 char *translated;
761 NTSTATUS status;
763 if (!p)
764 return(NULL);
766 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
767 if (!ptr)
768 return(NULL);
770 dname = ptr->d_name;
773 #ifdef NEXT2
774 if (telldir(p) < 0)
775 return(NULL);
776 #endif
778 #ifdef HAVE_BROKEN_READDIR_NAME
779 /* using /usr/ucb/cc is BAD */
780 dname = dname - 2;
781 #endif
783 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
784 talloc_tos(), &translated);
785 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
786 *talloced = NULL;
787 return dname;
789 *talloced = translated;
790 if (!NT_STATUS_IS_OK(status)) {
791 return NULL;
793 return translated;
796 /*******************************************************************
797 A wrapper for vfs_chdir().
798 ********************************************************************/
800 int vfs_ChDir(connection_struct *conn, const char *path)
802 int ret;
804 if (strcsequal(path,".")) {
805 return 0;
808 DEBUG(4,("vfs_ChDir to %s\n",path));
810 ret = SMB_VFS_CHDIR(conn,path);
811 if (ret == 0) {
812 TALLOC_FREE(conn->cwd);
813 conn->cwd = vfs_GetWd(conn, conn);
814 DEBUG(4,("vfs_ChDir got %s\n",conn->cwd));
816 return ret;
819 /*******************************************************************
820 Return the absolute current directory path - given a UNIX pathname.
821 Note that this path is returned in DOS format, not UNIX
822 format. Note this can be called with conn == NULL.
823 ********************************************************************/
825 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
827 char *current_dir = NULL;
828 char *result = NULL;
829 DATA_BLOB cache_value;
830 struct file_id key;
831 struct smb_filename *smb_fname_dot = NULL;
832 struct smb_filename *smb_fname_full = NULL;
833 NTSTATUS status;
835 if (!lp_getwd_cache()) {
836 goto nocache;
839 status = create_synthetic_smb_fname(ctx, ".", NULL, NULL,
840 &smb_fname_dot);
841 if (!NT_STATUS_IS_OK(status)) {
842 errno = map_errno_from_nt_status(status);
843 goto out;
846 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
848 * Known to fail for root: the directory may be NFS-mounted
849 * and exported with root_squash (so has no root access).
851 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
852 "(NFS problem ?)\n", strerror(errno) ));
853 goto nocache;
856 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
858 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
859 data_blob_const(&key, sizeof(key)),
860 &cache_value)) {
861 goto nocache;
864 SMB_ASSERT((cache_value.length > 0)
865 && (cache_value.data[cache_value.length-1] == '\0'));
867 status = create_synthetic_smb_fname(ctx, (char *)cache_value.data,
868 NULL, NULL, &smb_fname_full);
869 if (!NT_STATUS_IS_OK(status)) {
870 errno = map_errno_from_nt_status(status);
871 goto out;
874 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
875 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
876 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
877 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
879 * Ok, we're done
881 result = talloc_strdup(ctx, smb_fname_full->base_name);
882 if (result == NULL) {
883 errno = ENOMEM;
885 goto out;
888 nocache:
891 * We don't have the information to hand so rely on traditional
892 * methods. The very slow getcwd, which spawns a process on some
893 * systems, or the not quite so bad getwd.
896 current_dir = SMB_VFS_GETWD(conn);
897 if (current_dir == NULL) {
898 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
899 strerror(errno)));
900 goto out;
903 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
904 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
906 memcache_add(smbd_memcache(), GETWD_CACHE,
907 data_blob_const(&key, sizeof(key)),
908 data_blob_const(current_dir,
909 strlen(current_dir)+1));
912 result = talloc_strdup(ctx, current_dir);
913 if (result == NULL) {
914 errno = ENOMEM;
917 out:
918 TALLOC_FREE(smb_fname_dot);
919 TALLOC_FREE(smb_fname_full);
920 SAFE_FREE(current_dir);
921 return result;
924 /*******************************************************************
925 Reduce a file name, removing .. elements and checking that
926 it is below dir in the heirachy. This uses realpath.
927 This function must run as root, and will return names
928 and valid stat structs that can be checked on open.
929 ********************************************************************/
931 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
932 const char *fname,
933 struct smb_request *smbreq)
935 NTSTATUS status;
936 TALLOC_CTX *ctx = talloc_tos();
937 const char *conn_rootdir;
938 size_t rootdir_len;
939 char *dir_name = NULL;
940 const char *last_component = NULL;
941 char *resolved_name = NULL;
942 char *saved_dir = NULL;
943 struct smb_filename *smb_fname_cwd = NULL;
944 struct privilege_paths *priv_paths = NULL;
945 int ret;
947 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
948 fname,
949 conn->connectpath));
952 priv_paths = talloc_zero(smbreq, struct privilege_paths);
953 if (!priv_paths) {
954 status = NT_STATUS_NO_MEMORY;
955 goto err;
958 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
959 status = NT_STATUS_NO_MEMORY;
960 goto err;
963 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
964 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
966 if (priv_paths->parent_name.base_name == NULL ||
967 priv_paths->file_name.base_name == NULL) {
968 status = NT_STATUS_NO_MEMORY;
969 goto err;
972 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
973 status = map_nt_error_from_unix(errno);
974 goto err;
976 /* Remember where we were. */
977 saved_dir = vfs_GetWd(ctx, conn);
978 if (!saved_dir) {
979 status = map_nt_error_from_unix(errno);
980 goto err;
983 /* Go to the parent directory to lock in memory. */
984 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
985 status = map_nt_error_from_unix(errno);
986 goto err;
989 /* Get the absolute path of the parent directory. */
990 resolved_name = SMB_VFS_REALPATH(conn,".");
991 if (!resolved_name) {
992 status = map_nt_error_from_unix(errno);
993 goto err;
996 if (*resolved_name != '/') {
997 DEBUG(0,("check_reduced_name_with_privilege: realpath "
998 "doesn't return absolute paths !\n"));
999 status = NT_STATUS_OBJECT_NAME_INVALID;
1000 goto err;
1003 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1004 priv_paths->parent_name.base_name,
1005 resolved_name));
1007 /* Now check the stat value is the same. */
1008 status = create_synthetic_smb_fname(talloc_tos(), ".",
1009 NULL, NULL,
1010 &smb_fname_cwd);
1011 if (!NT_STATUS_IS_OK(status)) {
1012 goto err;
1015 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1016 status = map_nt_error_from_unix(errno);
1017 goto err;
1020 /* Ensure we're pointing at the same place. */
1021 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1022 DEBUG(0,("check_reduced_name_with_privilege: "
1023 "device/inode/uid/gid on directory %s changed. "
1024 "Denying access !\n",
1025 priv_paths->parent_name.base_name));
1026 status = NT_STATUS_ACCESS_DENIED;
1027 goto err;
1030 /* Ensure we're below the connect path. */
1032 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1033 if (conn_rootdir == NULL) {
1034 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1035 "conn_rootdir\n"));
1036 status = NT_STATUS_ACCESS_DENIED;
1037 goto err;
1040 rootdir_len = strlen(conn_rootdir);
1041 if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1042 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1043 "attempt: %s is a symlink outside the "
1044 "share path\n",
1045 dir_name));
1046 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1047 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1048 status = NT_STATUS_ACCESS_DENIED;
1049 goto err;
1052 /* Now ensure that the last component either doesn't
1053 exist, or is *NOT* a symlink. */
1055 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1056 if (ret == -1) {
1057 /* Errno must be ENOENT for this be ok. */
1058 if (errno != ENOENT) {
1059 status = map_nt_error_from_unix(errno);
1060 DEBUG(2, ("check_reduced_name_with_privilege: "
1061 "LSTAT on %s failed with %s\n",
1062 priv_paths->file_name.base_name,
1063 nt_errstr(status)));
1064 goto err;
1068 if (VALID_STAT(priv_paths->file_name.st) &&
1069 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1070 DEBUG(2, ("check_reduced_name_with_privilege: "
1071 "Last component %s is a symlink. Denying"
1072 "access.\n",
1073 priv_paths->file_name.base_name));
1074 status = NT_STATUS_ACCESS_DENIED;
1075 goto err;
1078 smbreq->priv_paths = priv_paths;
1079 status = NT_STATUS_OK;
1081 err:
1083 if (saved_dir) {
1084 vfs_ChDir(conn, saved_dir);
1086 SAFE_FREE(resolved_name);
1087 if (!NT_STATUS_IS_OK(status)) {
1088 TALLOC_FREE(priv_paths);
1090 TALLOC_FREE(dir_name);
1091 return status;
1094 /*******************************************************************
1095 Reduce a file name, removing .. elements and checking that
1096 it is below dir in the heirachy. This uses realpath.
1097 ********************************************************************/
1099 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1101 char *resolved_name = NULL;
1102 bool allow_symlinks = true;
1103 bool allow_widelinks = false;
1105 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1107 resolved_name = SMB_VFS_REALPATH(conn,fname);
1109 if (!resolved_name) {
1110 switch (errno) {
1111 case ENOTDIR:
1112 DEBUG(3,("check_reduced_name: Component not a "
1113 "directory in getting realpath for "
1114 "%s\n", fname));
1115 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1116 case ENOENT:
1118 TALLOC_CTX *ctx = talloc_tos();
1119 char *dir_name = NULL;
1120 const char *last_component = NULL;
1121 char *new_name = NULL;
1122 int ret;
1124 /* Last component didn't exist.
1125 Remove it and try and canonicalise
1126 the directory name. */
1127 if (!parent_dirname(ctx, fname,
1128 &dir_name,
1129 &last_component)) {
1130 return NT_STATUS_NO_MEMORY;
1133 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1134 if (!resolved_name) {
1135 NTSTATUS status = map_nt_error_from_unix(errno);
1137 if (errno == ENOENT || errno == ENOTDIR) {
1138 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1141 DEBUG(3,("check_reduce_name: "
1142 "couldn't get realpath for "
1143 "%s (%s)\n",
1144 fname,
1145 nt_errstr(status)));
1146 return status;
1148 ret = asprintf(&new_name, "%s/%s",
1149 resolved_name, last_component);
1150 SAFE_FREE(resolved_name);
1151 if (ret == -1) {
1152 return NT_STATUS_NO_MEMORY;
1154 resolved_name = new_name;
1155 break;
1157 default:
1158 DEBUG(3,("check_reduced_name: couldn't get "
1159 "realpath for %s\n", fname));
1160 return map_nt_error_from_unix(errno);
1164 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1165 resolved_name));
1167 if (*resolved_name != '/') {
1168 DEBUG(0,("check_reduced_name: realpath doesn't return "
1169 "absolute paths !\n"));
1170 SAFE_FREE(resolved_name);
1171 return NT_STATUS_OBJECT_NAME_INVALID;
1174 allow_widelinks = lp_widelinks(SNUM(conn));
1175 allow_symlinks = lp_symlinks(SNUM(conn));
1177 /* Common widelinks and symlinks checks. */
1178 if (!allow_widelinks || !allow_symlinks) {
1179 const char *conn_rootdir;
1180 size_t rootdir_len;
1182 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1183 if (conn_rootdir == NULL) {
1184 DEBUG(2, ("check_reduced_name: Could not get "
1185 "conn_rootdir\n"));
1186 SAFE_FREE(resolved_name);
1187 return NT_STATUS_ACCESS_DENIED;
1190 rootdir_len = strlen(conn_rootdir);
1191 if (strncmp(conn_rootdir, resolved_name,
1192 rootdir_len) != 0) {
1193 DEBUG(2, ("check_reduced_name: Bad access "
1194 "attempt: %s is a symlink outside the "
1195 "share path\n", fname));
1196 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1197 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1198 SAFE_FREE(resolved_name);
1199 return NT_STATUS_ACCESS_DENIED;
1202 /* Extra checks if all symlinks are disallowed. */
1203 if (!allow_symlinks) {
1204 /* fname can't have changed in resolved_path. */
1205 const char *p = &resolved_name[rootdir_len];
1207 /* *p can be '\0' if fname was "." */
1208 if (*p == '\0' && ISDOT(fname)) {
1209 goto out;
1212 if (*p != '/') {
1213 DEBUG(2, ("check_reduced_name: logic error (%c) "
1214 "in resolved_name: %s\n",
1216 fname));
1217 SAFE_FREE(resolved_name);
1218 return NT_STATUS_ACCESS_DENIED;
1221 p++;
1222 if (strcmp(fname, p)!=0) {
1223 DEBUG(2, ("check_reduced_name: Bad access "
1224 "attempt: %s is a symlink to %s\n",
1225 fname, p));
1226 SAFE_FREE(resolved_name);
1227 return NT_STATUS_ACCESS_DENIED;
1232 out:
1234 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1235 resolved_name));
1236 SAFE_FREE(resolved_name);
1237 return NT_STATUS_OK;
1241 * XXX: This is temporary and there should be no callers of this once
1242 * smb_filename is plumbed through all path based operations.
1244 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1245 SMB_STRUCT_STAT *psbuf)
1247 struct smb_filename *smb_fname = NULL;
1248 NTSTATUS status;
1249 int ret;
1251 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1252 &smb_fname);
1253 if (!NT_STATUS_IS_OK(status)) {
1254 errno = map_errno_from_nt_status(status);
1255 return -1;
1258 if (lp_posix_pathnames()) {
1259 ret = SMB_VFS_LSTAT(conn, smb_fname);
1260 } else {
1261 ret = SMB_VFS_STAT(conn, smb_fname);
1264 if (ret != -1) {
1265 *psbuf = smb_fname->st;
1268 TALLOC_FREE(smb_fname);
1269 return ret;
1273 * XXX: This is temporary and there should be no callers of this once
1274 * smb_filename is plumbed through all path based operations.
1276 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1277 SMB_STRUCT_STAT *psbuf)
1279 struct smb_filename *smb_fname = NULL;
1280 NTSTATUS status;
1281 int ret;
1283 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1284 &smb_fname);
1285 if (!NT_STATUS_IS_OK(status)) {
1286 errno = map_errno_from_nt_status(status);
1287 return -1;
1290 ret = SMB_VFS_LSTAT(conn, smb_fname);
1291 if (ret != -1) {
1292 *psbuf = smb_fname->st;
1295 TALLOC_FREE(smb_fname);
1296 return ret;
1300 * Ensure LSTAT is called for POSIX paths.
1303 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1305 int ret;
1307 if(fsp->fh->fd == -1) {
1308 if (fsp->posix_open) {
1309 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1310 } else {
1311 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1313 if (ret == -1) {
1314 return map_nt_error_from_unix(errno);
1316 } else {
1317 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1318 return map_nt_error_from_unix(errno);
1321 return NT_STATUS_OK;
1325 * Initialize num_streams and streams, then call VFS op streaminfo
1327 NTSTATUS vfs_streaminfo(connection_struct *conn,
1328 struct files_struct *fsp,
1329 const char *fname,
1330 TALLOC_CTX *mem_ctx,
1331 unsigned int *num_streams,
1332 struct stream_struct **streams)
1334 *num_streams = 0;
1335 *streams = NULL;
1336 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1340 generate a file_id from a stat structure
1342 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1344 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1347 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1348 const char *service, const char *user)
1350 VFS_FIND(connect);
1351 return handle->fns->connect_fn(handle, service, user);
1354 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1356 VFS_FIND(disconnect);
1357 handle->fns->disconnect_fn(handle);
1360 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1361 const char *path, bool small_query,
1362 uint64_t *bsize, uint64_t *dfree,
1363 uint64_t *dsize)
1365 VFS_FIND(disk_free);
1366 return handle->fns->disk_free_fn(handle, path, small_query, bsize,
1367 dfree, dsize);
1370 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1371 enum SMB_QUOTA_TYPE qtype, unid_t id,
1372 SMB_DISK_QUOTA *qt)
1374 VFS_FIND(get_quota);
1375 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1378 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1379 enum SMB_QUOTA_TYPE qtype, unid_t id,
1380 SMB_DISK_QUOTA *qt)
1382 VFS_FIND(set_quota);
1383 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1386 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1387 struct files_struct *fsp,
1388 struct shadow_copy_data *shadow_copy_data,
1389 bool labels)
1391 VFS_FIND(get_shadow_copy_data);
1392 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1393 shadow_copy_data,
1394 labels);
1396 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1397 struct vfs_statvfs_struct *statbuf)
1399 VFS_FIND(statvfs);
1400 return handle->fns->statvfs_fn(handle, path, statbuf);
1403 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1404 enum timestamp_set_resolution *p_ts_res)
1406 VFS_FIND(fs_capabilities);
1407 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1410 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1411 struct dfs_GetDFSReferral *r)
1413 VFS_FIND(get_dfs_referrals);
1414 return handle->fns->get_dfs_referrals_fn(handle, r);
1417 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1418 const char *fname, const char *mask,
1419 uint32 attributes)
1421 VFS_FIND(opendir);
1422 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1425 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1426 struct files_struct *fsp,
1427 const char *mask,
1428 uint32 attributes)
1430 VFS_FIND(fdopendir);
1431 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1434 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1435 DIR *dirp,
1436 SMB_STRUCT_STAT *sbuf)
1438 VFS_FIND(readdir);
1439 return handle->fns->readdir_fn(handle, dirp, sbuf);
1442 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1443 DIR *dirp, long offset)
1445 VFS_FIND(seekdir);
1446 handle->fns->seekdir_fn(handle, dirp, offset);
1449 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1450 DIR *dirp)
1452 VFS_FIND(telldir);
1453 return handle->fns->telldir_fn(handle, dirp);
1456 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1457 DIR *dirp)
1459 VFS_FIND(rewind_dir);
1460 handle->fns->rewind_dir_fn(handle, dirp);
1463 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1464 mode_t mode)
1466 VFS_FIND(mkdir);
1467 return handle->fns->mkdir_fn(handle, path, mode);
1470 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1472 VFS_FIND(rmdir);
1473 return handle->fns->rmdir_fn(handle, path);
1476 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1477 DIR *dir)
1479 VFS_FIND(closedir);
1480 return handle->fns->closedir_fn(handle, dir);
1483 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1484 DIR *dirp)
1486 VFS_FIND(init_search_op);
1487 handle->fns->init_search_op_fn(handle, dirp);
1490 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1491 struct smb_filename *smb_fname, struct files_struct *fsp,
1492 int flags, mode_t mode)
1494 VFS_FIND(open);
1495 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1498 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1499 struct smb_request *req,
1500 uint16_t root_dir_fid,
1501 struct smb_filename *smb_fname,
1502 uint32_t access_mask,
1503 uint32_t share_access,
1504 uint32_t create_disposition,
1505 uint32_t create_options,
1506 uint32_t file_attributes,
1507 uint32_t oplock_request,
1508 uint64_t allocation_size,
1509 uint32_t private_flags,
1510 struct security_descriptor *sd,
1511 struct ea_list *ea_list,
1512 files_struct **result,
1513 int *pinfo)
1515 VFS_FIND(create_file);
1516 return handle->fns->create_file_fn(
1517 handle, req, root_dir_fid, smb_fname, access_mask,
1518 share_access, create_disposition, create_options,
1519 file_attributes, oplock_request, allocation_size,
1520 private_flags, sd, ea_list,
1521 result, pinfo);
1524 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1525 struct files_struct *fsp)
1527 VFS_FIND(close);
1528 return handle->fns->close_fn(handle, fsp);
1531 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1532 struct files_struct *fsp, void *data, size_t n)
1534 VFS_FIND(read);
1535 return handle->fns->read_fn(handle, fsp, data, n);
1538 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1539 struct files_struct *fsp, void *data, size_t n,
1540 off_t offset)
1542 VFS_FIND(pread);
1543 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1546 struct smb_vfs_call_pread_state {
1547 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1548 ssize_t retval;
1551 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1553 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1554 TALLOC_CTX *mem_ctx,
1555 struct tevent_context *ev,
1556 struct files_struct *fsp,
1557 void *data,
1558 size_t n, off_t offset)
1560 struct tevent_req *req, *subreq;
1561 struct smb_vfs_call_pread_state *state;
1563 req = tevent_req_create(mem_ctx, &state,
1564 struct smb_vfs_call_pread_state);
1565 if (req == NULL) {
1566 return NULL;
1568 VFS_FIND(pread_send);
1569 state->recv_fn = handle->fns->pread_recv_fn;
1571 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1572 offset);
1573 if (tevent_req_nomem(subreq, req)) {
1574 return tevent_req_post(req, ev);
1576 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1577 return req;
1580 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1582 struct tevent_req *req = tevent_req_callback_data(
1583 subreq, struct tevent_req);
1584 struct smb_vfs_call_pread_state *state = tevent_req_data(
1585 req, struct smb_vfs_call_pread_state);
1586 int err;
1588 state->retval = state->recv_fn(subreq, &err);
1589 TALLOC_FREE(subreq);
1590 if (state->retval == -1) {
1591 tevent_req_error(req, err);
1592 return;
1594 tevent_req_done(req);
1597 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req, int *perrno)
1599 struct smb_vfs_call_pread_state *state = tevent_req_data(
1600 req, struct smb_vfs_call_pread_state);
1601 int err;
1603 if (tevent_req_is_unix_error(req, &err)) {
1604 *perrno = err;
1605 return -1;
1607 return state->retval;
1610 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1611 struct files_struct *fsp, const void *data,
1612 size_t n)
1614 VFS_FIND(write);
1615 return handle->fns->write_fn(handle, fsp, data, n);
1618 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1619 struct files_struct *fsp, const void *data,
1620 size_t n, off_t offset)
1622 VFS_FIND(pwrite);
1623 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1626 struct smb_vfs_call_pwrite_state {
1627 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1628 ssize_t retval;
1631 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1633 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1634 TALLOC_CTX *mem_ctx,
1635 struct tevent_context *ev,
1636 struct files_struct *fsp,
1637 const void *data,
1638 size_t n, off_t offset)
1640 struct tevent_req *req, *subreq;
1641 struct smb_vfs_call_pwrite_state *state;
1643 req = tevent_req_create(mem_ctx, &state,
1644 struct smb_vfs_call_pwrite_state);
1645 if (req == NULL) {
1646 return NULL;
1648 VFS_FIND(pwrite_send);
1649 state->recv_fn = handle->fns->pwrite_recv_fn;
1651 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1652 offset);
1653 if (tevent_req_nomem(subreq, req)) {
1654 return tevent_req_post(req, ev);
1656 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1657 return req;
1660 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1662 struct tevent_req *req = tevent_req_callback_data(
1663 subreq, struct tevent_req);
1664 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1665 req, struct smb_vfs_call_pwrite_state);
1666 int err;
1668 state->retval = state->recv_fn(subreq, &err);
1669 TALLOC_FREE(subreq);
1670 if (state->retval == -1) {
1671 tevent_req_error(req, err);
1672 return;
1674 tevent_req_done(req);
1677 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req, int *perrno)
1679 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1680 req, struct smb_vfs_call_pwrite_state);
1681 int err;
1683 if (tevent_req_is_unix_error(req, &err)) {
1684 *perrno = err;
1685 return -1;
1687 return state->retval;
1690 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1691 struct files_struct *fsp, off_t offset,
1692 int whence)
1694 VFS_FIND(lseek);
1695 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1698 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1699 files_struct *fromfsp, const DATA_BLOB *header,
1700 off_t offset, size_t count)
1702 VFS_FIND(sendfile);
1703 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1704 count);
1707 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1708 files_struct *tofsp, off_t offset,
1709 size_t count)
1711 VFS_FIND(recvfile);
1712 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1715 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1716 const struct smb_filename *smb_fname_src,
1717 const struct smb_filename *smb_fname_dst)
1719 VFS_FIND(rename);
1720 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1723 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1724 struct files_struct *fsp)
1726 VFS_FIND(fsync);
1727 return handle->fns->fsync_fn(handle, fsp);
1730 struct smb_vfs_call_fsync_state {
1731 int (*recv_fn)(struct tevent_req *req, int *err);
1732 int retval;
1735 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1737 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1738 TALLOC_CTX *mem_ctx,
1739 struct tevent_context *ev,
1740 struct files_struct *fsp)
1742 struct tevent_req *req, *subreq;
1743 struct smb_vfs_call_fsync_state *state;
1745 req = tevent_req_create(mem_ctx, &state,
1746 struct smb_vfs_call_fsync_state);
1747 if (req == NULL) {
1748 return NULL;
1750 VFS_FIND(fsync_send);
1751 state->recv_fn = handle->fns->fsync_recv_fn;
1753 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1754 if (tevent_req_nomem(subreq, req)) {
1755 return tevent_req_post(req, ev);
1757 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1758 return req;
1761 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1763 struct tevent_req *req = tevent_req_callback_data(
1764 subreq, struct tevent_req);
1765 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1766 req, struct smb_vfs_call_fsync_state);
1767 int err;
1769 state->retval = state->recv_fn(subreq, &err);
1770 TALLOC_FREE(subreq);
1771 if (state->retval == -1) {
1772 tevent_req_error(req, err);
1773 return;
1775 tevent_req_done(req);
1778 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, int *perrno)
1780 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1781 req, struct smb_vfs_call_fsync_state);
1782 int err;
1784 if (tevent_req_is_unix_error(req, &err)) {
1785 *perrno = err;
1786 return -1;
1788 return state->retval;
1792 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1793 struct smb_filename *smb_fname)
1795 VFS_FIND(stat);
1796 return handle->fns->stat_fn(handle, smb_fname);
1799 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1800 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1802 VFS_FIND(fstat);
1803 return handle->fns->fstat_fn(handle, fsp, sbuf);
1806 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1807 struct smb_filename *smb_filename)
1809 VFS_FIND(lstat);
1810 return handle->fns->lstat_fn(handle, smb_filename);
1813 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1814 struct files_struct *fsp,
1815 const SMB_STRUCT_STAT *sbuf)
1817 VFS_FIND(get_alloc_size);
1818 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1821 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1822 const struct smb_filename *smb_fname)
1824 VFS_FIND(unlink);
1825 return handle->fns->unlink_fn(handle, smb_fname);
1828 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1829 mode_t mode)
1831 VFS_FIND(chmod);
1832 return handle->fns->chmod_fn(handle, path, mode);
1835 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1836 struct files_struct *fsp, mode_t mode)
1838 VFS_FIND(fchmod);
1839 return handle->fns->fchmod_fn(handle, fsp, mode);
1842 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1843 uid_t uid, gid_t gid)
1845 VFS_FIND(chown);
1846 return handle->fns->chown_fn(handle, path, uid, gid);
1849 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1850 struct files_struct *fsp, uid_t uid, gid_t gid)
1852 VFS_FIND(fchown);
1853 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1856 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1857 uid_t uid, gid_t gid)
1859 VFS_FIND(lchown);
1860 return handle->fns->lchown_fn(handle, path, uid, gid);
1863 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1865 int ret;
1866 bool as_root = false;
1867 const char *path;
1868 char *saved_dir = NULL;
1869 char *parent_dir = NULL;
1870 NTSTATUS status;
1872 if (fsp->fh->fd != -1) {
1873 /* Try fchown. */
1874 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1875 if (ret == 0) {
1876 return NT_STATUS_OK;
1878 if (ret == -1 && errno != ENOSYS) {
1879 return map_nt_error_from_unix(errno);
1883 as_root = (geteuid() == 0);
1885 if (as_root) {
1887 * We are being asked to chown as root. Make
1888 * sure we chdir() into the path to pin it,
1889 * and always act using lchown to ensure we
1890 * don't deref any symbolic links.
1892 const char *final_component = NULL;
1893 struct smb_filename local_fname;
1895 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1896 if (!saved_dir) {
1897 status = map_nt_error_from_unix(errno);
1898 DEBUG(0,("vfs_chown_fsp: failed to get "
1899 "current working directory. Error was %s\n",
1900 strerror(errno)));
1901 return status;
1904 if (!parent_dirname(talloc_tos(),
1905 fsp->fsp_name->base_name,
1906 &parent_dir,
1907 &final_component)) {
1908 return NT_STATUS_NO_MEMORY;
1911 /* cd into the parent dir to pin it. */
1912 ret = vfs_ChDir(fsp->conn, parent_dir);
1913 if (ret == -1) {
1914 return map_nt_error_from_unix(errno);
1917 ZERO_STRUCT(local_fname);
1918 local_fname.base_name = discard_const_p(char, final_component);
1920 /* Must use lstat here. */
1921 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1922 if (ret == -1) {
1923 status = map_nt_error_from_unix(errno);
1924 goto out;
1927 /* Ensure it matches the fsp stat. */
1928 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1929 status = NT_STATUS_ACCESS_DENIED;
1930 goto out;
1932 path = final_component;
1933 } else {
1934 path = fsp->fsp_name->base_name;
1937 if (fsp->posix_open || as_root) {
1938 ret = SMB_VFS_LCHOWN(fsp->conn,
1939 path,
1940 uid, gid);
1941 } else {
1942 ret = SMB_VFS_CHOWN(fsp->conn,
1943 path,
1944 uid, gid);
1947 if (ret == 0) {
1948 status = NT_STATUS_OK;
1949 } else {
1950 status = map_nt_error_from_unix(errno);
1953 out:
1955 if (as_root) {
1956 vfs_ChDir(fsp->conn,saved_dir);
1957 TALLOC_FREE(saved_dir);
1958 TALLOC_FREE(parent_dir);
1960 return status;
1963 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1965 VFS_FIND(chdir);
1966 return handle->fns->chdir_fn(handle, path);
1969 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
1971 VFS_FIND(getwd);
1972 return handle->fns->getwd_fn(handle);
1975 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
1976 const struct smb_filename *smb_fname,
1977 struct smb_file_time *ft)
1979 VFS_FIND(ntimes);
1980 return handle->fns->ntimes_fn(handle, smb_fname, ft);
1983 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
1984 struct files_struct *fsp, off_t offset)
1986 VFS_FIND(ftruncate);
1987 return handle->fns->ftruncate_fn(handle, fsp, offset);
1990 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
1991 struct files_struct *fsp,
1992 enum vfs_fallocate_mode mode,
1993 off_t offset,
1994 off_t len)
1996 VFS_FIND(fallocate);
1997 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2000 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2001 struct files_struct *fsp, uint32 share_mode,
2002 uint32_t access_mask)
2004 VFS_FIND(kernel_flock);
2005 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2006 access_mask);
2009 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2010 struct files_struct *fsp, int leasetype)
2012 VFS_FIND(linux_setlease);
2013 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2016 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
2017 const char *newpath)
2019 VFS_FIND(symlink);
2020 return handle->fns->symlink_fn(handle, oldpath, newpath);
2023 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2024 const char *path, char *buf, size_t bufsiz)
2026 VFS_FIND(readlink);
2027 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
2030 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
2031 const char *newpath)
2033 VFS_FIND(link);
2034 return handle->fns->link_fn(handle, oldpath, newpath);
2037 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
2038 mode_t mode, SMB_DEV_T dev)
2040 VFS_FIND(mknod);
2041 return handle->fns->mknod_fn(handle, path, mode, dev);
2044 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
2046 VFS_FIND(realpath);
2047 return handle->fns->realpath_fn(handle, path);
2050 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
2051 struct sys_notify_context *ctx,
2052 const char *path,
2053 uint32_t *filter,
2054 uint32_t *subdir_filter,
2055 void (*callback)(struct sys_notify_context *ctx,
2056 void *private_data,
2057 struct notify_event *ev),
2058 void *private_data, void *handle_p)
2060 VFS_FIND(notify_watch);
2061 return handle->fns->notify_watch_fn(handle, ctx, path,
2062 filter, subdir_filter, callback,
2063 private_data, handle_p);
2066 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
2067 unsigned int flags)
2069 VFS_FIND(chflags);
2070 return handle->fns->chflags_fn(handle, path, flags);
2073 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2074 const SMB_STRUCT_STAT *sbuf)
2076 VFS_FIND(file_id_create);
2077 return handle->fns->file_id_create_fn(handle, sbuf);
2080 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2081 struct files_struct *fsp,
2082 const char *fname,
2083 TALLOC_CTX *mem_ctx,
2084 unsigned int *num_streams,
2085 struct stream_struct **streams)
2087 VFS_FIND(streaminfo);
2088 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
2089 num_streams, streams);
2092 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2093 const char *path, const char *name,
2094 TALLOC_CTX *mem_ctx, char **found_name)
2096 VFS_FIND(get_real_filename);
2097 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2098 found_name);
2101 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2102 const char *filename)
2104 VFS_FIND(connectpath);
2105 return handle->fns->connectpath_fn(handle, filename);
2108 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2109 struct files_struct *fsp,
2110 struct lock_struct *plock)
2112 VFS_FIND(strict_lock);
2113 return handle->fns->strict_lock_fn(handle, fsp, plock);
2116 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2117 struct files_struct *fsp,
2118 struct lock_struct *plock)
2120 VFS_FIND(strict_unlock);
2121 handle->fns->strict_unlock_fn(handle, fsp, plock);
2124 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2125 const char *name,
2126 enum vfs_translate_direction direction,
2127 TALLOC_CTX *mem_ctx,
2128 char **mapped_name)
2130 VFS_FIND(translate_name);
2131 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2132 mapped_name);
2135 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2136 struct files_struct *fsp,
2137 TALLOC_CTX *ctx,
2138 uint32_t function,
2139 uint16_t req_flags,
2140 const uint8_t *in_data,
2141 uint32_t in_len,
2142 uint8_t **out_data,
2143 uint32_t max_out_len,
2144 uint32_t *out_len)
2146 VFS_FIND(fsctl);
2147 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2148 in_data, in_len, out_data, max_out_len,
2149 out_len);
2152 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2153 struct files_struct *fsp,
2154 uint32 security_info,
2155 struct security_descriptor **ppdesc)
2157 VFS_FIND(fget_nt_acl);
2158 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2159 ppdesc);
2162 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2163 const char *name,
2164 uint32 security_info,
2165 struct security_descriptor **ppdesc)
2167 VFS_FIND(get_nt_acl);
2168 return handle->fns->get_nt_acl_fn(handle, name, security_info, ppdesc);
2171 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2172 struct files_struct *fsp,
2173 uint32 security_info_sent,
2174 const struct security_descriptor *psd)
2176 VFS_FIND(fset_nt_acl);
2177 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2178 psd);
2181 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2182 struct smb_filename *file,
2183 struct security_acl *sacl,
2184 uint32_t access_requested,
2185 uint32_t access_denied)
2187 VFS_FIND(audit_file);
2188 return handle->fns->audit_file_fn(handle,
2189 file,
2190 sacl,
2191 access_requested,
2192 access_denied);
2195 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2196 mode_t mode)
2198 VFS_FIND(chmod_acl);
2199 return handle->fns->chmod_acl_fn(handle, name, mode);
2202 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2203 struct files_struct *fsp, mode_t mode)
2205 VFS_FIND(fchmod_acl);
2206 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2209 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2210 const char *path_p,
2211 SMB_ACL_TYPE_T type)
2213 VFS_FIND(sys_acl_get_file);
2214 return handle->fns->sys_acl_get_file_fn(handle, path_p, type);
2217 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2218 struct files_struct *fsp)
2220 VFS_FIND(sys_acl_get_fd);
2221 return handle->fns->sys_acl_get_fd_fn(handle, fsp);
2224 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2225 const char *path_p,
2226 SMB_ACL_TYPE_T type,
2227 TALLOC_CTX *mem_ctx,
2228 char **blob_description,
2229 DATA_BLOB *blob)
2231 VFS_FIND(sys_acl_blob_get_file);
2232 return handle->fns->sys_acl_blob_get_file_fn(handle, path_p, type, mem_ctx, blob_description, blob);
2235 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2236 struct files_struct *fsp,
2237 TALLOC_CTX *mem_ctx,
2238 char **blob_description,
2239 DATA_BLOB *blob)
2241 VFS_FIND(sys_acl_blob_get_fd);
2242 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2245 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2246 const char *name, SMB_ACL_TYPE_T acltype,
2247 SMB_ACL_T theacl)
2249 VFS_FIND(sys_acl_set_file);
2250 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2253 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2254 struct files_struct *fsp, SMB_ACL_T theacl)
2256 VFS_FIND(sys_acl_set_fd);
2257 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2260 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2261 const char *path)
2263 VFS_FIND(sys_acl_delete_def_file);
2264 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2267 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2268 const char *path, const char *name, void *value,
2269 size_t size)
2271 VFS_FIND(getxattr);
2272 return handle->fns->getxattr_fn(handle, path, name, value, size);
2275 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2276 struct files_struct *fsp, const char *name,
2277 void *value, size_t size)
2279 VFS_FIND(fgetxattr);
2280 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2283 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2284 const char *path, char *list, size_t size)
2286 VFS_FIND(listxattr);
2287 return handle->fns->listxattr_fn(handle, path, list, size);
2290 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2291 struct files_struct *fsp, char *list,
2292 size_t size)
2294 VFS_FIND(flistxattr);
2295 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2298 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2299 const char *path, const char *name)
2301 VFS_FIND(removexattr);
2302 return handle->fns->removexattr_fn(handle, path, name);
2305 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2306 struct files_struct *fsp, const char *name)
2308 VFS_FIND(fremovexattr);
2309 return handle->fns->fremovexattr_fn(handle, fsp, name);
2312 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2313 const char *name, const void *value, size_t size,
2314 int flags)
2316 VFS_FIND(setxattr);
2317 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2320 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2321 struct files_struct *fsp, const char *name,
2322 const void *value, size_t size, int flags)
2324 VFS_FIND(fsetxattr);
2325 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2328 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2329 struct files_struct *fsp)
2331 VFS_FIND(aio_force);
2332 return handle->fns->aio_force_fn(handle, fsp);
2335 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2336 const struct smb_filename *fname,
2337 SMB_STRUCT_STAT *sbuf)
2339 VFS_FIND(is_offline);
2340 return handle->fns->is_offline_fn(handle, fname, sbuf);
2343 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2344 const struct smb_filename *fname)
2346 VFS_FIND(set_offline);
2347 return handle->fns->set_offline_fn(handle, fname);
2350 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2351 struct files_struct *fsp,
2352 TALLOC_CTX *mem_ctx,
2353 DATA_BLOB *cookie)
2355 VFS_FIND(durable_cookie);
2356 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2359 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2360 struct files_struct *fsp,
2361 const DATA_BLOB old_cookie,
2362 TALLOC_CTX *mem_ctx,
2363 DATA_BLOB *new_cookie)
2365 VFS_FIND(durable_disconnect);
2366 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2367 mem_ctx, new_cookie);
2370 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2371 struct smb_request *smb1req,
2372 struct smbXsrv_open *op,
2373 const DATA_BLOB old_cookie,
2374 TALLOC_CTX *mem_ctx,
2375 struct files_struct **fsp,
2376 DATA_BLOB *new_cookie)
2378 VFS_FIND(durable_reconnect);
2379 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2380 old_cookie, mem_ctx, fsp,
2381 new_cookie);