s3:vfs: add durable VFS operations
[Samba/gebeck_regimport.git] / source3 / smbd / vfs.c
blobbb9549c887015e917efaae63b4a378cbcb9ce852
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 res;
804 if (!LastDir) {
805 LastDir = SMB_STRDUP("");
808 if (strcsequal(path,"."))
809 return(0);
811 if (*path == '/' && strcsequal(LastDir,path))
812 return(0);
814 DEBUG(4,("vfs_ChDir to %s\n",path));
816 res = SMB_VFS_CHDIR(conn,path);
817 if (!res) {
818 SAFE_FREE(LastDir);
819 LastDir = SMB_STRDUP(path);
821 return(res);
824 /*******************************************************************
825 Return the absolute current directory path - given a UNIX pathname.
826 Note that this path is returned in DOS format, not UNIX
827 format. Note this can be called with conn == NULL.
828 ********************************************************************/
830 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
832 char *current_dir = NULL;
833 char *result = NULL;
834 DATA_BLOB cache_value;
835 struct file_id key;
836 struct smb_filename *smb_fname_dot = NULL;
837 struct smb_filename *smb_fname_full = NULL;
838 NTSTATUS status;
840 if (!lp_getwd_cache()) {
841 goto nocache;
844 status = create_synthetic_smb_fname(ctx, ".", NULL, NULL,
845 &smb_fname_dot);
846 if (!NT_STATUS_IS_OK(status)) {
847 errno = map_errno_from_nt_status(status);
848 goto out;
851 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
853 * Known to fail for root: the directory may be NFS-mounted
854 * and exported with root_squash (so has no root access).
856 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
857 "(NFS problem ?)\n", strerror(errno) ));
858 goto nocache;
861 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
863 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
864 data_blob_const(&key, sizeof(key)),
865 &cache_value)) {
866 goto nocache;
869 SMB_ASSERT((cache_value.length > 0)
870 && (cache_value.data[cache_value.length-1] == '\0'));
872 status = create_synthetic_smb_fname(ctx, (char *)cache_value.data,
873 NULL, NULL, &smb_fname_full);
874 if (!NT_STATUS_IS_OK(status)) {
875 errno = map_errno_from_nt_status(status);
876 goto out;
879 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
880 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
881 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
882 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
884 * Ok, we're done
886 result = talloc_strdup(ctx, smb_fname_full->base_name);
887 if (result == NULL) {
888 errno = ENOMEM;
890 goto out;
893 nocache:
896 * We don't have the information to hand so rely on traditional
897 * methods. The very slow getcwd, which spawns a process on some
898 * systems, or the not quite so bad getwd.
901 current_dir = SMB_VFS_GETWD(conn);
902 if (current_dir == NULL) {
903 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
904 strerror(errno)));
905 goto out;
908 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
909 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
911 memcache_add(smbd_memcache(), GETWD_CACHE,
912 data_blob_const(&key, sizeof(key)),
913 data_blob_const(current_dir,
914 strlen(current_dir)+1));
917 result = talloc_strdup(ctx, current_dir);
918 if (result == NULL) {
919 errno = ENOMEM;
922 out:
923 TALLOC_FREE(smb_fname_dot);
924 TALLOC_FREE(smb_fname_full);
925 SAFE_FREE(current_dir);
926 return result;
929 /*******************************************************************
930 Reduce a file name, removing .. elements and checking that
931 it is below dir in the heirachy. This uses realpath.
932 This function must run as root, and will return names
933 and valid stat structs that can be checked on open.
934 ********************************************************************/
936 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
937 const char *fname,
938 struct smb_request *smbreq)
940 NTSTATUS status;
941 TALLOC_CTX *ctx = talloc_tos();
942 const char *conn_rootdir;
943 size_t rootdir_len;
944 char *dir_name = NULL;
945 const char *last_component = NULL;
946 char *resolved_name = NULL;
947 char *saved_dir = NULL;
948 struct smb_filename *smb_fname_cwd = NULL;
949 struct privilege_paths *priv_paths = NULL;
950 int ret;
952 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
953 fname,
954 conn->connectpath));
957 priv_paths = talloc_zero(smbreq, struct privilege_paths);
958 if (!priv_paths) {
959 status = NT_STATUS_NO_MEMORY;
960 goto err;
963 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
964 status = NT_STATUS_NO_MEMORY;
965 goto err;
968 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
969 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
971 if (priv_paths->parent_name.base_name == NULL ||
972 priv_paths->file_name.base_name == NULL) {
973 status = NT_STATUS_NO_MEMORY;
974 goto err;
977 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
978 status = map_nt_error_from_unix(errno);
979 goto err;
981 /* Remember where we were. */
982 saved_dir = vfs_GetWd(ctx, conn);
983 if (!saved_dir) {
984 status = map_nt_error_from_unix(errno);
985 goto err;
988 /* Go to the parent directory to lock in memory. */
989 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
990 status = map_nt_error_from_unix(errno);
991 goto err;
994 /* Get the absolute path of the parent directory. */
995 resolved_name = SMB_VFS_REALPATH(conn,".");
996 if (!resolved_name) {
997 status = map_nt_error_from_unix(errno);
998 goto err;
1001 if (*resolved_name != '/') {
1002 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1003 "doesn't return absolute paths !\n"));
1004 status = NT_STATUS_OBJECT_NAME_INVALID;
1005 goto err;
1008 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1009 priv_paths->parent_name.base_name,
1010 resolved_name));
1012 /* Now check the stat value is the same. */
1013 status = create_synthetic_smb_fname(talloc_tos(), ".",
1014 NULL, NULL,
1015 &smb_fname_cwd);
1016 if (!NT_STATUS_IS_OK(status)) {
1017 goto err;
1020 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1021 status = map_nt_error_from_unix(errno);
1022 goto err;
1025 /* Ensure we're pointing at the same place. */
1026 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1027 DEBUG(0,("check_reduced_name_with_privilege: "
1028 "device/inode/uid/gid on directory %s changed. "
1029 "Denying access !\n",
1030 priv_paths->parent_name.base_name));
1031 status = NT_STATUS_ACCESS_DENIED;
1032 goto err;
1035 /* Ensure we're below the connect path. */
1037 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1038 if (conn_rootdir == NULL) {
1039 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1040 "conn_rootdir\n"));
1041 status = NT_STATUS_ACCESS_DENIED;
1042 goto err;
1045 rootdir_len = strlen(conn_rootdir);
1046 if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1047 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1048 "attempt: %s is a symlink outside the "
1049 "share path\n",
1050 dir_name));
1051 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1052 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1053 status = NT_STATUS_ACCESS_DENIED;
1054 goto err;
1057 /* Now ensure that the last component either doesn't
1058 exist, or is *NOT* a symlink. */
1060 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1061 if (ret == -1) {
1062 /* Errno must be ENOENT for this be ok. */
1063 if (errno != ENOENT) {
1064 status = map_nt_error_from_unix(errno);
1065 DEBUG(2, ("check_reduced_name_with_privilege: "
1066 "LSTAT on %s failed with %s\n",
1067 priv_paths->file_name.base_name,
1068 nt_errstr(status)));
1069 goto err;
1073 if (VALID_STAT(priv_paths->file_name.st) &&
1074 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1075 DEBUG(2, ("check_reduced_name_with_privilege: "
1076 "Last component %s is a symlink. Denying"
1077 "access.\n",
1078 priv_paths->file_name.base_name));
1079 status = NT_STATUS_ACCESS_DENIED;
1080 goto err;
1083 smbreq->priv_paths = priv_paths;
1084 status = NT_STATUS_OK;
1086 err:
1088 if (saved_dir) {
1089 vfs_ChDir(conn, saved_dir);
1091 SAFE_FREE(resolved_name);
1092 if (!NT_STATUS_IS_OK(status)) {
1093 TALLOC_FREE(priv_paths);
1095 TALLOC_FREE(dir_name);
1096 return status;
1099 /*******************************************************************
1100 Reduce a file name, removing .. elements and checking that
1101 it is below dir in the heirachy. This uses realpath.
1102 ********************************************************************/
1104 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1106 char *resolved_name = NULL;
1107 bool allow_symlinks = true;
1108 bool allow_widelinks = false;
1110 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1112 resolved_name = SMB_VFS_REALPATH(conn,fname);
1114 if (!resolved_name) {
1115 switch (errno) {
1116 case ENOTDIR:
1117 DEBUG(3,("check_reduced_name: Component not a "
1118 "directory in getting realpath for "
1119 "%s\n", fname));
1120 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1121 case ENOENT:
1123 TALLOC_CTX *ctx = talloc_tos();
1124 char *dir_name = NULL;
1125 const char *last_component = NULL;
1126 char *new_name = NULL;
1127 int ret;
1129 /* Last component didn't exist.
1130 Remove it and try and canonicalise
1131 the directory name. */
1132 if (!parent_dirname(ctx, fname,
1133 &dir_name,
1134 &last_component)) {
1135 return NT_STATUS_NO_MEMORY;
1138 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1139 if (!resolved_name) {
1140 NTSTATUS status = map_nt_error_from_unix(errno);
1142 if (errno == ENOENT || errno == ENOTDIR) {
1143 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1146 DEBUG(3,("check_reduce_name: "
1147 "couldn't get realpath for "
1148 "%s (%s)\n",
1149 fname,
1150 nt_errstr(status)));
1151 return status;
1153 ret = asprintf(&new_name, "%s/%s",
1154 resolved_name, last_component);
1155 SAFE_FREE(resolved_name);
1156 if (ret == -1) {
1157 return NT_STATUS_NO_MEMORY;
1159 resolved_name = new_name;
1160 break;
1162 default:
1163 DEBUG(3,("check_reduced_name: couldn't get "
1164 "realpath for %s\n", fname));
1165 return map_nt_error_from_unix(errno);
1169 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1170 resolved_name));
1172 if (*resolved_name != '/') {
1173 DEBUG(0,("check_reduced_name: realpath doesn't return "
1174 "absolute paths !\n"));
1175 SAFE_FREE(resolved_name);
1176 return NT_STATUS_OBJECT_NAME_INVALID;
1179 allow_widelinks = lp_widelinks(SNUM(conn));
1180 allow_symlinks = lp_symlinks(SNUM(conn));
1182 /* Common widelinks and symlinks checks. */
1183 if (!allow_widelinks || !allow_symlinks) {
1184 const char *conn_rootdir;
1185 size_t rootdir_len;
1187 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1188 if (conn_rootdir == NULL) {
1189 DEBUG(2, ("check_reduced_name: Could not get "
1190 "conn_rootdir\n"));
1191 SAFE_FREE(resolved_name);
1192 return NT_STATUS_ACCESS_DENIED;
1195 rootdir_len = strlen(conn_rootdir);
1196 if (strncmp(conn_rootdir, resolved_name,
1197 rootdir_len) != 0) {
1198 DEBUG(2, ("check_reduced_name: Bad access "
1199 "attempt: %s is a symlink outside the "
1200 "share path\n", fname));
1201 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1202 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1203 SAFE_FREE(resolved_name);
1204 return NT_STATUS_ACCESS_DENIED;
1207 /* Extra checks if all symlinks are disallowed. */
1208 if (!allow_symlinks) {
1209 /* fname can't have changed in resolved_path. */
1210 const char *p = &resolved_name[rootdir_len];
1212 /* *p can be '\0' if fname was "." */
1213 if (*p == '\0' && ISDOT(fname)) {
1214 goto out;
1217 if (*p != '/') {
1218 DEBUG(2, ("check_reduced_name: logic error (%c) "
1219 "in resolved_name: %s\n",
1221 fname));
1222 SAFE_FREE(resolved_name);
1223 return NT_STATUS_ACCESS_DENIED;
1226 p++;
1227 if (strcmp(fname, p)!=0) {
1228 DEBUG(2, ("check_reduced_name: Bad access "
1229 "attempt: %s is a symlink to %s\n",
1230 fname, p));
1231 SAFE_FREE(resolved_name);
1232 return NT_STATUS_ACCESS_DENIED;
1237 out:
1239 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1240 resolved_name));
1241 SAFE_FREE(resolved_name);
1242 return NT_STATUS_OK;
1246 * XXX: This is temporary and there should be no callers of this once
1247 * smb_filename is plumbed through all path based operations.
1249 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1250 SMB_STRUCT_STAT *psbuf)
1252 struct smb_filename *smb_fname = NULL;
1253 NTSTATUS status;
1254 int ret;
1256 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1257 &smb_fname);
1258 if (!NT_STATUS_IS_OK(status)) {
1259 errno = map_errno_from_nt_status(status);
1260 return -1;
1263 if (lp_posix_pathnames()) {
1264 ret = SMB_VFS_LSTAT(conn, smb_fname);
1265 } else {
1266 ret = SMB_VFS_STAT(conn, smb_fname);
1269 if (ret != -1) {
1270 *psbuf = smb_fname->st;
1273 TALLOC_FREE(smb_fname);
1274 return ret;
1278 * XXX: This is temporary and there should be no callers of this once
1279 * smb_filename is plumbed through all path based operations.
1281 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1282 SMB_STRUCT_STAT *psbuf)
1284 struct smb_filename *smb_fname = NULL;
1285 NTSTATUS status;
1286 int ret;
1288 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1289 &smb_fname);
1290 if (!NT_STATUS_IS_OK(status)) {
1291 errno = map_errno_from_nt_status(status);
1292 return -1;
1295 ret = SMB_VFS_LSTAT(conn, smb_fname);
1296 if (ret != -1) {
1297 *psbuf = smb_fname->st;
1300 TALLOC_FREE(smb_fname);
1301 return ret;
1305 * Ensure LSTAT is called for POSIX paths.
1308 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1310 int ret;
1312 if(fsp->fh->fd == -1) {
1313 if (fsp->posix_open) {
1314 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1315 } else {
1316 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1318 if (ret == -1) {
1319 return map_nt_error_from_unix(errno);
1321 } else {
1322 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1323 return map_nt_error_from_unix(errno);
1326 return NT_STATUS_OK;
1330 * Initialize num_streams and streams, then call VFS op streaminfo
1332 NTSTATUS vfs_streaminfo(connection_struct *conn,
1333 struct files_struct *fsp,
1334 const char *fname,
1335 TALLOC_CTX *mem_ctx,
1336 unsigned int *num_streams,
1337 struct stream_struct **streams)
1339 *num_streams = 0;
1340 *streams = NULL;
1341 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1345 generate a file_id from a stat structure
1347 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1349 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1352 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1353 const char *service, const char *user)
1355 VFS_FIND(connect);
1356 return handle->fns->connect_fn(handle, service, user);
1359 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1361 VFS_FIND(disconnect);
1362 handle->fns->disconnect_fn(handle);
1365 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1366 const char *path, bool small_query,
1367 uint64_t *bsize, uint64_t *dfree,
1368 uint64_t *dsize)
1370 VFS_FIND(disk_free);
1371 return handle->fns->disk_free_fn(handle, path, small_query, bsize,
1372 dfree, dsize);
1375 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1376 enum SMB_QUOTA_TYPE qtype, unid_t id,
1377 SMB_DISK_QUOTA *qt)
1379 VFS_FIND(get_quota);
1380 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1383 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1384 enum SMB_QUOTA_TYPE qtype, unid_t id,
1385 SMB_DISK_QUOTA *qt)
1387 VFS_FIND(set_quota);
1388 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1391 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1392 struct files_struct *fsp,
1393 struct shadow_copy_data *shadow_copy_data,
1394 bool labels)
1396 VFS_FIND(get_shadow_copy_data);
1397 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1398 shadow_copy_data,
1399 labels);
1401 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1402 struct vfs_statvfs_struct *statbuf)
1404 VFS_FIND(statvfs);
1405 return handle->fns->statvfs_fn(handle, path, statbuf);
1408 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1409 enum timestamp_set_resolution *p_ts_res)
1411 VFS_FIND(fs_capabilities);
1412 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1415 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1416 struct dfs_GetDFSReferral *r)
1418 VFS_FIND(get_dfs_referrals);
1419 return handle->fns->get_dfs_referrals_fn(handle, r);
1422 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1423 const char *fname, const char *mask,
1424 uint32 attributes)
1426 VFS_FIND(opendir);
1427 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1430 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1431 struct files_struct *fsp,
1432 const char *mask,
1433 uint32 attributes)
1435 VFS_FIND(fdopendir);
1436 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1439 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1440 DIR *dirp,
1441 SMB_STRUCT_STAT *sbuf)
1443 VFS_FIND(readdir);
1444 return handle->fns->readdir_fn(handle, dirp, sbuf);
1447 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1448 DIR *dirp, long offset)
1450 VFS_FIND(seekdir);
1451 handle->fns->seekdir_fn(handle, dirp, offset);
1454 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1455 DIR *dirp)
1457 VFS_FIND(telldir);
1458 return handle->fns->telldir_fn(handle, dirp);
1461 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1462 DIR *dirp)
1464 VFS_FIND(rewind_dir);
1465 handle->fns->rewind_dir_fn(handle, dirp);
1468 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1469 mode_t mode)
1471 VFS_FIND(mkdir);
1472 return handle->fns->mkdir_fn(handle, path, mode);
1475 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1477 VFS_FIND(rmdir);
1478 return handle->fns->rmdir_fn(handle, path);
1481 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1482 DIR *dir)
1484 VFS_FIND(closedir);
1485 return handle->fns->closedir_fn(handle, dir);
1488 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1489 DIR *dirp)
1491 VFS_FIND(init_search_op);
1492 handle->fns->init_search_op_fn(handle, dirp);
1495 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1496 struct smb_filename *smb_fname, struct files_struct *fsp,
1497 int flags, mode_t mode)
1499 VFS_FIND(open);
1500 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1503 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1504 struct smb_request *req,
1505 uint16_t root_dir_fid,
1506 struct smb_filename *smb_fname,
1507 uint32_t access_mask,
1508 uint32_t share_access,
1509 uint32_t create_disposition,
1510 uint32_t create_options,
1511 uint32_t file_attributes,
1512 uint32_t oplock_request,
1513 uint64_t allocation_size,
1514 uint32_t private_flags,
1515 struct security_descriptor *sd,
1516 struct ea_list *ea_list,
1517 files_struct **result,
1518 int *pinfo)
1520 VFS_FIND(create_file);
1521 return handle->fns->create_file_fn(
1522 handle, req, root_dir_fid, smb_fname, access_mask,
1523 share_access, create_disposition, create_options,
1524 file_attributes, oplock_request, allocation_size,
1525 private_flags, sd, ea_list,
1526 result, pinfo);
1529 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1530 struct files_struct *fsp)
1532 VFS_FIND(close);
1533 return handle->fns->close_fn(handle, fsp);
1536 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1537 struct files_struct *fsp, void *data, size_t n)
1539 VFS_FIND(read);
1540 return handle->fns->read_fn(handle, fsp, data, n);
1543 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1544 struct files_struct *fsp, void *data, size_t n,
1545 off_t offset)
1547 VFS_FIND(pread);
1548 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1551 struct smb_vfs_call_pread_state {
1552 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1553 ssize_t retval;
1556 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1558 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1559 TALLOC_CTX *mem_ctx,
1560 struct tevent_context *ev,
1561 struct files_struct *fsp,
1562 void *data,
1563 size_t n, off_t offset)
1565 struct tevent_req *req, *subreq;
1566 struct smb_vfs_call_pread_state *state;
1568 req = tevent_req_create(mem_ctx, &state,
1569 struct smb_vfs_call_pread_state);
1570 if (req == NULL) {
1571 return NULL;
1573 VFS_FIND(pread_send);
1574 state->recv_fn = handle->fns->pread_recv_fn;
1576 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1577 offset);
1578 if (tevent_req_nomem(subreq, req)) {
1579 return tevent_req_post(req, ev);
1581 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1582 return req;
1585 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1587 struct tevent_req *req = tevent_req_callback_data(
1588 subreq, struct tevent_req);
1589 struct smb_vfs_call_pread_state *state = tevent_req_data(
1590 req, struct smb_vfs_call_pread_state);
1591 int err;
1593 state->retval = state->recv_fn(subreq, &err);
1594 TALLOC_FREE(subreq);
1595 if (state->retval == -1) {
1596 tevent_req_error(req, err);
1597 return;
1599 tevent_req_done(req);
1602 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req, int *perrno)
1604 struct smb_vfs_call_pread_state *state = tevent_req_data(
1605 req, struct smb_vfs_call_pread_state);
1606 int err;
1608 if (tevent_req_is_unix_error(req, &err)) {
1609 *perrno = err;
1610 return -1;
1612 return state->retval;
1615 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1616 struct files_struct *fsp, const void *data,
1617 size_t n)
1619 VFS_FIND(write);
1620 return handle->fns->write_fn(handle, fsp, data, n);
1623 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1624 struct files_struct *fsp, const void *data,
1625 size_t n, off_t offset)
1627 VFS_FIND(pwrite);
1628 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1631 struct smb_vfs_call_pwrite_state {
1632 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1633 ssize_t retval;
1636 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1638 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1639 TALLOC_CTX *mem_ctx,
1640 struct tevent_context *ev,
1641 struct files_struct *fsp,
1642 const void *data,
1643 size_t n, off_t offset)
1645 struct tevent_req *req, *subreq;
1646 struct smb_vfs_call_pwrite_state *state;
1648 req = tevent_req_create(mem_ctx, &state,
1649 struct smb_vfs_call_pwrite_state);
1650 if (req == NULL) {
1651 return NULL;
1653 VFS_FIND(pwrite_send);
1654 state->recv_fn = handle->fns->pwrite_recv_fn;
1656 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1657 offset);
1658 if (tevent_req_nomem(subreq, req)) {
1659 return tevent_req_post(req, ev);
1661 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1662 return req;
1665 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1667 struct tevent_req *req = tevent_req_callback_data(
1668 subreq, struct tevent_req);
1669 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1670 req, struct smb_vfs_call_pwrite_state);
1671 int err;
1673 state->retval = state->recv_fn(subreq, &err);
1674 TALLOC_FREE(subreq);
1675 if (state->retval == -1) {
1676 tevent_req_error(req, err);
1677 return;
1679 tevent_req_done(req);
1682 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req, int *perrno)
1684 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1685 req, struct smb_vfs_call_pwrite_state);
1686 int err;
1688 if (tevent_req_is_unix_error(req, &err)) {
1689 *perrno = err;
1690 return -1;
1692 return state->retval;
1695 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1696 struct files_struct *fsp, off_t offset,
1697 int whence)
1699 VFS_FIND(lseek);
1700 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1703 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1704 files_struct *fromfsp, const DATA_BLOB *header,
1705 off_t offset, size_t count)
1707 VFS_FIND(sendfile);
1708 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1709 count);
1712 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1713 files_struct *tofsp, off_t offset,
1714 size_t count)
1716 VFS_FIND(recvfile);
1717 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1720 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1721 const struct smb_filename *smb_fname_src,
1722 const struct smb_filename *smb_fname_dst)
1724 VFS_FIND(rename);
1725 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1728 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1729 struct files_struct *fsp)
1731 VFS_FIND(fsync);
1732 return handle->fns->fsync_fn(handle, fsp);
1735 struct smb_vfs_call_fsync_state {
1736 int (*recv_fn)(struct tevent_req *req, int *err);
1737 int retval;
1740 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1742 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1743 TALLOC_CTX *mem_ctx,
1744 struct tevent_context *ev,
1745 struct files_struct *fsp)
1747 struct tevent_req *req, *subreq;
1748 struct smb_vfs_call_fsync_state *state;
1750 req = tevent_req_create(mem_ctx, &state,
1751 struct smb_vfs_call_fsync_state);
1752 if (req == NULL) {
1753 return NULL;
1755 VFS_FIND(fsync_send);
1756 state->recv_fn = handle->fns->fsync_recv_fn;
1758 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1759 if (tevent_req_nomem(subreq, req)) {
1760 return tevent_req_post(req, ev);
1762 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1763 return req;
1766 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1768 struct tevent_req *req = tevent_req_callback_data(
1769 subreq, struct tevent_req);
1770 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1771 req, struct smb_vfs_call_fsync_state);
1772 int err;
1774 state->retval = state->recv_fn(subreq, &err);
1775 TALLOC_FREE(subreq);
1776 if (state->retval == -1) {
1777 tevent_req_error(req, err);
1778 return;
1780 tevent_req_done(req);
1783 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, int *perrno)
1785 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1786 req, struct smb_vfs_call_fsync_state);
1787 int err;
1789 if (tevent_req_is_unix_error(req, &err)) {
1790 *perrno = err;
1791 return -1;
1793 return state->retval;
1797 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1798 struct smb_filename *smb_fname)
1800 VFS_FIND(stat);
1801 return handle->fns->stat_fn(handle, smb_fname);
1804 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1805 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1807 VFS_FIND(fstat);
1808 return handle->fns->fstat_fn(handle, fsp, sbuf);
1811 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1812 struct smb_filename *smb_filename)
1814 VFS_FIND(lstat);
1815 return handle->fns->lstat_fn(handle, smb_filename);
1818 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1819 struct files_struct *fsp,
1820 const SMB_STRUCT_STAT *sbuf)
1822 VFS_FIND(get_alloc_size);
1823 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1826 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1827 const struct smb_filename *smb_fname)
1829 VFS_FIND(unlink);
1830 return handle->fns->unlink_fn(handle, smb_fname);
1833 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1834 mode_t mode)
1836 VFS_FIND(chmod);
1837 return handle->fns->chmod_fn(handle, path, mode);
1840 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1841 struct files_struct *fsp, mode_t mode)
1843 VFS_FIND(fchmod);
1844 return handle->fns->fchmod_fn(handle, fsp, mode);
1847 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1848 uid_t uid, gid_t gid)
1850 VFS_FIND(chown);
1851 return handle->fns->chown_fn(handle, path, uid, gid);
1854 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1855 struct files_struct *fsp, uid_t uid, gid_t gid)
1857 VFS_FIND(fchown);
1858 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1861 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1862 uid_t uid, gid_t gid)
1864 VFS_FIND(lchown);
1865 return handle->fns->lchown_fn(handle, path, uid, gid);
1868 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1870 int ret;
1871 bool as_root = false;
1872 const char *path;
1873 char *saved_dir = NULL;
1874 char *parent_dir = NULL;
1875 NTSTATUS status;
1877 if (fsp->fh->fd != -1) {
1878 /* Try fchown. */
1879 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1880 if (ret == 0) {
1881 return NT_STATUS_OK;
1883 if (ret == -1 && errno != ENOSYS) {
1884 return map_nt_error_from_unix(errno);
1888 as_root = (geteuid() == 0);
1890 if (as_root) {
1892 * We are being asked to chown as root. Make
1893 * sure we chdir() into the path to pin it,
1894 * and always act using lchown to ensure we
1895 * don't deref any symbolic links.
1897 const char *final_component = NULL;
1898 struct smb_filename local_fname;
1900 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1901 if (!saved_dir) {
1902 status = map_nt_error_from_unix(errno);
1903 DEBUG(0,("vfs_chown_fsp: failed to get "
1904 "current working directory. Error was %s\n",
1905 strerror(errno)));
1906 return status;
1909 if (!parent_dirname(talloc_tos(),
1910 fsp->fsp_name->base_name,
1911 &parent_dir,
1912 &final_component)) {
1913 return NT_STATUS_NO_MEMORY;
1916 /* cd into the parent dir to pin it. */
1917 ret = vfs_ChDir(fsp->conn, parent_dir);
1918 if (ret == -1) {
1919 return map_nt_error_from_unix(errno);
1922 ZERO_STRUCT(local_fname);
1923 local_fname.base_name = discard_const_p(char, final_component);
1925 /* Must use lstat here. */
1926 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1927 if (ret == -1) {
1928 status = map_nt_error_from_unix(errno);
1929 goto out;
1932 /* Ensure it matches the fsp stat. */
1933 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1934 status = NT_STATUS_ACCESS_DENIED;
1935 goto out;
1937 path = final_component;
1938 } else {
1939 path = fsp->fsp_name->base_name;
1942 if (fsp->posix_open || as_root) {
1943 ret = SMB_VFS_LCHOWN(fsp->conn,
1944 path,
1945 uid, gid);
1946 } else {
1947 ret = SMB_VFS_CHOWN(fsp->conn,
1948 path,
1949 uid, gid);
1952 if (ret == 0) {
1953 status = NT_STATUS_OK;
1954 } else {
1955 status = map_nt_error_from_unix(errno);
1958 out:
1960 if (as_root) {
1961 vfs_ChDir(fsp->conn,saved_dir);
1962 TALLOC_FREE(saved_dir);
1963 TALLOC_FREE(parent_dir);
1965 return status;
1968 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1970 VFS_FIND(chdir);
1971 return handle->fns->chdir_fn(handle, path);
1974 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
1976 VFS_FIND(getwd);
1977 return handle->fns->getwd_fn(handle);
1980 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
1981 const struct smb_filename *smb_fname,
1982 struct smb_file_time *ft)
1984 VFS_FIND(ntimes);
1985 return handle->fns->ntimes_fn(handle, smb_fname, ft);
1988 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
1989 struct files_struct *fsp, off_t offset)
1991 VFS_FIND(ftruncate);
1992 return handle->fns->ftruncate_fn(handle, fsp, offset);
1995 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
1996 struct files_struct *fsp,
1997 enum vfs_fallocate_mode mode,
1998 off_t offset,
1999 off_t len)
2001 VFS_FIND(fallocate);
2002 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2005 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2006 struct files_struct *fsp, uint32 share_mode,
2007 uint32_t access_mask)
2009 VFS_FIND(kernel_flock);
2010 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2011 access_mask);
2014 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2015 struct files_struct *fsp, int leasetype)
2017 VFS_FIND(linux_setlease);
2018 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2021 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
2022 const char *newpath)
2024 VFS_FIND(symlink);
2025 return handle->fns->symlink_fn(handle, oldpath, newpath);
2028 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2029 const char *path, char *buf, size_t bufsiz)
2031 VFS_FIND(readlink);
2032 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
2035 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
2036 const char *newpath)
2038 VFS_FIND(link);
2039 return handle->fns->link_fn(handle, oldpath, newpath);
2042 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
2043 mode_t mode, SMB_DEV_T dev)
2045 VFS_FIND(mknod);
2046 return handle->fns->mknod_fn(handle, path, mode, dev);
2049 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
2051 VFS_FIND(realpath);
2052 return handle->fns->realpath_fn(handle, path);
2055 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
2056 struct sys_notify_context *ctx,
2057 const char *path,
2058 uint32_t *filter,
2059 uint32_t *subdir_filter,
2060 void (*callback)(struct sys_notify_context *ctx,
2061 void *private_data,
2062 struct notify_event *ev),
2063 void *private_data, void *handle_p)
2065 VFS_FIND(notify_watch);
2066 return handle->fns->notify_watch_fn(handle, ctx, path,
2067 filter, subdir_filter, callback,
2068 private_data, handle_p);
2071 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
2072 unsigned int flags)
2074 VFS_FIND(chflags);
2075 return handle->fns->chflags_fn(handle, path, flags);
2078 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2079 const SMB_STRUCT_STAT *sbuf)
2081 VFS_FIND(file_id_create);
2082 return handle->fns->file_id_create_fn(handle, sbuf);
2085 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2086 struct files_struct *fsp,
2087 const char *fname,
2088 TALLOC_CTX *mem_ctx,
2089 unsigned int *num_streams,
2090 struct stream_struct **streams)
2092 VFS_FIND(streaminfo);
2093 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
2094 num_streams, streams);
2097 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2098 const char *path, const char *name,
2099 TALLOC_CTX *mem_ctx, char **found_name)
2101 VFS_FIND(get_real_filename);
2102 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2103 found_name);
2106 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2107 const char *filename)
2109 VFS_FIND(connectpath);
2110 return handle->fns->connectpath_fn(handle, filename);
2113 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2114 struct files_struct *fsp,
2115 struct lock_struct *plock)
2117 VFS_FIND(strict_lock);
2118 return handle->fns->strict_lock_fn(handle, fsp, plock);
2121 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2122 struct files_struct *fsp,
2123 struct lock_struct *plock)
2125 VFS_FIND(strict_unlock);
2126 handle->fns->strict_unlock_fn(handle, fsp, plock);
2129 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2130 const char *name,
2131 enum vfs_translate_direction direction,
2132 TALLOC_CTX *mem_ctx,
2133 char **mapped_name)
2135 VFS_FIND(translate_name);
2136 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2137 mapped_name);
2140 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2141 struct files_struct *fsp,
2142 TALLOC_CTX *ctx,
2143 uint32_t function,
2144 uint16_t req_flags,
2145 const uint8_t *in_data,
2146 uint32_t in_len,
2147 uint8_t **out_data,
2148 uint32_t max_out_len,
2149 uint32_t *out_len)
2151 VFS_FIND(fsctl);
2152 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2153 in_data, in_len, out_data, max_out_len,
2154 out_len);
2157 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2158 struct files_struct *fsp,
2159 uint32 security_info,
2160 struct security_descriptor **ppdesc)
2162 VFS_FIND(fget_nt_acl);
2163 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2164 ppdesc);
2167 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2168 const char *name,
2169 uint32 security_info,
2170 struct security_descriptor **ppdesc)
2172 VFS_FIND(get_nt_acl);
2173 return handle->fns->get_nt_acl_fn(handle, name, security_info, ppdesc);
2176 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2177 struct files_struct *fsp,
2178 uint32 security_info_sent,
2179 const struct security_descriptor *psd)
2181 VFS_FIND(fset_nt_acl);
2182 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2183 psd);
2186 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2187 struct smb_filename *file,
2188 struct security_acl *sacl,
2189 uint32_t access_requested,
2190 uint32_t access_denied)
2192 VFS_FIND(audit_file);
2193 return handle->fns->audit_file_fn(handle,
2194 file,
2195 sacl,
2196 access_requested,
2197 access_denied);
2200 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2201 mode_t mode)
2203 VFS_FIND(chmod_acl);
2204 return handle->fns->chmod_acl_fn(handle, name, mode);
2207 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2208 struct files_struct *fsp, mode_t mode)
2210 VFS_FIND(fchmod_acl);
2211 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2214 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2215 const char *path_p,
2216 SMB_ACL_TYPE_T type)
2218 VFS_FIND(sys_acl_get_file);
2219 return handle->fns->sys_acl_get_file_fn(handle, path_p, type);
2222 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2223 struct files_struct *fsp)
2225 VFS_FIND(sys_acl_get_fd);
2226 return handle->fns->sys_acl_get_fd_fn(handle, fsp);
2229 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2230 const char *name, SMB_ACL_TYPE_T acltype,
2231 SMB_ACL_T theacl)
2233 VFS_FIND(sys_acl_set_file);
2234 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2237 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2238 struct files_struct *fsp, SMB_ACL_T theacl)
2240 VFS_FIND(sys_acl_set_fd);
2241 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2244 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2245 const char *path)
2247 VFS_FIND(sys_acl_delete_def_file);
2248 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2251 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2252 const char *path, const char *name, void *value,
2253 size_t size)
2255 VFS_FIND(getxattr);
2256 return handle->fns->getxattr_fn(handle, path, name, value, size);
2259 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2260 struct files_struct *fsp, const char *name,
2261 void *value, size_t size)
2263 VFS_FIND(fgetxattr);
2264 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2267 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2268 const char *path, char *list, size_t size)
2270 VFS_FIND(listxattr);
2271 return handle->fns->listxattr_fn(handle, path, list, size);
2274 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2275 struct files_struct *fsp, char *list,
2276 size_t size)
2278 VFS_FIND(flistxattr);
2279 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2282 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2283 const char *path, const char *name)
2285 VFS_FIND(removexattr);
2286 return handle->fns->removexattr_fn(handle, path, name);
2289 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2290 struct files_struct *fsp, const char *name)
2292 VFS_FIND(fremovexattr);
2293 return handle->fns->fremovexattr_fn(handle, fsp, name);
2296 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2297 const char *name, const void *value, size_t size,
2298 int flags)
2300 VFS_FIND(setxattr);
2301 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2304 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2305 struct files_struct *fsp, const char *name,
2306 const void *value, size_t size, int flags)
2308 VFS_FIND(fsetxattr);
2309 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2312 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2313 struct files_struct *fsp)
2315 VFS_FIND(aio_force);
2316 return handle->fns->aio_force_fn(handle, fsp);
2319 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2320 const struct smb_filename *fname,
2321 SMB_STRUCT_STAT *sbuf)
2323 VFS_FIND(is_offline);
2324 return handle->fns->is_offline_fn(handle, fname, sbuf);
2327 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2328 const struct smb_filename *fname)
2330 VFS_FIND(set_offline);
2331 return handle->fns->set_offline_fn(handle, fname);
2334 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2335 struct files_struct *fsp,
2336 TALLOC_CTX *mem_ctx,
2337 DATA_BLOB *cookie)
2339 VFS_FIND(durable_cookie);
2340 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2343 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2344 struct files_struct *fsp,
2345 const DATA_BLOB old_cookie,
2346 TALLOC_CTX *mem_ctx,
2347 DATA_BLOB *new_cookie)
2349 VFS_FIND(durable_disconnect);
2350 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2351 mem_ctx, new_cookie);
2354 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2355 struct smb_request *smb1req,
2356 struct smbXsrv_open *op,
2357 const DATA_BLOB old_cookie,
2358 TALLOC_CTX *mem_ctx,
2359 struct files_struct **fsp,
2360 DATA_BLOB *new_cookie)
2362 VFS_FIND(durable_reconnect);
2363 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2364 old_cookie, mem_ctx, fsp,
2365 new_cookie);