Revert "s3:smbd: set req->smb2req->compat_chain_fsp in file_fsp()"
[Samba/gebeck_regimport.git] / source3 / smbd / vfs.c
blob6d090a95de76a48312feb4110b07df0ed57b55ec
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"
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_VFS
37 static_decl_vfs;
39 struct vfs_fsp_data {
40 struct vfs_fsp_data *next;
41 struct vfs_handle_struct *owner;
42 void (*destroy)(void *p_data);
43 void *_dummy_;
44 /* NOTE: This structure contains four pointers so that we can guarantee
45 * that the end of the structure is always both 4-byte and 8-byte aligned.
49 struct vfs_init_function_entry {
50 char *name;
51 struct vfs_init_function_entry *prev, *next;
52 const struct vfs_fn_pointers *fns;
55 /****************************************************************************
56 maintain the list of available backends
57 ****************************************************************************/
59 static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
61 struct vfs_init_function_entry *entry = backends;
63 DEBUG(10, ("vfs_find_backend_entry called for %s\n", name));
65 while(entry) {
66 if (strcmp(entry->name, name)==0) return entry;
67 entry = entry->next;
70 return NULL;
73 NTSTATUS smb_register_vfs(int version, const char *name,
74 const struct vfs_fn_pointers *fns)
76 struct vfs_init_function_entry *entry = backends;
78 if ((version != SMB_VFS_INTERFACE_VERSION)) {
79 DEBUG(0, ("Failed to register vfs module.\n"
80 "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
81 "current SMB_VFS_INTERFACE_VERSION is %d.\n"
82 "Please recompile against the current Samba Version!\n",
83 version, SMB_VFS_INTERFACE_VERSION));
84 return NT_STATUS_OBJECT_TYPE_MISMATCH;
87 if (!name || !name[0]) {
88 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
89 return NT_STATUS_INVALID_PARAMETER;
92 if (vfs_find_backend_entry(name)) {
93 DEBUG(0,("VFS module %s already loaded!\n", name));
94 return NT_STATUS_OBJECT_NAME_COLLISION;
97 entry = SMB_XMALLOC_P(struct vfs_init_function_entry);
98 entry->name = smb_xstrdup(name);
99 entry->fns = fns;
101 DLIST_ADD(backends, entry);
102 DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
103 return NT_STATUS_OK;
106 /****************************************************************************
107 initialise default vfs hooks
108 ****************************************************************************/
110 static void vfs_init_default(connection_struct *conn)
112 DEBUG(3, ("Initialising default vfs hooks\n"));
113 vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME);
116 /****************************************************************************
117 initialise custom vfs hooks
118 ****************************************************************************/
120 bool vfs_init_custom(connection_struct *conn, const char *vfs_object)
122 char *module_path = NULL;
123 char *module_name = NULL;
124 char *module_param = NULL, *p;
125 vfs_handle_struct *handle;
126 const struct vfs_init_function_entry *entry;
128 if (!conn||!vfs_object||!vfs_object[0]) {
129 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
130 "empty vfs_object!\n"));
131 return False;
134 if(!backends) {
135 static_init_vfs;
138 DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
140 module_path = smb_xstrdup(vfs_object);
142 p = strchr_m(module_path, ':');
144 if (p) {
145 *p = 0;
146 module_param = p+1;
147 trim_char(module_param, ' ', ' ');
150 trim_char(module_path, ' ', ' ');
152 module_name = smb_xstrdup(module_path);
154 if ((module_name[0] == '/') &&
155 (strcmp(module_path, DEFAULT_VFS_MODULE_NAME) != 0)) {
158 * Extract the module name from the path. Just use the base
159 * name of the last path component.
162 SAFE_FREE(module_name);
163 module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
165 p = strchr_m(module_name, '.');
167 if (p != NULL) {
168 *p = '\0';
172 /* First, try to load the module with the new module system */
173 entry = vfs_find_backend_entry(module_name);
174 if (!entry) {
175 NTSTATUS status;
177 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
178 vfs_object));
180 status = smb_load_module("vfs", module_path);
181 if (!NT_STATUS_IS_OK(status)) {
182 DEBUG(0, ("error probing vfs module '%s': %s\n",
183 module_path, nt_errstr(status)));
184 goto fail;
187 entry = vfs_find_backend_entry(module_name);
188 if (!entry) {
189 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
190 goto fail;
194 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
196 handle = talloc_zero(conn, vfs_handle_struct);
197 if (!handle) {
198 DEBUG(0,("TALLOC_ZERO() failed!\n"));
199 goto fail;
201 handle->conn = conn;
202 handle->fns = entry->fns;
203 if (module_param) {
204 handle->param = talloc_strdup(conn, module_param);
206 DLIST_ADD(conn->vfs_handles, handle);
208 SAFE_FREE(module_path);
209 SAFE_FREE(module_name);
210 return True;
212 fail:
213 SAFE_FREE(module_path);
214 SAFE_FREE(module_name);
215 return False;
218 /*****************************************************************
219 Allow VFS modules to extend files_struct with VFS-specific state.
220 This will be ok for small numbers of extensions, but might need to
221 be refactored if it becomes more widely used.
222 ******************************************************************/
224 #define EXT_DATA_AREA(e) ((uint8 *)(e) + sizeof(struct vfs_fsp_data))
226 void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle,
227 files_struct *fsp, size_t ext_size,
228 void (*destroy_fn)(void *p_data))
230 struct vfs_fsp_data *ext;
231 void * ext_data;
233 /* Prevent VFS modules adding multiple extensions. */
234 if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
235 return ext_data;
238 ext = (struct vfs_fsp_data *)TALLOC_ZERO(
239 handle->conn, sizeof(struct vfs_fsp_data) + ext_size);
240 if (ext == NULL) {
241 return NULL;
244 ext->owner = handle;
245 ext->next = fsp->vfs_extension;
246 ext->destroy = destroy_fn;
247 fsp->vfs_extension = ext;
248 return EXT_DATA_AREA(ext);
251 void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
253 struct vfs_fsp_data *curr;
254 struct vfs_fsp_data *prev;
256 for (curr = fsp->vfs_extension, prev = NULL;
257 curr;
258 prev = curr, curr = curr->next) {
259 if (curr->owner == handle) {
260 if (prev) {
261 prev->next = curr->next;
262 } else {
263 fsp->vfs_extension = curr->next;
265 if (curr->destroy) {
266 curr->destroy(EXT_DATA_AREA(curr));
268 TALLOC_FREE(curr);
269 return;
274 void vfs_remove_all_fsp_extensions(files_struct *fsp)
276 struct vfs_fsp_data *curr;
277 struct vfs_fsp_data *prev;
279 for (curr = fsp->vfs_extension, prev = NULL;
280 curr;
281 prev = curr, curr = curr->next)
283 if (prev) {
284 prev->next = curr->next;
285 } else {
286 fsp->vfs_extension = curr->next;
288 if (curr->destroy) {
289 curr->destroy(EXT_DATA_AREA(curr));
291 TALLOC_FREE(curr);
295 void *vfs_memctx_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
297 struct vfs_fsp_data *head;
299 for (head = fsp->vfs_extension; head; head = head->next) {
300 if (head->owner == handle) {
301 return head;
305 return NULL;
308 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
310 struct vfs_fsp_data *head;
312 head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
313 if (head != NULL) {
314 return EXT_DATA_AREA(head);
317 return NULL;
320 #undef EXT_DATA_AREA
322 /*****************************************************************
323 Generic VFS init.
324 ******************************************************************/
326 bool smbd_vfs_init(connection_struct *conn)
328 const char **vfs_objects;
329 unsigned int i = 0;
330 int j = 0;
332 /* Normal share - initialise with disk access functions */
333 vfs_init_default(conn);
334 vfs_objects = lp_vfs_objects(SNUM(conn));
336 /* Override VFS functions if 'vfs object' was not specified*/
337 if (!vfs_objects || !vfs_objects[0])
338 return True;
340 for (i=0; vfs_objects[i] ;) {
341 i++;
344 for (j=i-1; j >= 0; j--) {
345 if (!vfs_init_custom(conn, vfs_objects[j])) {
346 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
347 return False;
350 return True;
353 /*******************************************************************
354 Check if a file exists in the vfs.
355 ********************************************************************/
357 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
359 /* Only return OK if stat was successful and S_ISREG */
360 if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
361 S_ISREG(smb_fname->st.st_ex_mode)) {
362 return NT_STATUS_OK;
365 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
368 /****************************************************************************
369 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
370 ****************************************************************************/
372 ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
374 size_t total=0;
376 while (total < byte_count)
378 ssize_t ret = SMB_VFS_READ(fsp, buf + total,
379 byte_count - total);
381 if (ret == 0) return total;
382 if (ret == -1) {
383 if (errno == EINTR)
384 continue;
385 else
386 return -1;
388 total += ret;
390 return (ssize_t)total;
393 ssize_t vfs_pread_data(files_struct *fsp, char *buf,
394 size_t byte_count, off_t offset)
396 size_t total=0;
398 while (total < byte_count)
400 ssize_t ret = SMB_VFS_PREAD(fsp, buf + total,
401 byte_count - total, offset + total);
403 if (ret == 0) return total;
404 if (ret == -1) {
405 if (errno == EINTR)
406 continue;
407 else
408 return -1;
410 total += ret;
412 return (ssize_t)total;
415 /****************************************************************************
416 Write data to a fd on the vfs.
417 ****************************************************************************/
419 ssize_t vfs_write_data(struct smb_request *req,
420 files_struct *fsp,
421 const char *buffer,
422 size_t N)
424 size_t total=0;
425 ssize_t ret;
427 if (req && req->unread_bytes) {
428 SMB_ASSERT(req->unread_bytes == N);
429 /* VFS_RECVFILE must drain the socket
430 * before returning. */
431 req->unread_bytes = 0;
432 return SMB_VFS_RECVFILE(req->sconn->sock,
433 fsp,
434 (off_t)-1,
438 while (total < N) {
439 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
441 if (ret == -1)
442 return -1;
443 if (ret == 0)
444 return total;
446 total += ret;
448 return (ssize_t)total;
451 ssize_t vfs_pwrite_data(struct smb_request *req,
452 files_struct *fsp,
453 const char *buffer,
454 size_t N,
455 off_t offset)
457 size_t total=0;
458 ssize_t ret;
460 if (req && req->unread_bytes) {
461 SMB_ASSERT(req->unread_bytes == N);
462 /* VFS_RECVFILE must drain the socket
463 * before returning. */
464 req->unread_bytes = 0;
465 return SMB_VFS_RECVFILE(req->sconn->sock,
466 fsp,
467 offset,
471 while (total < N) {
472 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
473 offset + total);
475 if (ret == -1)
476 return -1;
477 if (ret == 0)
478 return total;
480 total += ret;
482 return (ssize_t)total;
484 /****************************************************************************
485 An allocate file space call using the vfs interface.
486 Allocates space for a file from a filedescriptor.
487 Returns 0 on success, -1 on failure.
488 ****************************************************************************/
490 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
492 int ret;
493 connection_struct *conn = fsp->conn;
494 uint64_t space_avail;
495 uint64_t bsize,dfree,dsize;
496 NTSTATUS status;
499 * Actually try and commit the space on disk....
502 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
503 fsp_str_dbg(fsp), (double)len));
505 if (((off_t)len) < 0) {
506 DEBUG(0,("vfs_allocate_file_space: %s negative len "
507 "requested.\n", fsp_str_dbg(fsp)));
508 errno = EINVAL;
509 return -1;
512 status = vfs_stat_fsp(fsp);
513 if (!NT_STATUS_IS_OK(status)) {
514 return -1;
517 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
518 return 0;
520 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
521 /* Shrink - use ftruncate. */
523 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
524 "size %.0f\n", fsp_str_dbg(fsp),
525 (double)fsp->fsp_name->st.st_ex_size));
527 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
529 flush_write_cache(fsp, SIZECHANGE_FLUSH);
530 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
531 set_filelen_write_cache(fsp, len);
534 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
536 return ret;
539 if (!lp_strict_allocate(SNUM(fsp->conn)))
540 return 0;
542 /* Grow - we need to test if we have enough space. */
544 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
546 /* See if we have a syscall that will allocate beyond end-of-file
547 without changing EOF. */
548 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
550 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
552 if (ret == 0) {
553 /* We changed the allocation size on disk, but not
554 EOF - exactly as required. We're done ! */
555 return 0;
558 len -= fsp->fsp_name->st.st_ex_size;
559 len /= 1024; /* Len is now number of 1k blocks needed. */
560 space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
561 &bsize, &dfree, &dsize);
562 if (space_avail == (uint64_t)-1) {
563 return -1;
566 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
567 "needed blocks = %.0f, space avail = %.0f\n",
568 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
569 (double)space_avail));
571 if (len > space_avail) {
572 errno = ENOSPC;
573 return -1;
576 return 0;
579 /****************************************************************************
580 A vfs set_filelen call.
581 set the length of a file from a filedescriptor.
582 Returns 0 on success, -1 on failure.
583 ****************************************************************************/
585 int vfs_set_filelen(files_struct *fsp, off_t len)
587 int ret;
589 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
591 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
592 fsp_str_dbg(fsp), (double)len));
593 flush_write_cache(fsp, SIZECHANGE_FLUSH);
594 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
595 set_filelen_write_cache(fsp, len);
596 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
597 FILE_NOTIFY_CHANGE_SIZE
598 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
599 fsp->fsp_name->base_name);
602 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
604 return ret;
607 /****************************************************************************
608 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
609 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
610 as this is also called from the default SMB_VFS_FTRUNCATE code.
611 Always extends the file size.
612 Returns 0 on success, errno on failure.
613 ****************************************************************************/
615 #define SPARSE_BUF_WRITE_SIZE (32*1024)
617 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
619 ssize_t pwrite_ret;
620 size_t total = 0;
622 if (!sparse_buf) {
623 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
624 if (!sparse_buf) {
625 errno = ENOMEM;
626 return ENOMEM;
630 while (total < len) {
631 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
633 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
634 if (pwrite_ret == -1) {
635 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
636 "%s failed with error %s\n",
637 fsp_str_dbg(fsp), strerror(errno)));
638 return errno;
640 total += pwrite_ret;
643 return 0;
646 /****************************************************************************
647 A vfs fill sparse call.
648 Writes zeros from the end of file to len, if len is greater than EOF.
649 Used only by strict_sync.
650 Returns 0 on success, -1 on failure.
651 ****************************************************************************/
653 int vfs_fill_sparse(files_struct *fsp, off_t len)
655 int ret;
656 NTSTATUS status;
657 off_t offset;
658 size_t num_to_write;
660 status = vfs_stat_fsp(fsp);
661 if (!NT_STATUS_IS_OK(status)) {
662 return -1;
665 if (len <= fsp->fsp_name->st.st_ex_size) {
666 return 0;
669 #ifdef S_ISFIFO
670 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
671 return 0;
673 #endif
675 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
676 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
677 (double)fsp->fsp_name->st.st_ex_size, (double)len,
678 (double)(len - fsp->fsp_name->st.st_ex_size)));
680 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
682 flush_write_cache(fsp, SIZECHANGE_FLUSH);
684 offset = fsp->fsp_name->st.st_ex_size;
685 num_to_write = len - fsp->fsp_name->st.st_ex_size;
687 /* Only do this on non-stream file handles. */
688 if (fsp->base_fsp == NULL) {
689 /* for allocation try fallocate first. This can fail on some
690 * platforms e.g. when the filesystem doesn't support it and no
691 * emulation is being done by the libc (like on AIX with JFS1). In that
692 * case we do our own emulation. fallocate implementations can
693 * return ENOTSUP or EINVAL in cases like that. */
694 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
695 offset, num_to_write);
696 if (ret == ENOSPC) {
697 errno = ENOSPC;
698 ret = -1;
699 goto out;
701 if (ret == 0) {
702 goto out;
704 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
705 "error %d. Falling back to slow manual allocation\n", ret));
708 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
709 if (ret != 0) {
710 errno = ret;
711 ret = -1;
714 out:
716 if (ret == 0) {
717 set_filelen_write_cache(fsp, len);
720 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
721 return ret;
724 /****************************************************************************
725 Transfer some data (n bytes) between two file_struct's.
726 ****************************************************************************/
728 static ssize_t vfs_read_fn(void *file, void *buf, size_t len)
730 struct files_struct *fsp = (struct files_struct *)file;
732 return SMB_VFS_READ(fsp, buf, len);
735 static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
737 struct files_struct *fsp = (struct files_struct *)file;
739 return SMB_VFS_WRITE(fsp, buf, len);
742 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
744 return transfer_file_internal((void *)in, (void *)out, n,
745 vfs_read_fn, vfs_write_fn);
748 /*******************************************************************
749 A vfs_readdir wrapper which just returns the file name.
750 ********************************************************************/
752 const char *vfs_readdirname(connection_struct *conn, void *p,
753 SMB_STRUCT_STAT *sbuf, char **talloced)
755 struct dirent *ptr= NULL;
756 const char *dname;
757 char *translated;
758 NTSTATUS status;
760 if (!p)
761 return(NULL);
763 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
764 if (!ptr)
765 return(NULL);
767 dname = ptr->d_name;
770 #ifdef NEXT2
771 if (telldir(p) < 0)
772 return(NULL);
773 #endif
775 #ifdef HAVE_BROKEN_READDIR_NAME
776 /* using /usr/ucb/cc is BAD */
777 dname = dname - 2;
778 #endif
780 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
781 talloc_tos(), &translated);
782 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
783 *talloced = NULL;
784 return dname;
786 *talloced = translated;
787 if (!NT_STATUS_IS_OK(status)) {
788 return NULL;
790 return translated;
793 /*******************************************************************
794 A wrapper for vfs_chdir().
795 ********************************************************************/
797 int vfs_ChDir(connection_struct *conn, const char *path)
799 int res;
801 if (!LastDir) {
802 LastDir = SMB_STRDUP("");
805 if (strcsequal(path,"."))
806 return(0);
808 if (*path == '/' && strcsequal(LastDir,path))
809 return(0);
811 DEBUG(4,("vfs_ChDir to %s\n",path));
813 res = SMB_VFS_CHDIR(conn,path);
814 if (!res) {
815 SAFE_FREE(LastDir);
816 LastDir = SMB_STRDUP(path);
818 return(res);
821 /*******************************************************************
822 Return the absolute current directory path - given a UNIX pathname.
823 Note that this path is returned in DOS format, not UNIX
824 format. Note this can be called with conn == NULL.
825 ********************************************************************/
827 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
829 char *current_dir = NULL;
830 char *result = NULL;
831 DATA_BLOB cache_value;
832 struct file_id key;
833 struct smb_filename *smb_fname_dot = NULL;
834 struct smb_filename *smb_fname_full = NULL;
835 NTSTATUS status;
837 if (!lp_getwd_cache()) {
838 goto nocache;
841 status = create_synthetic_smb_fname(ctx, ".", NULL, NULL,
842 &smb_fname_dot);
843 if (!NT_STATUS_IS_OK(status)) {
844 errno = map_errno_from_nt_status(status);
845 goto out;
848 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
850 * Known to fail for root: the directory may be NFS-mounted
851 * and exported with root_squash (so has no root access).
853 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
854 "(NFS problem ?)\n", strerror(errno) ));
855 goto nocache;
858 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
860 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
861 data_blob_const(&key, sizeof(key)),
862 &cache_value)) {
863 goto nocache;
866 SMB_ASSERT((cache_value.length > 0)
867 && (cache_value.data[cache_value.length-1] == '\0'));
869 status = create_synthetic_smb_fname(ctx, (char *)cache_value.data,
870 NULL, NULL, &smb_fname_full);
871 if (!NT_STATUS_IS_OK(status)) {
872 errno = map_errno_from_nt_status(status);
873 goto out;
876 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
877 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
878 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
879 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
881 * Ok, we're done
883 result = talloc_strdup(ctx, smb_fname_full->base_name);
884 if (result == NULL) {
885 errno = ENOMEM;
887 goto out;
890 nocache:
893 * We don't have the information to hand so rely on traditional
894 * methods. The very slow getcwd, which spawns a process on some
895 * systems, or the not quite so bad getwd.
898 current_dir = SMB_VFS_GETWD(conn);
899 if (current_dir == NULL) {
900 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
901 strerror(errno)));
902 goto out;
905 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
906 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
908 memcache_add(smbd_memcache(), GETWD_CACHE,
909 data_blob_const(&key, sizeof(key)),
910 data_blob_const(current_dir,
911 strlen(current_dir)+1));
914 result = talloc_strdup(ctx, current_dir);
915 if (result == NULL) {
916 errno = ENOMEM;
919 out:
920 TALLOC_FREE(smb_fname_dot);
921 TALLOC_FREE(smb_fname_full);
922 SAFE_FREE(current_dir);
923 return result;
926 /*******************************************************************
927 Reduce a file name, removing .. elements and checking that
928 it is below dir in the heirachy. This uses realpath.
929 This function must run as root, and will return names
930 and valid stat structs that can be checked on open.
931 ********************************************************************/
933 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
934 const char *fname,
935 struct smb_request *smbreq)
937 NTSTATUS status;
938 TALLOC_CTX *ctx = talloc_tos();
939 const char *conn_rootdir;
940 size_t rootdir_len;
941 char *dir_name = NULL;
942 const char *last_component = NULL;
943 char *resolved_name = NULL;
944 char *saved_dir = NULL;
945 struct smb_filename *smb_fname_cwd = NULL;
946 struct privilege_paths *priv_paths = NULL;
947 int ret;
949 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
950 fname,
951 conn->connectpath));
954 priv_paths = talloc_zero(smbreq, struct privilege_paths);
955 if (!priv_paths) {
956 status = NT_STATUS_NO_MEMORY;
957 goto err;
960 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
961 status = NT_STATUS_NO_MEMORY;
962 goto err;
965 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
966 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
968 if (priv_paths->parent_name.base_name == NULL ||
969 priv_paths->file_name.base_name == NULL) {
970 status = NT_STATUS_NO_MEMORY;
971 goto err;
974 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
975 status = map_nt_error_from_unix(errno);
976 goto err;
978 /* Remember where we were. */
979 saved_dir = vfs_GetWd(ctx, conn);
980 if (!saved_dir) {
981 status = map_nt_error_from_unix(errno);
982 goto err;
985 /* Go to the parent directory to lock in memory. */
986 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
987 status = map_nt_error_from_unix(errno);
988 goto err;
991 /* Get the absolute path of the parent directory. */
992 resolved_name = SMB_VFS_REALPATH(conn,".");
993 if (!resolved_name) {
994 status = map_nt_error_from_unix(errno);
995 goto err;
998 if (*resolved_name != '/') {
999 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1000 "doesn't return absolute paths !\n"));
1001 status = NT_STATUS_OBJECT_NAME_INVALID;
1002 goto err;
1005 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1006 priv_paths->parent_name.base_name,
1007 resolved_name));
1009 /* Now check the stat value is the same. */
1010 status = create_synthetic_smb_fname(talloc_tos(), ".",
1011 NULL, NULL,
1012 &smb_fname_cwd);
1013 if (!NT_STATUS_IS_OK(status)) {
1014 goto err;
1017 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1018 status = map_nt_error_from_unix(errno);
1019 goto err;
1022 /* Ensure we're pointing at the same place. */
1023 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1024 DEBUG(0,("check_reduced_name_with_privilege: "
1025 "device/inode/uid/gid on directory %s changed. "
1026 "Denying access !\n",
1027 priv_paths->parent_name.base_name));
1028 status = NT_STATUS_ACCESS_DENIED;
1029 goto err;
1032 /* Ensure we're below the connect path. */
1034 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1035 if (conn_rootdir == NULL) {
1036 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1037 "conn_rootdir\n"));
1038 status = NT_STATUS_ACCESS_DENIED;
1039 goto err;
1042 rootdir_len = strlen(conn_rootdir);
1043 if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1044 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1045 "attempt: %s is a symlink outside the "
1046 "share path\n",
1047 dir_name));
1048 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1049 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1050 status = NT_STATUS_ACCESS_DENIED;
1051 goto err;
1054 /* Now ensure that the last component either doesn't
1055 exist, or is *NOT* a symlink. */
1057 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1058 if (ret == -1) {
1059 /* Errno must be ENOENT for this be ok. */
1060 if (errno != ENOENT) {
1061 status = map_nt_error_from_unix(errno);
1062 DEBUG(2, ("check_reduced_name_with_privilege: "
1063 "LSTAT on %s failed with %s\n",
1064 priv_paths->file_name.base_name,
1065 nt_errstr(status)));
1066 goto err;
1070 if (VALID_STAT(priv_paths->file_name.st) &&
1071 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1072 DEBUG(2, ("check_reduced_name_with_privilege: "
1073 "Last component %s is a symlink. Denying"
1074 "access.\n",
1075 priv_paths->file_name.base_name));
1076 status = NT_STATUS_ACCESS_DENIED;
1077 goto err;
1080 smbreq->priv_paths = priv_paths;
1081 status = NT_STATUS_OK;
1083 err:
1085 if (saved_dir) {
1086 vfs_ChDir(conn, saved_dir);
1088 SAFE_FREE(resolved_name);
1089 if (!NT_STATUS_IS_OK(status)) {
1090 TALLOC_FREE(priv_paths);
1092 return status;
1095 /*******************************************************************
1096 Reduce a file name, removing .. elements and checking that
1097 it is below dir in the heirachy. This uses realpath.
1098 ********************************************************************/
1100 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1102 char *resolved_name = NULL;
1103 bool allow_symlinks = true;
1104 bool allow_widelinks = false;
1106 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1108 resolved_name = SMB_VFS_REALPATH(conn,fname);
1110 if (!resolved_name) {
1111 switch (errno) {
1112 case ENOTDIR:
1113 DEBUG(3,("check_reduced_name: Component not a "
1114 "directory in getting realpath for "
1115 "%s\n", fname));
1116 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1117 case ENOENT:
1119 TALLOC_CTX *ctx = talloc_tos();
1120 char *dir_name = NULL;
1121 const char *last_component = NULL;
1122 char *new_name = NULL;
1123 int ret;
1125 /* Last component didn't exist.
1126 Remove it and try and canonicalise
1127 the directory name. */
1128 if (!parent_dirname(ctx, fname,
1129 &dir_name,
1130 &last_component)) {
1131 return NT_STATUS_NO_MEMORY;
1134 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1135 if (!resolved_name) {
1136 NTSTATUS status = map_nt_error_from_unix(errno);
1138 if (errno == ENOENT || errno == ENOTDIR) {
1139 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1142 DEBUG(3,("check_reduce_name: "
1143 "couldn't get realpath for "
1144 "%s (%s)\n",
1145 fname,
1146 nt_errstr(status)));
1147 return status;
1149 ret = asprintf(&new_name, "%s/%s",
1150 resolved_name, last_component);
1151 SAFE_FREE(resolved_name);
1152 if (ret == -1) {
1153 return NT_STATUS_NO_MEMORY;
1155 resolved_name = new_name;
1156 break;
1158 default:
1159 DEBUG(3,("check_reduced_name: couldn't get "
1160 "realpath for %s\n", fname));
1161 return map_nt_error_from_unix(errno);
1165 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1166 resolved_name));
1168 if (*resolved_name != '/') {
1169 DEBUG(0,("check_reduced_name: realpath doesn't return "
1170 "absolute paths !\n"));
1171 SAFE_FREE(resolved_name);
1172 return NT_STATUS_OBJECT_NAME_INVALID;
1175 allow_widelinks = lp_widelinks(SNUM(conn));
1176 allow_symlinks = lp_symlinks(SNUM(conn));
1178 /* Common widelinks and symlinks checks. */
1179 if (!allow_widelinks || !allow_symlinks) {
1180 const char *conn_rootdir;
1181 size_t rootdir_len;
1183 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1184 if (conn_rootdir == NULL) {
1185 DEBUG(2, ("check_reduced_name: Could not get "
1186 "conn_rootdir\n"));
1187 SAFE_FREE(resolved_name);
1188 return NT_STATUS_ACCESS_DENIED;
1191 rootdir_len = strlen(conn_rootdir);
1192 if (strncmp(conn_rootdir, resolved_name,
1193 rootdir_len) != 0) {
1194 DEBUG(2, ("check_reduced_name: Bad access "
1195 "attempt: %s is a symlink outside the "
1196 "share path\n", fname));
1197 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1198 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1199 SAFE_FREE(resolved_name);
1200 return NT_STATUS_ACCESS_DENIED;
1203 /* Extra checks if all symlinks are disallowed. */
1204 if (!allow_symlinks) {
1205 /* fname can't have changed in resolved_path. */
1206 const char *p = &resolved_name[rootdir_len];
1208 /* *p can be '\0' if fname was "." */
1209 if (*p == '\0' && ISDOT(fname)) {
1210 goto out;
1213 if (*p != '/') {
1214 DEBUG(2, ("check_reduced_name: logic error (%c) "
1215 "in resolved_name: %s\n",
1217 fname));
1218 SAFE_FREE(resolved_name);
1219 return NT_STATUS_ACCESS_DENIED;
1222 p++;
1223 if (strcmp(fname, p)!=0) {
1224 DEBUG(2, ("check_reduced_name: Bad access "
1225 "attempt: %s is a symlink\n",
1226 fname));
1227 SAFE_FREE(resolved_name);
1228 return NT_STATUS_ACCESS_DENIED;
1233 out:
1235 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1236 resolved_name));
1237 SAFE_FREE(resolved_name);
1238 return NT_STATUS_OK;
1242 * XXX: This is temporary and there should be no callers of this once
1243 * smb_filename is plumbed through all path based operations.
1245 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1246 SMB_STRUCT_STAT *psbuf)
1248 struct smb_filename *smb_fname = NULL;
1249 NTSTATUS status;
1250 int ret;
1252 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1253 &smb_fname);
1254 if (!NT_STATUS_IS_OK(status)) {
1255 errno = map_errno_from_nt_status(status);
1256 return -1;
1259 if (lp_posix_pathnames()) {
1260 ret = SMB_VFS_LSTAT(conn, smb_fname);
1261 } else {
1262 ret = SMB_VFS_STAT(conn, smb_fname);
1265 if (ret != -1) {
1266 *psbuf = smb_fname->st;
1269 TALLOC_FREE(smb_fname);
1270 return ret;
1274 * XXX: This is temporary and there should be no callers of this once
1275 * smb_filename is plumbed through all path based operations.
1277 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1278 SMB_STRUCT_STAT *psbuf)
1280 struct smb_filename *smb_fname = NULL;
1281 NTSTATUS status;
1282 int ret;
1284 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1285 &smb_fname);
1286 if (!NT_STATUS_IS_OK(status)) {
1287 errno = map_errno_from_nt_status(status);
1288 return -1;
1291 ret = SMB_VFS_LSTAT(conn, smb_fname);
1292 if (ret != -1) {
1293 *psbuf = smb_fname->st;
1296 TALLOC_FREE(smb_fname);
1297 return ret;
1301 * Ensure LSTAT is called for POSIX paths.
1304 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1306 int ret;
1308 if(fsp->fh->fd == -1) {
1309 if (fsp->posix_open) {
1310 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1311 } else {
1312 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1314 if (ret == -1) {
1315 return map_nt_error_from_unix(errno);
1317 } else {
1318 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1319 return map_nt_error_from_unix(errno);
1322 return NT_STATUS_OK;
1326 * Initialize num_streams and streams, then call VFS op streaminfo
1328 NTSTATUS vfs_streaminfo(connection_struct *conn,
1329 struct files_struct *fsp,
1330 const char *fname,
1331 TALLOC_CTX *mem_ctx,
1332 unsigned int *num_streams,
1333 struct stream_struct **streams)
1335 *num_streams = 0;
1336 *streams = NULL;
1337 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1341 generate a file_id from a stat structure
1343 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1345 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1348 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1349 const char *service, const char *user)
1351 VFS_FIND(connect);
1352 return handle->fns->connect_fn(handle, service, user);
1355 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1357 VFS_FIND(disconnect);
1358 handle->fns->disconnect_fn(handle);
1361 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1362 const char *path, bool small_query,
1363 uint64_t *bsize, uint64_t *dfree,
1364 uint64_t *dsize)
1366 VFS_FIND(disk_free);
1367 return handle->fns->disk_free_fn(handle, path, small_query, bsize,
1368 dfree, dsize);
1371 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1372 enum SMB_QUOTA_TYPE qtype, unid_t id,
1373 SMB_DISK_QUOTA *qt)
1375 VFS_FIND(get_quota);
1376 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1379 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1380 enum SMB_QUOTA_TYPE qtype, unid_t id,
1381 SMB_DISK_QUOTA *qt)
1383 VFS_FIND(set_quota);
1384 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1387 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1388 struct files_struct *fsp,
1389 struct shadow_copy_data *shadow_copy_data,
1390 bool labels)
1392 VFS_FIND(get_shadow_copy_data);
1393 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1394 shadow_copy_data,
1395 labels);
1397 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1398 struct vfs_statvfs_struct *statbuf)
1400 VFS_FIND(statvfs);
1401 return handle->fns->statvfs_fn(handle, path, statbuf);
1404 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1405 enum timestamp_set_resolution *p_ts_res)
1407 VFS_FIND(fs_capabilities);
1408 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1411 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1412 struct dfs_GetDFSReferral *r)
1414 VFS_FIND(get_dfs_referrals);
1415 return handle->fns->get_dfs_referrals_fn(handle, r);
1418 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1419 const char *fname, const char *mask,
1420 uint32 attributes)
1422 VFS_FIND(opendir);
1423 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1426 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1427 struct files_struct *fsp,
1428 const char *mask,
1429 uint32 attributes)
1431 VFS_FIND(fdopendir);
1432 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1435 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1436 DIR *dirp,
1437 SMB_STRUCT_STAT *sbuf)
1439 VFS_FIND(readdir);
1440 return handle->fns->readdir_fn(handle, dirp, sbuf);
1443 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1444 DIR *dirp, long offset)
1446 VFS_FIND(seekdir);
1447 handle->fns->seekdir_fn(handle, dirp, offset);
1450 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1451 DIR *dirp)
1453 VFS_FIND(telldir);
1454 return handle->fns->telldir_fn(handle, dirp);
1457 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1458 DIR *dirp)
1460 VFS_FIND(rewind_dir);
1461 handle->fns->rewind_dir_fn(handle, dirp);
1464 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1465 mode_t mode)
1467 VFS_FIND(mkdir);
1468 return handle->fns->mkdir_fn(handle, path, mode);
1471 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1473 VFS_FIND(rmdir);
1474 return handle->fns->rmdir_fn(handle, path);
1477 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1478 DIR *dir)
1480 VFS_FIND(closedir);
1481 return handle->fns->closedir_fn(handle, dir);
1484 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1485 DIR *dirp)
1487 VFS_FIND(init_search_op);
1488 handle->fns->init_search_op_fn(handle, dirp);
1491 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1492 struct smb_filename *smb_fname, struct files_struct *fsp,
1493 int flags, mode_t mode)
1495 VFS_FIND(open);
1496 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1499 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1500 struct smb_request *req,
1501 uint16_t root_dir_fid,
1502 struct smb_filename *smb_fname,
1503 uint32_t access_mask,
1504 uint32_t share_access,
1505 uint32_t create_disposition,
1506 uint32_t create_options,
1507 uint32_t file_attributes,
1508 uint32_t oplock_request,
1509 uint64_t allocation_size,
1510 uint32_t private_flags,
1511 struct security_descriptor *sd,
1512 struct ea_list *ea_list,
1513 files_struct **result,
1514 int *pinfo)
1516 VFS_FIND(create_file);
1517 return handle->fns->create_file_fn(
1518 handle, req, root_dir_fid, smb_fname, access_mask,
1519 share_access, create_disposition, create_options,
1520 file_attributes, oplock_request, allocation_size,
1521 private_flags, sd, ea_list,
1522 result, pinfo);
1525 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1526 struct files_struct *fsp)
1528 VFS_FIND(close);
1529 return handle->fns->close_fn(handle, fsp);
1532 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1533 struct files_struct *fsp, void *data, size_t n)
1535 VFS_FIND(read);
1536 return handle->fns->read_fn(handle, fsp, data, n);
1539 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1540 struct files_struct *fsp, void *data, size_t n,
1541 off_t offset)
1543 VFS_FIND(pread);
1544 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1547 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1548 struct files_struct *fsp, const void *data,
1549 size_t n)
1551 VFS_FIND(write);
1552 return handle->fns->write_fn(handle, fsp, data, n);
1555 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1556 struct files_struct *fsp, const void *data,
1557 size_t n, off_t offset)
1559 VFS_FIND(pwrite);
1560 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1563 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1564 struct files_struct *fsp, off_t offset,
1565 int whence)
1567 VFS_FIND(lseek);
1568 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1571 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1572 files_struct *fromfsp, const DATA_BLOB *header,
1573 off_t offset, size_t count)
1575 VFS_FIND(sendfile);
1576 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1577 count);
1580 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1581 files_struct *tofsp, off_t offset,
1582 size_t count)
1584 VFS_FIND(recvfile);
1585 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1588 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1589 const struct smb_filename *smb_fname_src,
1590 const struct smb_filename *smb_fname_dst)
1592 VFS_FIND(rename);
1593 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1596 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1597 struct files_struct *fsp)
1599 VFS_FIND(fsync);
1600 return handle->fns->fsync_fn(handle, fsp);
1603 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1604 struct smb_filename *smb_fname)
1606 VFS_FIND(stat);
1607 return handle->fns->stat_fn(handle, smb_fname);
1610 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1611 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1613 VFS_FIND(fstat);
1614 return handle->fns->fstat_fn(handle, fsp, sbuf);
1617 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1618 struct smb_filename *smb_filename)
1620 VFS_FIND(lstat);
1621 return handle->fns->lstat_fn(handle, smb_filename);
1624 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1625 struct files_struct *fsp,
1626 const SMB_STRUCT_STAT *sbuf)
1628 VFS_FIND(get_alloc_size);
1629 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1632 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1633 const struct smb_filename *smb_fname)
1635 VFS_FIND(unlink);
1636 return handle->fns->unlink_fn(handle, smb_fname);
1639 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1640 mode_t mode)
1642 VFS_FIND(chmod);
1643 return handle->fns->chmod_fn(handle, path, mode);
1646 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1647 struct files_struct *fsp, mode_t mode)
1649 VFS_FIND(fchmod);
1650 return handle->fns->fchmod_fn(handle, fsp, mode);
1653 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1654 uid_t uid, gid_t gid)
1656 VFS_FIND(chown);
1657 return handle->fns->chown_fn(handle, path, uid, gid);
1660 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1661 struct files_struct *fsp, uid_t uid, gid_t gid)
1663 VFS_FIND(fchown);
1664 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1667 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1668 uid_t uid, gid_t gid)
1670 VFS_FIND(lchown);
1671 return handle->fns->lchown_fn(handle, path, uid, gid);
1674 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1676 int ret;
1677 bool as_root = false;
1678 const char *path;
1679 char *saved_dir = NULL;
1680 char *parent_dir = NULL;
1681 NTSTATUS status;
1683 if (fsp->fh->fd != -1) {
1684 /* Try fchown. */
1685 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1686 if (ret == 0) {
1687 return NT_STATUS_OK;
1689 if (ret == -1 && errno != ENOSYS) {
1690 return map_nt_error_from_unix(errno);
1694 as_root = (geteuid() == 0);
1696 if (as_root) {
1698 * We are being asked to chown as root. Make
1699 * sure we chdir() into the path to pin it,
1700 * and always act using lchown to ensure we
1701 * don't deref any symbolic links.
1703 const char *final_component = NULL;
1704 struct smb_filename local_fname;
1706 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1707 if (!saved_dir) {
1708 status = map_nt_error_from_unix(errno);
1709 DEBUG(0,("vfs_chown_fsp: failed to get "
1710 "current working directory. Error was %s\n",
1711 strerror(errno)));
1712 return status;
1715 if (!parent_dirname(talloc_tos(),
1716 fsp->fsp_name->base_name,
1717 &parent_dir,
1718 &final_component)) {
1719 return NT_STATUS_NO_MEMORY;
1722 /* cd into the parent dir to pin it. */
1723 ret = vfs_ChDir(fsp->conn, parent_dir);
1724 if (ret == -1) {
1725 return map_nt_error_from_unix(errno);
1728 ZERO_STRUCT(local_fname);
1729 local_fname.base_name = discard_const_p(char, final_component);
1731 /* Must use lstat here. */
1732 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1733 if (ret == -1) {
1734 status = map_nt_error_from_unix(errno);
1735 goto out;
1738 /* Ensure it matches the fsp stat. */
1739 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1740 status = NT_STATUS_ACCESS_DENIED;
1741 goto out;
1743 path = final_component;
1744 } else {
1745 path = fsp->fsp_name->base_name;
1748 if (fsp->posix_open || as_root) {
1749 ret = SMB_VFS_LCHOWN(fsp->conn,
1750 path,
1751 uid, gid);
1752 } else {
1753 ret = SMB_VFS_CHOWN(fsp->conn,
1754 path,
1755 uid, gid);
1758 if (ret == 0) {
1759 status = NT_STATUS_OK;
1760 } else {
1761 status = map_nt_error_from_unix(errno);
1764 out:
1766 if (as_root) {
1767 vfs_ChDir(fsp->conn,saved_dir);
1768 TALLOC_FREE(saved_dir);
1769 TALLOC_FREE(parent_dir);
1771 return status;
1774 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1776 VFS_FIND(chdir);
1777 return handle->fns->chdir_fn(handle, path);
1780 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
1782 VFS_FIND(getwd);
1783 return handle->fns->getwd_fn(handle);
1786 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
1787 const struct smb_filename *smb_fname,
1788 struct smb_file_time *ft)
1790 VFS_FIND(ntimes);
1791 return handle->fns->ntimes_fn(handle, smb_fname, ft);
1794 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
1795 struct files_struct *fsp, off_t offset)
1797 VFS_FIND(ftruncate);
1798 return handle->fns->ftruncate_fn(handle, fsp, offset);
1801 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
1802 struct files_struct *fsp,
1803 enum vfs_fallocate_mode mode,
1804 off_t offset,
1805 off_t len)
1807 VFS_FIND(fallocate);
1808 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
1811 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
1812 struct files_struct *fsp, uint32 share_mode,
1813 uint32_t access_mask)
1815 VFS_FIND(kernel_flock);
1816 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
1817 access_mask);
1820 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
1821 struct files_struct *fsp, int leasetype)
1823 VFS_FIND(linux_setlease);
1824 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
1827 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
1828 const char *newpath)
1830 VFS_FIND(symlink);
1831 return handle->fns->symlink_fn(handle, oldpath, newpath);
1834 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
1835 const char *path, char *buf, size_t bufsiz)
1837 VFS_FIND(readlink);
1838 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
1841 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
1842 const char *newpath)
1844 VFS_FIND(link);
1845 return handle->fns->link_fn(handle, oldpath, newpath);
1848 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
1849 mode_t mode, SMB_DEV_T dev)
1851 VFS_FIND(mknod);
1852 return handle->fns->mknod_fn(handle, path, mode, dev);
1855 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
1857 VFS_FIND(realpath);
1858 return handle->fns->realpath_fn(handle, path);
1861 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
1862 struct sys_notify_context *ctx,
1863 const char *path,
1864 uint32_t *filter,
1865 uint32_t *subdir_filter,
1866 void (*callback)(struct sys_notify_context *ctx,
1867 void *private_data,
1868 struct notify_event *ev),
1869 void *private_data, void *handle_p)
1871 VFS_FIND(notify_watch);
1872 return handle->fns->notify_watch_fn(handle, ctx, path,
1873 filter, subdir_filter, callback,
1874 private_data, handle_p);
1877 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
1878 unsigned int flags)
1880 VFS_FIND(chflags);
1881 return handle->fns->chflags_fn(handle, path, flags);
1884 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
1885 const SMB_STRUCT_STAT *sbuf)
1887 VFS_FIND(file_id_create);
1888 return handle->fns->file_id_create_fn(handle, sbuf);
1891 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
1892 struct files_struct *fsp,
1893 const char *fname,
1894 TALLOC_CTX *mem_ctx,
1895 unsigned int *num_streams,
1896 struct stream_struct **streams)
1898 VFS_FIND(streaminfo);
1899 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
1900 num_streams, streams);
1903 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
1904 const char *path, const char *name,
1905 TALLOC_CTX *mem_ctx, char **found_name)
1907 VFS_FIND(get_real_filename);
1908 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
1909 found_name);
1912 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
1913 const char *filename)
1915 VFS_FIND(connectpath);
1916 return handle->fns->connectpath_fn(handle, filename);
1919 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
1920 struct files_struct *fsp,
1921 struct lock_struct *plock)
1923 VFS_FIND(strict_lock);
1924 return handle->fns->strict_lock_fn(handle, fsp, plock);
1927 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
1928 struct files_struct *fsp,
1929 struct lock_struct *plock)
1931 VFS_FIND(strict_unlock);
1932 handle->fns->strict_unlock_fn(handle, fsp, plock);
1935 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
1936 const char *name,
1937 enum vfs_translate_direction direction,
1938 TALLOC_CTX *mem_ctx,
1939 char **mapped_name)
1941 VFS_FIND(translate_name);
1942 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
1943 mapped_name);
1946 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
1947 struct files_struct *fsp,
1948 TALLOC_CTX *ctx,
1949 uint32_t function,
1950 uint16_t req_flags,
1951 const uint8_t *in_data,
1952 uint32_t in_len,
1953 uint8_t **out_data,
1954 uint32_t max_out_len,
1955 uint32_t *out_len)
1957 VFS_FIND(fsctl);
1958 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
1959 in_data, in_len, out_data, max_out_len,
1960 out_len);
1963 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
1964 struct files_struct *fsp,
1965 uint32 security_info,
1966 struct security_descriptor **ppdesc)
1968 VFS_FIND(fget_nt_acl);
1969 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
1970 ppdesc);
1973 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
1974 const char *name,
1975 uint32 security_info,
1976 struct security_descriptor **ppdesc)
1978 VFS_FIND(get_nt_acl);
1979 return handle->fns->get_nt_acl_fn(handle, name, security_info, ppdesc);
1982 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
1983 struct files_struct *fsp,
1984 uint32 security_info_sent,
1985 const struct security_descriptor *psd)
1987 VFS_FIND(fset_nt_acl);
1988 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
1989 psd);
1992 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
1993 struct smb_filename *file,
1994 struct security_acl *sacl,
1995 uint32_t access_requested,
1996 uint32_t access_denied)
1998 VFS_FIND(audit_file);
1999 return handle->fns->audit_file_fn(handle,
2000 file,
2001 sacl,
2002 access_requested,
2003 access_denied);
2006 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2007 mode_t mode)
2009 VFS_FIND(chmod_acl);
2010 return handle->fns->chmod_acl_fn(handle, name, mode);
2013 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2014 struct files_struct *fsp, mode_t mode)
2016 VFS_FIND(fchmod_acl);
2017 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2020 int smb_vfs_call_sys_acl_get_entry(struct vfs_handle_struct *handle,
2021 SMB_ACL_T theacl, int entry_id,
2022 SMB_ACL_ENTRY_T *entry_p)
2024 VFS_FIND(sys_acl_get_entry);
2025 return handle->fns->sys_acl_get_entry_fn(handle, theacl, entry_id,
2026 entry_p);
2029 int smb_vfs_call_sys_acl_get_tag_type(struct vfs_handle_struct *handle,
2030 SMB_ACL_ENTRY_T entry_d,
2031 SMB_ACL_TAG_T *tag_type_p)
2033 VFS_FIND(sys_acl_get_tag_type);
2034 return handle->fns->sys_acl_get_tag_type_fn(handle, entry_d,
2035 tag_type_p);
2038 int smb_vfs_call_sys_acl_get_permset(struct vfs_handle_struct *handle,
2039 SMB_ACL_ENTRY_T entry_d,
2040 SMB_ACL_PERMSET_T *permset_p)
2042 VFS_FIND(sys_acl_get_permset);
2043 return handle->fns->sys_acl_get_permset_fn(handle, entry_d, permset_p);
2046 void * smb_vfs_call_sys_acl_get_qualifier(struct vfs_handle_struct *handle,
2047 SMB_ACL_ENTRY_T entry_d)
2049 VFS_FIND(sys_acl_get_qualifier);
2050 return handle->fns->sys_acl_get_qualifier_fn(handle, entry_d);
2053 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2054 const char *path_p,
2055 SMB_ACL_TYPE_T type)
2057 VFS_FIND(sys_acl_get_file);
2058 return handle->fns->sys_acl_get_file_fn(handle, path_p, type);
2061 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2062 struct files_struct *fsp)
2064 VFS_FIND(sys_acl_get_fd);
2065 return handle->fns->sys_acl_get_fd_fn(handle, fsp);
2068 int smb_vfs_call_sys_acl_clear_perms(struct vfs_handle_struct *handle,
2069 SMB_ACL_PERMSET_T permset)
2071 VFS_FIND(sys_acl_clear_perms);
2072 return handle->fns->sys_acl_clear_perms_fn(handle, permset);
2075 int smb_vfs_call_sys_acl_add_perm(struct vfs_handle_struct *handle,
2076 SMB_ACL_PERMSET_T permset,
2077 SMB_ACL_PERM_T perm)
2079 VFS_FIND(sys_acl_add_perm);
2080 return handle->fns->sys_acl_add_perm_fn(handle, permset, perm);
2083 char * smb_vfs_call_sys_acl_to_text(struct vfs_handle_struct *handle,
2084 SMB_ACL_T theacl, ssize_t *plen)
2086 VFS_FIND(sys_acl_to_text);
2087 return handle->fns->sys_acl_to_text_fn(handle, theacl, plen);
2090 SMB_ACL_T smb_vfs_call_sys_acl_init(struct vfs_handle_struct *handle,
2091 int count)
2093 VFS_FIND(sys_acl_init);
2094 return handle->fns->sys_acl_init_fn(handle, count);
2097 int smb_vfs_call_sys_acl_create_entry(struct vfs_handle_struct *handle,
2098 SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2100 VFS_FIND(sys_acl_create_entry);
2101 return handle->fns->sys_acl_create_entry_fn(handle, pacl, pentry);
2104 int smb_vfs_call_sys_acl_set_tag_type(struct vfs_handle_struct *handle,
2105 SMB_ACL_ENTRY_T entry,
2106 SMB_ACL_TAG_T tagtype)
2108 VFS_FIND(sys_acl_set_tag_type);
2109 return handle->fns->sys_acl_set_tag_type_fn(handle, entry, tagtype);
2112 int smb_vfs_call_sys_acl_set_qualifier(struct vfs_handle_struct *handle,
2113 SMB_ACL_ENTRY_T entry, void *qual)
2115 VFS_FIND(sys_acl_set_qualifier);
2116 return handle->fns->sys_acl_set_qualifier_fn(handle, entry, qual);
2119 int smb_vfs_call_sys_acl_set_permset(struct vfs_handle_struct *handle,
2120 SMB_ACL_ENTRY_T entry,
2121 SMB_ACL_PERMSET_T permset)
2123 VFS_FIND(sys_acl_set_permset);
2124 return handle->fns->sys_acl_set_permset_fn(handle, entry, permset);
2127 int smb_vfs_call_sys_acl_valid(struct vfs_handle_struct *handle,
2128 SMB_ACL_T theacl)
2130 VFS_FIND(sys_acl_valid);
2131 return handle->fns->sys_acl_valid_fn(handle, theacl);
2134 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2135 const char *name, SMB_ACL_TYPE_T acltype,
2136 SMB_ACL_T theacl)
2138 VFS_FIND(sys_acl_set_file);
2139 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2142 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2143 struct files_struct *fsp, SMB_ACL_T theacl)
2145 VFS_FIND(sys_acl_set_fd);
2146 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2149 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2150 const char *path)
2152 VFS_FIND(sys_acl_delete_def_file);
2153 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2156 int smb_vfs_call_sys_acl_get_perm(struct vfs_handle_struct *handle,
2157 SMB_ACL_PERMSET_T permset,
2158 SMB_ACL_PERM_T perm)
2160 VFS_FIND(sys_acl_get_perm);
2161 return handle->fns->sys_acl_get_perm_fn(handle, permset, perm);
2164 int smb_vfs_call_sys_acl_free_text(struct vfs_handle_struct *handle,
2165 char *text)
2167 VFS_FIND(sys_acl_free_text);
2168 return handle->fns->sys_acl_free_text_fn(handle, text);
2171 int smb_vfs_call_sys_acl_free_acl(struct vfs_handle_struct *handle,
2172 SMB_ACL_T posix_acl)
2174 VFS_FIND(sys_acl_free_acl);
2175 return handle->fns->sys_acl_free_acl_fn(handle, posix_acl);
2178 int smb_vfs_call_sys_acl_free_qualifier(struct vfs_handle_struct *handle,
2179 void *qualifier, SMB_ACL_TAG_T tagtype)
2181 VFS_FIND(sys_acl_free_qualifier);
2182 return handle->fns->sys_acl_free_qualifier_fn(handle, qualifier,
2183 tagtype);
2186 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2187 const char *path, const char *name, void *value,
2188 size_t size)
2190 VFS_FIND(getxattr);
2191 return handle->fns->getxattr_fn(handle, path, name, value, size);
2194 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2195 struct files_struct *fsp, const char *name,
2196 void *value, size_t size)
2198 VFS_FIND(fgetxattr);
2199 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2202 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2203 const char *path, char *list, size_t size)
2205 VFS_FIND(listxattr);
2206 return handle->fns->listxattr_fn(handle, path, list, size);
2209 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2210 struct files_struct *fsp, char *list,
2211 size_t size)
2213 VFS_FIND(flistxattr);
2214 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2217 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2218 const char *path, const char *name)
2220 VFS_FIND(removexattr);
2221 return handle->fns->removexattr_fn(handle, path, name);
2224 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2225 struct files_struct *fsp, const char *name)
2227 VFS_FIND(fremovexattr);
2228 return handle->fns->fremovexattr_fn(handle, fsp, name);
2231 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2232 const char *name, const void *value, size_t size,
2233 int flags)
2235 VFS_FIND(setxattr);
2236 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2239 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2240 struct files_struct *fsp, const char *name,
2241 const void *value, size_t size, int flags)
2243 VFS_FIND(fsetxattr);
2244 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2247 int smb_vfs_call_aio_read(struct vfs_handle_struct *handle,
2248 struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2250 VFS_FIND(aio_read);
2251 return handle->fns->aio_read_fn(handle, fsp, aiocb);
2254 int smb_vfs_call_aio_write(struct vfs_handle_struct *handle,
2255 struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2257 VFS_FIND(aio_write);
2258 return handle->fns->aio_write_fn(handle, fsp, aiocb);
2261 ssize_t smb_vfs_call_aio_return(struct vfs_handle_struct *handle,
2262 struct files_struct *fsp,
2263 SMB_STRUCT_AIOCB *aiocb)
2265 VFS_FIND(aio_return);
2266 return handle->fns->aio_return_fn(handle, fsp, aiocb);
2269 int smb_vfs_call_aio_cancel(struct vfs_handle_struct *handle,
2270 struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2272 VFS_FIND(aio_cancel);
2273 return handle->fns->aio_cancel_fn(handle, fsp, aiocb);
2276 int smb_vfs_call_aio_error(struct vfs_handle_struct *handle,
2277 struct files_struct *fsp,
2278 SMB_STRUCT_AIOCB *aiocb)
2280 VFS_FIND(aio_error);
2281 return handle->fns->aio_error_fn(handle, fsp, aiocb);
2284 int smb_vfs_call_aio_fsync(struct vfs_handle_struct *handle,
2285 struct files_struct *fsp, int op,
2286 SMB_STRUCT_AIOCB *aiocb)
2288 VFS_FIND(aio_fsync);
2289 return handle->fns->aio_fsync_fn(handle, fsp, op, aiocb);
2292 int smb_vfs_call_aio_suspend(struct vfs_handle_struct *handle,
2293 struct files_struct *fsp,
2294 const SMB_STRUCT_AIOCB * const aiocb[], int n,
2295 const struct timespec *timeout)
2297 VFS_FIND(aio_suspend);
2298 return handle->fns->aio_suspend_fn(handle, fsp, aiocb, n, timeout);
2301 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2302 struct files_struct *fsp)
2304 VFS_FIND(aio_force);
2305 return handle->fns->aio_force_fn(handle, fsp);
2308 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2309 const struct smb_filename *fname,
2310 SMB_STRUCT_STAT *sbuf)
2312 VFS_FIND(is_offline);
2313 return handle->fns->is_offline_fn(handle, fname, sbuf);
2316 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2317 const struct smb_filename *fname)
2319 VFS_FIND(set_offline);
2320 return handle->fns->set_offline_fn(handle, fname);