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