s3:smbd: change blocking.c to use fsp_fnum_dbg() for fsp->fnum logging.
[Samba/gebeck_regimport.git] / source3 / smbd / vfs.c
blob32e3472efe8fd8eb00edc730072def0961377e41
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 *next;
279 for (curr = fsp->vfs_extension; curr; curr = next) {
281 next = curr->next;
282 fsp->vfs_extension = next;
284 if (curr->destroy) {
285 curr->destroy(EXT_DATA_AREA(curr));
287 TALLOC_FREE(curr);
291 void *vfs_memctx_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
293 struct vfs_fsp_data *head;
295 for (head = fsp->vfs_extension; head; head = head->next) {
296 if (head->owner == handle) {
297 return head;
301 return NULL;
304 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
306 struct vfs_fsp_data *head;
308 head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
309 if (head != NULL) {
310 return EXT_DATA_AREA(head);
313 return NULL;
316 #undef EXT_DATA_AREA
318 /*****************************************************************
319 Generic VFS init.
320 ******************************************************************/
322 bool smbd_vfs_init(connection_struct *conn)
324 const char **vfs_objects;
325 unsigned int i = 0;
326 int j = 0;
328 /* Normal share - initialise with disk access functions */
329 vfs_init_default(conn);
330 vfs_objects = lp_vfs_objects(SNUM(conn));
332 /* Override VFS functions if 'vfs object' was not specified*/
333 if (!vfs_objects || !vfs_objects[0])
334 return True;
336 for (i=0; vfs_objects[i] ;) {
337 i++;
340 for (j=i-1; j >= 0; j--) {
341 if (!vfs_init_custom(conn, vfs_objects[j])) {
342 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
343 return False;
346 return True;
349 /*******************************************************************
350 Check if a file exists in the vfs.
351 ********************************************************************/
353 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
355 /* Only return OK if stat was successful and S_ISREG */
356 if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
357 S_ISREG(smb_fname->st.st_ex_mode)) {
358 return NT_STATUS_OK;
361 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
364 /****************************************************************************
365 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
366 ****************************************************************************/
368 ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
370 size_t total=0;
372 while (total < byte_count)
374 ssize_t ret = SMB_VFS_READ(fsp, buf + total,
375 byte_count - total);
377 if (ret == 0) return total;
378 if (ret == -1) {
379 if (errno == EINTR)
380 continue;
381 else
382 return -1;
384 total += ret;
386 return (ssize_t)total;
389 ssize_t vfs_pread_data(files_struct *fsp, char *buf,
390 size_t byte_count, off_t offset)
392 size_t total=0;
394 while (total < byte_count)
396 ssize_t ret = SMB_VFS_PREAD(fsp, buf + total,
397 byte_count - total, offset + total);
399 if (ret == 0) return total;
400 if (ret == -1) {
401 if (errno == EINTR)
402 continue;
403 else
404 return -1;
406 total += ret;
408 return (ssize_t)total;
411 /****************************************************************************
412 Write data to a fd on the vfs.
413 ****************************************************************************/
415 ssize_t vfs_write_data(struct smb_request *req,
416 files_struct *fsp,
417 const char *buffer,
418 size_t N)
420 size_t total=0;
421 ssize_t ret;
423 if (req && req->unread_bytes) {
424 SMB_ASSERT(req->unread_bytes == N);
425 /* VFS_RECVFILE must drain the socket
426 * before returning. */
427 req->unread_bytes = 0;
428 return SMB_VFS_RECVFILE(req->sconn->sock,
429 fsp,
430 (off_t)-1,
434 while (total < N) {
435 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
437 if (ret == -1)
438 return -1;
439 if (ret == 0)
440 return total;
442 total += ret;
444 return (ssize_t)total;
447 ssize_t vfs_pwrite_data(struct smb_request *req,
448 files_struct *fsp,
449 const char *buffer,
450 size_t N,
451 off_t offset)
453 size_t total=0;
454 ssize_t ret;
456 if (req && req->unread_bytes) {
457 SMB_ASSERT(req->unread_bytes == N);
458 /* VFS_RECVFILE must drain the socket
459 * before returning. */
460 req->unread_bytes = 0;
461 return SMB_VFS_RECVFILE(req->sconn->sock,
462 fsp,
463 offset,
467 while (total < N) {
468 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
469 offset + total);
471 if (ret == -1)
472 return -1;
473 if (ret == 0)
474 return total;
476 total += ret;
478 return (ssize_t)total;
480 /****************************************************************************
481 An allocate file space call using the vfs interface.
482 Allocates space for a file from a filedescriptor.
483 Returns 0 on success, -1 on failure.
484 ****************************************************************************/
486 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
488 int ret;
489 connection_struct *conn = fsp->conn;
490 uint64_t space_avail;
491 uint64_t bsize,dfree,dsize;
492 NTSTATUS status;
495 * Actually try and commit the space on disk....
498 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
499 fsp_str_dbg(fsp), (double)len));
501 if (((off_t)len) < 0) {
502 DEBUG(0,("vfs_allocate_file_space: %s negative len "
503 "requested.\n", fsp_str_dbg(fsp)));
504 errno = EINVAL;
505 return -1;
508 status = vfs_stat_fsp(fsp);
509 if (!NT_STATUS_IS_OK(status)) {
510 return -1;
513 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
514 return 0;
516 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
517 /* Shrink - use ftruncate. */
519 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
520 "size %.0f\n", fsp_str_dbg(fsp),
521 (double)fsp->fsp_name->st.st_ex_size));
523 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
525 flush_write_cache(fsp, SIZECHANGE_FLUSH);
526 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
527 set_filelen_write_cache(fsp, len);
530 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
532 return ret;
535 if (!lp_strict_allocate(SNUM(fsp->conn)))
536 return 0;
538 /* Grow - we need to test if we have enough space. */
540 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
542 /* See if we have a syscall that will allocate beyond end-of-file
543 without changing EOF. */
544 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
546 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
548 if (ret == 0) {
549 /* We changed the allocation size on disk, but not
550 EOF - exactly as required. We're done ! */
551 return 0;
554 len -= fsp->fsp_name->st.st_ex_size;
555 len /= 1024; /* Len is now number of 1k blocks needed. */
556 space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
557 &bsize, &dfree, &dsize);
558 if (space_avail == (uint64_t)-1) {
559 return -1;
562 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
563 "needed blocks = %.0f, space avail = %.0f\n",
564 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
565 (double)space_avail));
567 if (len > space_avail) {
568 errno = ENOSPC;
569 return -1;
572 return 0;
575 /****************************************************************************
576 A vfs set_filelen call.
577 set the length of a file from a filedescriptor.
578 Returns 0 on success, -1 on failure.
579 ****************************************************************************/
581 int vfs_set_filelen(files_struct *fsp, off_t len)
583 int ret;
585 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
587 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
588 fsp_str_dbg(fsp), (double)len));
589 flush_write_cache(fsp, SIZECHANGE_FLUSH);
590 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
591 set_filelen_write_cache(fsp, len);
592 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
593 FILE_NOTIFY_CHANGE_SIZE
594 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
595 fsp->fsp_name->base_name);
598 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
600 return ret;
603 /****************************************************************************
604 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
605 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
606 as this is also called from the default SMB_VFS_FTRUNCATE code.
607 Always extends the file size.
608 Returns 0 on success, errno on failure.
609 ****************************************************************************/
611 #define SPARSE_BUF_WRITE_SIZE (32*1024)
613 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
615 ssize_t pwrite_ret;
616 size_t total = 0;
618 if (!sparse_buf) {
619 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
620 if (!sparse_buf) {
621 errno = ENOMEM;
622 return ENOMEM;
626 while (total < len) {
627 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
629 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
630 if (pwrite_ret == -1) {
631 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
632 "%s failed with error %s\n",
633 fsp_str_dbg(fsp), strerror(errno)));
634 return errno;
636 total += pwrite_ret;
639 return 0;
642 /****************************************************************************
643 A vfs fill sparse call.
644 Writes zeros from the end of file to len, if len is greater than EOF.
645 Used only by strict_sync.
646 Returns 0 on success, -1 on failure.
647 ****************************************************************************/
649 int vfs_fill_sparse(files_struct *fsp, off_t len)
651 int ret;
652 NTSTATUS status;
653 off_t offset;
654 size_t num_to_write;
656 status = vfs_stat_fsp(fsp);
657 if (!NT_STATUS_IS_OK(status)) {
658 return -1;
661 if (len <= fsp->fsp_name->st.st_ex_size) {
662 return 0;
665 #ifdef S_ISFIFO
666 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
667 return 0;
669 #endif
671 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
672 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
673 (double)fsp->fsp_name->st.st_ex_size, (double)len,
674 (double)(len - fsp->fsp_name->st.st_ex_size)));
676 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
678 flush_write_cache(fsp, SIZECHANGE_FLUSH);
680 offset = fsp->fsp_name->st.st_ex_size;
681 num_to_write = len - fsp->fsp_name->st.st_ex_size;
683 /* Only do this on non-stream file handles. */
684 if (fsp->base_fsp == NULL) {
685 /* for allocation try fallocate first. This can fail on some
686 * platforms e.g. when the filesystem doesn't support it and no
687 * emulation is being done by the libc (like on AIX with JFS1). In that
688 * case we do our own emulation. fallocate implementations can
689 * return ENOTSUP or EINVAL in cases like that. */
690 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
691 offset, num_to_write);
692 if (ret == ENOSPC) {
693 errno = ENOSPC;
694 ret = -1;
695 goto out;
697 if (ret == 0) {
698 goto out;
700 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
701 "error %d. Falling back to slow manual allocation\n", ret));
704 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
705 if (ret != 0) {
706 errno = ret;
707 ret = -1;
710 out:
712 if (ret == 0) {
713 set_filelen_write_cache(fsp, len);
716 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
717 return ret;
720 /****************************************************************************
721 Transfer some data (n bytes) between two file_struct's.
722 ****************************************************************************/
724 static ssize_t vfs_read_fn(void *file, void *buf, size_t len)
726 struct files_struct *fsp = (struct files_struct *)file;
728 return SMB_VFS_READ(fsp, buf, len);
731 static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
733 struct files_struct *fsp = (struct files_struct *)file;
735 return SMB_VFS_WRITE(fsp, buf, len);
738 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
740 return transfer_file_internal((void *)in, (void *)out, n,
741 vfs_read_fn, vfs_write_fn);
744 /*******************************************************************
745 A vfs_readdir wrapper which just returns the file name.
746 ********************************************************************/
748 const char *vfs_readdirname(connection_struct *conn, void *p,
749 SMB_STRUCT_STAT *sbuf, char **talloced)
751 struct dirent *ptr= NULL;
752 const char *dname;
753 char *translated;
754 NTSTATUS status;
756 if (!p)
757 return(NULL);
759 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
760 if (!ptr)
761 return(NULL);
763 dname = ptr->d_name;
766 #ifdef NEXT2
767 if (telldir(p) < 0)
768 return(NULL);
769 #endif
771 #ifdef HAVE_BROKEN_READDIR_NAME
772 /* using /usr/ucb/cc is BAD */
773 dname = dname - 2;
774 #endif
776 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
777 talloc_tos(), &translated);
778 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
779 *talloced = NULL;
780 return dname;
782 *talloced = translated;
783 if (!NT_STATUS_IS_OK(status)) {
784 return NULL;
786 return translated;
789 /*******************************************************************
790 A wrapper for vfs_chdir().
791 ********************************************************************/
793 int vfs_ChDir(connection_struct *conn, const char *path)
795 int res;
797 if (!LastDir) {
798 LastDir = SMB_STRDUP("");
801 if (strcsequal(path,"."))
802 return(0);
804 if (*path == '/' && strcsequal(LastDir,path))
805 return(0);
807 DEBUG(4,("vfs_ChDir to %s\n",path));
809 res = SMB_VFS_CHDIR(conn,path);
810 if (!res) {
811 SAFE_FREE(LastDir);
812 LastDir = SMB_STRDUP(path);
814 return(res);
817 /*******************************************************************
818 Return the absolute current directory path - given a UNIX pathname.
819 Note that this path is returned in DOS format, not UNIX
820 format. Note this can be called with conn == NULL.
821 ********************************************************************/
823 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
825 char *current_dir = NULL;
826 char *result = NULL;
827 DATA_BLOB cache_value;
828 struct file_id key;
829 struct smb_filename *smb_fname_dot = NULL;
830 struct smb_filename *smb_fname_full = NULL;
831 NTSTATUS status;
833 if (!lp_getwd_cache()) {
834 goto nocache;
837 status = create_synthetic_smb_fname(ctx, ".", NULL, NULL,
838 &smb_fname_dot);
839 if (!NT_STATUS_IS_OK(status)) {
840 errno = map_errno_from_nt_status(status);
841 goto out;
844 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
846 * Known to fail for root: the directory may be NFS-mounted
847 * and exported with root_squash (so has no root access).
849 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
850 "(NFS problem ?)\n", strerror(errno) ));
851 goto nocache;
854 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
856 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
857 data_blob_const(&key, sizeof(key)),
858 &cache_value)) {
859 goto nocache;
862 SMB_ASSERT((cache_value.length > 0)
863 && (cache_value.data[cache_value.length-1] == '\0'));
865 status = create_synthetic_smb_fname(ctx, (char *)cache_value.data,
866 NULL, NULL, &smb_fname_full);
867 if (!NT_STATUS_IS_OK(status)) {
868 errno = map_errno_from_nt_status(status);
869 goto out;
872 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
873 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
874 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
875 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
877 * Ok, we're done
879 result = talloc_strdup(ctx, smb_fname_full->base_name);
880 if (result == NULL) {
881 errno = ENOMEM;
883 goto out;
886 nocache:
889 * We don't have the information to hand so rely on traditional
890 * methods. The very slow getcwd, which spawns a process on some
891 * systems, or the not quite so bad getwd.
894 current_dir = SMB_VFS_GETWD(conn);
895 if (current_dir == NULL) {
896 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
897 strerror(errno)));
898 goto out;
901 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
902 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
904 memcache_add(smbd_memcache(), GETWD_CACHE,
905 data_blob_const(&key, sizeof(key)),
906 data_blob_const(current_dir,
907 strlen(current_dir)+1));
910 result = talloc_strdup(ctx, current_dir);
911 if (result == NULL) {
912 errno = ENOMEM;
915 out:
916 TALLOC_FREE(smb_fname_dot);
917 TALLOC_FREE(smb_fname_full);
918 SAFE_FREE(current_dir);
919 return result;
922 /*******************************************************************
923 Reduce a file name, removing .. elements and checking that
924 it is below dir in the heirachy. This uses realpath.
925 This function must run as root, and will return names
926 and valid stat structs that can be checked on open.
927 ********************************************************************/
929 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
930 const char *fname,
931 struct smb_request *smbreq)
933 NTSTATUS status;
934 TALLOC_CTX *ctx = talloc_tos();
935 const char *conn_rootdir;
936 size_t rootdir_len;
937 char *dir_name = NULL;
938 const char *last_component = NULL;
939 char *resolved_name = NULL;
940 char *saved_dir = NULL;
941 struct smb_filename *smb_fname_cwd = NULL;
942 struct privilege_paths *priv_paths = NULL;
943 int ret;
945 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
946 fname,
947 conn->connectpath));
950 priv_paths = talloc_zero(smbreq, struct privilege_paths);
951 if (!priv_paths) {
952 status = NT_STATUS_NO_MEMORY;
953 goto err;
956 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
957 status = NT_STATUS_NO_MEMORY;
958 goto err;
961 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
962 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
964 if (priv_paths->parent_name.base_name == NULL ||
965 priv_paths->file_name.base_name == NULL) {
966 status = NT_STATUS_NO_MEMORY;
967 goto err;
970 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
971 status = map_nt_error_from_unix(errno);
972 goto err;
974 /* Remember where we were. */
975 saved_dir = vfs_GetWd(ctx, conn);
976 if (!saved_dir) {
977 status = map_nt_error_from_unix(errno);
978 goto err;
981 /* Go to the parent directory to lock in memory. */
982 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
983 status = map_nt_error_from_unix(errno);
984 goto err;
987 /* Get the absolute path of the parent directory. */
988 resolved_name = SMB_VFS_REALPATH(conn,".");
989 if (!resolved_name) {
990 status = map_nt_error_from_unix(errno);
991 goto err;
994 if (*resolved_name != '/') {
995 DEBUG(0,("check_reduced_name_with_privilege: realpath "
996 "doesn't return absolute paths !\n"));
997 status = NT_STATUS_OBJECT_NAME_INVALID;
998 goto err;
1001 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1002 priv_paths->parent_name.base_name,
1003 resolved_name));
1005 /* Now check the stat value is the same. */
1006 status = create_synthetic_smb_fname(talloc_tos(), ".",
1007 NULL, NULL,
1008 &smb_fname_cwd);
1009 if (!NT_STATUS_IS_OK(status)) {
1010 goto err;
1013 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1014 status = map_nt_error_from_unix(errno);
1015 goto err;
1018 /* Ensure we're pointing at the same place. */
1019 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1020 DEBUG(0,("check_reduced_name_with_privilege: "
1021 "device/inode/uid/gid on directory %s changed. "
1022 "Denying access !\n",
1023 priv_paths->parent_name.base_name));
1024 status = NT_STATUS_ACCESS_DENIED;
1025 goto err;
1028 /* Ensure we're below the connect path. */
1030 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1031 if (conn_rootdir == NULL) {
1032 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1033 "conn_rootdir\n"));
1034 status = NT_STATUS_ACCESS_DENIED;
1035 goto err;
1038 rootdir_len = strlen(conn_rootdir);
1039 if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1040 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1041 "attempt: %s is a symlink outside the "
1042 "share path\n",
1043 dir_name));
1044 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1045 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1046 status = NT_STATUS_ACCESS_DENIED;
1047 goto err;
1050 /* Now ensure that the last component either doesn't
1051 exist, or is *NOT* a symlink. */
1053 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1054 if (ret == -1) {
1055 /* Errno must be ENOENT for this be ok. */
1056 if (errno != ENOENT) {
1057 status = map_nt_error_from_unix(errno);
1058 DEBUG(2, ("check_reduced_name_with_privilege: "
1059 "LSTAT on %s failed with %s\n",
1060 priv_paths->file_name.base_name,
1061 nt_errstr(status)));
1062 goto err;
1066 if (VALID_STAT(priv_paths->file_name.st) &&
1067 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1068 DEBUG(2, ("check_reduced_name_with_privilege: "
1069 "Last component %s is a symlink. Denying"
1070 "access.\n",
1071 priv_paths->file_name.base_name));
1072 status = NT_STATUS_ACCESS_DENIED;
1073 goto err;
1076 smbreq->priv_paths = priv_paths;
1077 status = NT_STATUS_OK;
1079 err:
1081 if (saved_dir) {
1082 vfs_ChDir(conn, saved_dir);
1084 SAFE_FREE(resolved_name);
1085 if (!NT_STATUS_IS_OK(status)) {
1086 TALLOC_FREE(priv_paths);
1088 return status;
1091 /*******************************************************************
1092 Reduce a file name, removing .. elements and checking that
1093 it is below dir in the heirachy. This uses realpath.
1094 ********************************************************************/
1096 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1098 char *resolved_name = NULL;
1099 bool allow_symlinks = true;
1100 bool allow_widelinks = false;
1102 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1104 resolved_name = SMB_VFS_REALPATH(conn,fname);
1106 if (!resolved_name) {
1107 switch (errno) {
1108 case ENOTDIR:
1109 DEBUG(3,("check_reduced_name: Component not a "
1110 "directory in getting realpath for "
1111 "%s\n", fname));
1112 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1113 case ENOENT:
1115 TALLOC_CTX *ctx = talloc_tos();
1116 char *dir_name = NULL;
1117 const char *last_component = NULL;
1118 char *new_name = NULL;
1119 int ret;
1121 /* Last component didn't exist.
1122 Remove it and try and canonicalise
1123 the directory name. */
1124 if (!parent_dirname(ctx, fname,
1125 &dir_name,
1126 &last_component)) {
1127 return NT_STATUS_NO_MEMORY;
1130 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1131 if (!resolved_name) {
1132 NTSTATUS status = map_nt_error_from_unix(errno);
1134 if (errno == ENOENT || errno == ENOTDIR) {
1135 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1138 DEBUG(3,("check_reduce_name: "
1139 "couldn't get realpath for "
1140 "%s (%s)\n",
1141 fname,
1142 nt_errstr(status)));
1143 return status;
1145 ret = asprintf(&new_name, "%s/%s",
1146 resolved_name, last_component);
1147 SAFE_FREE(resolved_name);
1148 if (ret == -1) {
1149 return NT_STATUS_NO_MEMORY;
1151 resolved_name = new_name;
1152 break;
1154 default:
1155 DEBUG(3,("check_reduced_name: couldn't get "
1156 "realpath for %s\n", fname));
1157 return map_nt_error_from_unix(errno);
1161 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1162 resolved_name));
1164 if (*resolved_name != '/') {
1165 DEBUG(0,("check_reduced_name: realpath doesn't return "
1166 "absolute paths !\n"));
1167 SAFE_FREE(resolved_name);
1168 return NT_STATUS_OBJECT_NAME_INVALID;
1171 allow_widelinks = lp_widelinks(SNUM(conn));
1172 allow_symlinks = lp_symlinks(SNUM(conn));
1174 /* Common widelinks and symlinks checks. */
1175 if (!allow_widelinks || !allow_symlinks) {
1176 const char *conn_rootdir;
1177 size_t rootdir_len;
1179 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1180 if (conn_rootdir == NULL) {
1181 DEBUG(2, ("check_reduced_name: Could not get "
1182 "conn_rootdir\n"));
1183 SAFE_FREE(resolved_name);
1184 return NT_STATUS_ACCESS_DENIED;
1187 rootdir_len = strlen(conn_rootdir);
1188 if (strncmp(conn_rootdir, resolved_name,
1189 rootdir_len) != 0) {
1190 DEBUG(2, ("check_reduced_name: Bad access "
1191 "attempt: %s is a symlink outside the "
1192 "share path\n", fname));
1193 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1194 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1195 SAFE_FREE(resolved_name);
1196 return NT_STATUS_ACCESS_DENIED;
1199 /* Extra checks if all symlinks are disallowed. */
1200 if (!allow_symlinks) {
1201 /* fname can't have changed in resolved_path. */
1202 const char *p = &resolved_name[rootdir_len];
1204 /* *p can be '\0' if fname was "." */
1205 if (*p == '\0' && ISDOT(fname)) {
1206 goto out;
1209 if (*p != '/') {
1210 DEBUG(2, ("check_reduced_name: logic error (%c) "
1211 "in resolved_name: %s\n",
1213 fname));
1214 SAFE_FREE(resolved_name);
1215 return NT_STATUS_ACCESS_DENIED;
1218 p++;
1219 if (strcmp(fname, p)!=0) {
1220 DEBUG(2, ("check_reduced_name: Bad access "
1221 "attempt: %s is a symlink\n",
1222 fname));
1223 SAFE_FREE(resolved_name);
1224 return NT_STATUS_ACCESS_DENIED;
1229 out:
1231 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1232 resolved_name));
1233 SAFE_FREE(resolved_name);
1234 return NT_STATUS_OK;
1238 * XXX: This is temporary and there should be no callers of this once
1239 * smb_filename is plumbed through all path based operations.
1241 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1242 SMB_STRUCT_STAT *psbuf)
1244 struct smb_filename *smb_fname = NULL;
1245 NTSTATUS status;
1246 int ret;
1248 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1249 &smb_fname);
1250 if (!NT_STATUS_IS_OK(status)) {
1251 errno = map_errno_from_nt_status(status);
1252 return -1;
1255 if (lp_posix_pathnames()) {
1256 ret = SMB_VFS_LSTAT(conn, smb_fname);
1257 } else {
1258 ret = SMB_VFS_STAT(conn, smb_fname);
1261 if (ret != -1) {
1262 *psbuf = smb_fname->st;
1265 TALLOC_FREE(smb_fname);
1266 return ret;
1270 * XXX: This is temporary and there should be no callers of this once
1271 * smb_filename is plumbed through all path based operations.
1273 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1274 SMB_STRUCT_STAT *psbuf)
1276 struct smb_filename *smb_fname = NULL;
1277 NTSTATUS status;
1278 int ret;
1280 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1281 &smb_fname);
1282 if (!NT_STATUS_IS_OK(status)) {
1283 errno = map_errno_from_nt_status(status);
1284 return -1;
1287 ret = SMB_VFS_LSTAT(conn, smb_fname);
1288 if (ret != -1) {
1289 *psbuf = smb_fname->st;
1292 TALLOC_FREE(smb_fname);
1293 return ret;
1297 * Ensure LSTAT is called for POSIX paths.
1300 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1302 int ret;
1304 if(fsp->fh->fd == -1) {
1305 if (fsp->posix_open) {
1306 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1307 } else {
1308 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1310 if (ret == -1) {
1311 return map_nt_error_from_unix(errno);
1313 } else {
1314 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1315 return map_nt_error_from_unix(errno);
1318 return NT_STATUS_OK;
1322 * Initialize num_streams and streams, then call VFS op streaminfo
1324 NTSTATUS vfs_streaminfo(connection_struct *conn,
1325 struct files_struct *fsp,
1326 const char *fname,
1327 TALLOC_CTX *mem_ctx,
1328 unsigned int *num_streams,
1329 struct stream_struct **streams)
1331 *num_streams = 0;
1332 *streams = NULL;
1333 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1337 generate a file_id from a stat structure
1339 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1341 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1344 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1345 const char *service, const char *user)
1347 VFS_FIND(connect);
1348 return handle->fns->connect_fn(handle, service, user);
1351 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1353 VFS_FIND(disconnect);
1354 handle->fns->disconnect_fn(handle);
1357 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1358 const char *path, bool small_query,
1359 uint64_t *bsize, uint64_t *dfree,
1360 uint64_t *dsize)
1362 VFS_FIND(disk_free);
1363 return handle->fns->disk_free_fn(handle, path, small_query, bsize,
1364 dfree, dsize);
1367 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1368 enum SMB_QUOTA_TYPE qtype, unid_t id,
1369 SMB_DISK_QUOTA *qt)
1371 VFS_FIND(get_quota);
1372 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1375 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1376 enum SMB_QUOTA_TYPE qtype, unid_t id,
1377 SMB_DISK_QUOTA *qt)
1379 VFS_FIND(set_quota);
1380 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1383 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1384 struct files_struct *fsp,
1385 struct shadow_copy_data *shadow_copy_data,
1386 bool labels)
1388 VFS_FIND(get_shadow_copy_data);
1389 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1390 shadow_copy_data,
1391 labels);
1393 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1394 struct vfs_statvfs_struct *statbuf)
1396 VFS_FIND(statvfs);
1397 return handle->fns->statvfs_fn(handle, path, statbuf);
1400 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1401 enum timestamp_set_resolution *p_ts_res)
1403 VFS_FIND(fs_capabilities);
1404 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1407 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1408 struct dfs_GetDFSReferral *r)
1410 VFS_FIND(get_dfs_referrals);
1411 return handle->fns->get_dfs_referrals_fn(handle, r);
1414 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1415 const char *fname, const char *mask,
1416 uint32 attributes)
1418 VFS_FIND(opendir);
1419 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1422 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1423 struct files_struct *fsp,
1424 const char *mask,
1425 uint32 attributes)
1427 VFS_FIND(fdopendir);
1428 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1431 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1432 DIR *dirp,
1433 SMB_STRUCT_STAT *sbuf)
1435 VFS_FIND(readdir);
1436 return handle->fns->readdir_fn(handle, dirp, sbuf);
1439 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1440 DIR *dirp, long offset)
1442 VFS_FIND(seekdir);
1443 handle->fns->seekdir_fn(handle, dirp, offset);
1446 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1447 DIR *dirp)
1449 VFS_FIND(telldir);
1450 return handle->fns->telldir_fn(handle, dirp);
1453 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1454 DIR *dirp)
1456 VFS_FIND(rewind_dir);
1457 handle->fns->rewind_dir_fn(handle, dirp);
1460 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1461 mode_t mode)
1463 VFS_FIND(mkdir);
1464 return handle->fns->mkdir_fn(handle, path, mode);
1467 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1469 VFS_FIND(rmdir);
1470 return handle->fns->rmdir_fn(handle, path);
1473 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1474 DIR *dir)
1476 VFS_FIND(closedir);
1477 return handle->fns->closedir_fn(handle, dir);
1480 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1481 DIR *dirp)
1483 VFS_FIND(init_search_op);
1484 handle->fns->init_search_op_fn(handle, dirp);
1487 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1488 struct smb_filename *smb_fname, struct files_struct *fsp,
1489 int flags, mode_t mode)
1491 VFS_FIND(open);
1492 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1495 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1496 struct smb_request *req,
1497 uint16_t root_dir_fid,
1498 struct smb_filename *smb_fname,
1499 uint32_t access_mask,
1500 uint32_t share_access,
1501 uint32_t create_disposition,
1502 uint32_t create_options,
1503 uint32_t file_attributes,
1504 uint32_t oplock_request,
1505 uint64_t allocation_size,
1506 uint32_t private_flags,
1507 struct security_descriptor *sd,
1508 struct ea_list *ea_list,
1509 files_struct **result,
1510 int *pinfo)
1512 VFS_FIND(create_file);
1513 return handle->fns->create_file_fn(
1514 handle, req, root_dir_fid, smb_fname, access_mask,
1515 share_access, create_disposition, create_options,
1516 file_attributes, oplock_request, allocation_size,
1517 private_flags, sd, ea_list,
1518 result, pinfo);
1521 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1522 struct files_struct *fsp)
1524 VFS_FIND(close);
1525 return handle->fns->close_fn(handle, fsp);
1528 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1529 struct files_struct *fsp, void *data, size_t n)
1531 VFS_FIND(read);
1532 return handle->fns->read_fn(handle, fsp, data, n);
1535 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1536 struct files_struct *fsp, void *data, size_t n,
1537 off_t offset)
1539 VFS_FIND(pread);
1540 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1543 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1544 struct files_struct *fsp, const void *data,
1545 size_t n)
1547 VFS_FIND(write);
1548 return handle->fns->write_fn(handle, fsp, data, n);
1551 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1552 struct files_struct *fsp, const void *data,
1553 size_t n, off_t offset)
1555 VFS_FIND(pwrite);
1556 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1559 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1560 struct files_struct *fsp, off_t offset,
1561 int whence)
1563 VFS_FIND(lseek);
1564 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1567 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1568 files_struct *fromfsp, const DATA_BLOB *header,
1569 off_t offset, size_t count)
1571 VFS_FIND(sendfile);
1572 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1573 count);
1576 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1577 files_struct *tofsp, off_t offset,
1578 size_t count)
1580 VFS_FIND(recvfile);
1581 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1584 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1585 const struct smb_filename *smb_fname_src,
1586 const struct smb_filename *smb_fname_dst)
1588 VFS_FIND(rename);
1589 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1592 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1593 struct files_struct *fsp)
1595 VFS_FIND(fsync);
1596 return handle->fns->fsync_fn(handle, fsp);
1599 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1600 struct smb_filename *smb_fname)
1602 VFS_FIND(stat);
1603 return handle->fns->stat_fn(handle, smb_fname);
1606 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1607 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1609 VFS_FIND(fstat);
1610 return handle->fns->fstat_fn(handle, fsp, sbuf);
1613 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1614 struct smb_filename *smb_filename)
1616 VFS_FIND(lstat);
1617 return handle->fns->lstat_fn(handle, smb_filename);
1620 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1621 struct files_struct *fsp,
1622 const SMB_STRUCT_STAT *sbuf)
1624 VFS_FIND(get_alloc_size);
1625 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1628 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1629 const struct smb_filename *smb_fname)
1631 VFS_FIND(unlink);
1632 return handle->fns->unlink_fn(handle, smb_fname);
1635 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1636 mode_t mode)
1638 VFS_FIND(chmod);
1639 return handle->fns->chmod_fn(handle, path, mode);
1642 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1643 struct files_struct *fsp, mode_t mode)
1645 VFS_FIND(fchmod);
1646 return handle->fns->fchmod_fn(handle, fsp, mode);
1649 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1650 uid_t uid, gid_t gid)
1652 VFS_FIND(chown);
1653 return handle->fns->chown_fn(handle, path, uid, gid);
1656 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1657 struct files_struct *fsp, uid_t uid, gid_t gid)
1659 VFS_FIND(fchown);
1660 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1663 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1664 uid_t uid, gid_t gid)
1666 VFS_FIND(lchown);
1667 return handle->fns->lchown_fn(handle, path, uid, gid);
1670 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1672 int ret;
1673 bool as_root = false;
1674 const char *path;
1675 char *saved_dir = NULL;
1676 char *parent_dir = NULL;
1677 NTSTATUS status;
1679 if (fsp->fh->fd != -1) {
1680 /* Try fchown. */
1681 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1682 if (ret == 0) {
1683 return NT_STATUS_OK;
1685 if (ret == -1 && errno != ENOSYS) {
1686 return map_nt_error_from_unix(errno);
1690 as_root = (geteuid() == 0);
1692 if (as_root) {
1694 * We are being asked to chown as root. Make
1695 * sure we chdir() into the path to pin it,
1696 * and always act using lchown to ensure we
1697 * don't deref any symbolic links.
1699 const char *final_component = NULL;
1700 struct smb_filename local_fname;
1702 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1703 if (!saved_dir) {
1704 status = map_nt_error_from_unix(errno);
1705 DEBUG(0,("vfs_chown_fsp: failed to get "
1706 "current working directory. Error was %s\n",
1707 strerror(errno)));
1708 return status;
1711 if (!parent_dirname(talloc_tos(),
1712 fsp->fsp_name->base_name,
1713 &parent_dir,
1714 &final_component)) {
1715 return NT_STATUS_NO_MEMORY;
1718 /* cd into the parent dir to pin it. */
1719 ret = vfs_ChDir(fsp->conn, parent_dir);
1720 if (ret == -1) {
1721 return map_nt_error_from_unix(errno);
1724 ZERO_STRUCT(local_fname);
1725 local_fname.base_name = discard_const_p(char, final_component);
1727 /* Must use lstat here. */
1728 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1729 if (ret == -1) {
1730 status = map_nt_error_from_unix(errno);
1731 goto out;
1734 /* Ensure it matches the fsp stat. */
1735 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1736 status = NT_STATUS_ACCESS_DENIED;
1737 goto out;
1739 path = final_component;
1740 } else {
1741 path = fsp->fsp_name->base_name;
1744 if (fsp->posix_open || as_root) {
1745 ret = SMB_VFS_LCHOWN(fsp->conn,
1746 path,
1747 uid, gid);
1748 } else {
1749 ret = SMB_VFS_CHOWN(fsp->conn,
1750 path,
1751 uid, gid);
1754 if (ret == 0) {
1755 status = NT_STATUS_OK;
1756 } else {
1757 status = map_nt_error_from_unix(errno);
1760 out:
1762 if (as_root) {
1763 vfs_ChDir(fsp->conn,saved_dir);
1764 TALLOC_FREE(saved_dir);
1765 TALLOC_FREE(parent_dir);
1767 return status;
1770 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1772 VFS_FIND(chdir);
1773 return handle->fns->chdir_fn(handle, path);
1776 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
1778 VFS_FIND(getwd);
1779 return handle->fns->getwd_fn(handle);
1782 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
1783 const struct smb_filename *smb_fname,
1784 struct smb_file_time *ft)
1786 VFS_FIND(ntimes);
1787 return handle->fns->ntimes_fn(handle, smb_fname, ft);
1790 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
1791 struct files_struct *fsp, off_t offset)
1793 VFS_FIND(ftruncate);
1794 return handle->fns->ftruncate_fn(handle, fsp, offset);
1797 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
1798 struct files_struct *fsp,
1799 enum vfs_fallocate_mode mode,
1800 off_t offset,
1801 off_t len)
1803 VFS_FIND(fallocate);
1804 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
1807 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
1808 struct files_struct *fsp, uint32 share_mode,
1809 uint32_t access_mask)
1811 VFS_FIND(kernel_flock);
1812 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
1813 access_mask);
1816 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
1817 struct files_struct *fsp, int leasetype)
1819 VFS_FIND(linux_setlease);
1820 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
1823 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
1824 const char *newpath)
1826 VFS_FIND(symlink);
1827 return handle->fns->symlink_fn(handle, oldpath, newpath);
1830 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
1831 const char *path, char *buf, size_t bufsiz)
1833 VFS_FIND(readlink);
1834 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
1837 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
1838 const char *newpath)
1840 VFS_FIND(link);
1841 return handle->fns->link_fn(handle, oldpath, newpath);
1844 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
1845 mode_t mode, SMB_DEV_T dev)
1847 VFS_FIND(mknod);
1848 return handle->fns->mknod_fn(handle, path, mode, dev);
1851 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
1853 VFS_FIND(realpath);
1854 return handle->fns->realpath_fn(handle, path);
1857 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
1858 struct sys_notify_context *ctx,
1859 const char *path,
1860 uint32_t *filter,
1861 uint32_t *subdir_filter,
1862 void (*callback)(struct sys_notify_context *ctx,
1863 void *private_data,
1864 struct notify_event *ev),
1865 void *private_data, void *handle_p)
1867 VFS_FIND(notify_watch);
1868 return handle->fns->notify_watch_fn(handle, ctx, path,
1869 filter, subdir_filter, callback,
1870 private_data, handle_p);
1873 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
1874 unsigned int flags)
1876 VFS_FIND(chflags);
1877 return handle->fns->chflags_fn(handle, path, flags);
1880 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
1881 const SMB_STRUCT_STAT *sbuf)
1883 VFS_FIND(file_id_create);
1884 return handle->fns->file_id_create_fn(handle, sbuf);
1887 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
1888 struct files_struct *fsp,
1889 const char *fname,
1890 TALLOC_CTX *mem_ctx,
1891 unsigned int *num_streams,
1892 struct stream_struct **streams)
1894 VFS_FIND(streaminfo);
1895 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
1896 num_streams, streams);
1899 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
1900 const char *path, const char *name,
1901 TALLOC_CTX *mem_ctx, char **found_name)
1903 VFS_FIND(get_real_filename);
1904 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
1905 found_name);
1908 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
1909 const char *filename)
1911 VFS_FIND(connectpath);
1912 return handle->fns->connectpath_fn(handle, filename);
1915 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
1916 struct files_struct *fsp,
1917 struct lock_struct *plock)
1919 VFS_FIND(strict_lock);
1920 return handle->fns->strict_lock_fn(handle, fsp, plock);
1923 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
1924 struct files_struct *fsp,
1925 struct lock_struct *plock)
1927 VFS_FIND(strict_unlock);
1928 handle->fns->strict_unlock_fn(handle, fsp, plock);
1931 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
1932 const char *name,
1933 enum vfs_translate_direction direction,
1934 TALLOC_CTX *mem_ctx,
1935 char **mapped_name)
1937 VFS_FIND(translate_name);
1938 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
1939 mapped_name);
1942 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
1943 struct files_struct *fsp,
1944 TALLOC_CTX *ctx,
1945 uint32_t function,
1946 uint16_t req_flags,
1947 const uint8_t *in_data,
1948 uint32_t in_len,
1949 uint8_t **out_data,
1950 uint32_t max_out_len,
1951 uint32_t *out_len)
1953 VFS_FIND(fsctl);
1954 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
1955 in_data, in_len, out_data, max_out_len,
1956 out_len);
1959 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
1960 struct files_struct *fsp,
1961 uint32 security_info,
1962 struct security_descriptor **ppdesc)
1964 VFS_FIND(fget_nt_acl);
1965 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
1966 ppdesc);
1969 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
1970 const char *name,
1971 uint32 security_info,
1972 struct security_descriptor **ppdesc)
1974 VFS_FIND(get_nt_acl);
1975 return handle->fns->get_nt_acl_fn(handle, name, security_info, ppdesc);
1978 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
1979 struct files_struct *fsp,
1980 uint32 security_info_sent,
1981 const struct security_descriptor *psd)
1983 VFS_FIND(fset_nt_acl);
1984 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
1985 psd);
1988 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
1989 struct smb_filename *file,
1990 struct security_acl *sacl,
1991 uint32_t access_requested,
1992 uint32_t access_denied)
1994 VFS_FIND(audit_file);
1995 return handle->fns->audit_file_fn(handle,
1996 file,
1997 sacl,
1998 access_requested,
1999 access_denied);
2002 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2003 mode_t mode)
2005 VFS_FIND(chmod_acl);
2006 return handle->fns->chmod_acl_fn(handle, name, mode);
2009 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2010 struct files_struct *fsp, mode_t mode)
2012 VFS_FIND(fchmod_acl);
2013 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2016 int smb_vfs_call_sys_acl_get_entry(struct vfs_handle_struct *handle,
2017 SMB_ACL_T theacl, int entry_id,
2018 SMB_ACL_ENTRY_T *entry_p)
2020 VFS_FIND(sys_acl_get_entry);
2021 return handle->fns->sys_acl_get_entry_fn(handle, theacl, entry_id,
2022 entry_p);
2025 int smb_vfs_call_sys_acl_get_tag_type(struct vfs_handle_struct *handle,
2026 SMB_ACL_ENTRY_T entry_d,
2027 SMB_ACL_TAG_T *tag_type_p)
2029 VFS_FIND(sys_acl_get_tag_type);
2030 return handle->fns->sys_acl_get_tag_type_fn(handle, entry_d,
2031 tag_type_p);
2034 int smb_vfs_call_sys_acl_get_permset(struct vfs_handle_struct *handle,
2035 SMB_ACL_ENTRY_T entry_d,
2036 SMB_ACL_PERMSET_T *permset_p)
2038 VFS_FIND(sys_acl_get_permset);
2039 return handle->fns->sys_acl_get_permset_fn(handle, entry_d, permset_p);
2042 void * smb_vfs_call_sys_acl_get_qualifier(struct vfs_handle_struct *handle,
2043 SMB_ACL_ENTRY_T entry_d)
2045 VFS_FIND(sys_acl_get_qualifier);
2046 return handle->fns->sys_acl_get_qualifier_fn(handle, entry_d);
2049 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2050 const char *path_p,
2051 SMB_ACL_TYPE_T type)
2053 VFS_FIND(sys_acl_get_file);
2054 return handle->fns->sys_acl_get_file_fn(handle, path_p, type);
2057 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2058 struct files_struct *fsp)
2060 VFS_FIND(sys_acl_get_fd);
2061 return handle->fns->sys_acl_get_fd_fn(handle, fsp);
2064 int smb_vfs_call_sys_acl_clear_perms(struct vfs_handle_struct *handle,
2065 SMB_ACL_PERMSET_T permset)
2067 VFS_FIND(sys_acl_clear_perms);
2068 return handle->fns->sys_acl_clear_perms_fn(handle, permset);
2071 int smb_vfs_call_sys_acl_add_perm(struct vfs_handle_struct *handle,
2072 SMB_ACL_PERMSET_T permset,
2073 SMB_ACL_PERM_T perm)
2075 VFS_FIND(sys_acl_add_perm);
2076 return handle->fns->sys_acl_add_perm_fn(handle, permset, perm);
2079 char * smb_vfs_call_sys_acl_to_text(struct vfs_handle_struct *handle,
2080 SMB_ACL_T theacl, ssize_t *plen)
2082 VFS_FIND(sys_acl_to_text);
2083 return handle->fns->sys_acl_to_text_fn(handle, theacl, plen);
2086 SMB_ACL_T smb_vfs_call_sys_acl_init(struct vfs_handle_struct *handle,
2087 int count)
2089 VFS_FIND(sys_acl_init);
2090 return handle->fns->sys_acl_init_fn(handle, count);
2093 int smb_vfs_call_sys_acl_create_entry(struct vfs_handle_struct *handle,
2094 SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2096 VFS_FIND(sys_acl_create_entry);
2097 return handle->fns->sys_acl_create_entry_fn(handle, pacl, pentry);
2100 int smb_vfs_call_sys_acl_set_tag_type(struct vfs_handle_struct *handle,
2101 SMB_ACL_ENTRY_T entry,
2102 SMB_ACL_TAG_T tagtype)
2104 VFS_FIND(sys_acl_set_tag_type);
2105 return handle->fns->sys_acl_set_tag_type_fn(handle, entry, tagtype);
2108 int smb_vfs_call_sys_acl_set_qualifier(struct vfs_handle_struct *handle,
2109 SMB_ACL_ENTRY_T entry, void *qual)
2111 VFS_FIND(sys_acl_set_qualifier);
2112 return handle->fns->sys_acl_set_qualifier_fn(handle, entry, qual);
2115 int smb_vfs_call_sys_acl_set_permset(struct vfs_handle_struct *handle,
2116 SMB_ACL_ENTRY_T entry,
2117 SMB_ACL_PERMSET_T permset)
2119 VFS_FIND(sys_acl_set_permset);
2120 return handle->fns->sys_acl_set_permset_fn(handle, entry, permset);
2123 int smb_vfs_call_sys_acl_valid(struct vfs_handle_struct *handle,
2124 SMB_ACL_T theacl)
2126 VFS_FIND(sys_acl_valid);
2127 return handle->fns->sys_acl_valid_fn(handle, theacl);
2130 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2131 const char *name, SMB_ACL_TYPE_T acltype,
2132 SMB_ACL_T theacl)
2134 VFS_FIND(sys_acl_set_file);
2135 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2138 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2139 struct files_struct *fsp, SMB_ACL_T theacl)
2141 VFS_FIND(sys_acl_set_fd);
2142 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2145 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2146 const char *path)
2148 VFS_FIND(sys_acl_delete_def_file);
2149 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2152 int smb_vfs_call_sys_acl_get_perm(struct vfs_handle_struct *handle,
2153 SMB_ACL_PERMSET_T permset,
2154 SMB_ACL_PERM_T perm)
2156 VFS_FIND(sys_acl_get_perm);
2157 return handle->fns->sys_acl_get_perm_fn(handle, permset, perm);
2160 int smb_vfs_call_sys_acl_free_text(struct vfs_handle_struct *handle,
2161 char *text)
2163 VFS_FIND(sys_acl_free_text);
2164 return handle->fns->sys_acl_free_text_fn(handle, text);
2167 int smb_vfs_call_sys_acl_free_acl(struct vfs_handle_struct *handle,
2168 SMB_ACL_T posix_acl)
2170 VFS_FIND(sys_acl_free_acl);
2171 return handle->fns->sys_acl_free_acl_fn(handle, posix_acl);
2174 int smb_vfs_call_sys_acl_free_qualifier(struct vfs_handle_struct *handle,
2175 void *qualifier, SMB_ACL_TAG_T tagtype)
2177 VFS_FIND(sys_acl_free_qualifier);
2178 return handle->fns->sys_acl_free_qualifier_fn(handle, qualifier,
2179 tagtype);
2182 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2183 const char *path, const char *name, void *value,
2184 size_t size)
2186 VFS_FIND(getxattr);
2187 return handle->fns->getxattr_fn(handle, path, name, value, size);
2190 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2191 struct files_struct *fsp, const char *name,
2192 void *value, size_t size)
2194 VFS_FIND(fgetxattr);
2195 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2198 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2199 const char *path, char *list, size_t size)
2201 VFS_FIND(listxattr);
2202 return handle->fns->listxattr_fn(handle, path, list, size);
2205 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2206 struct files_struct *fsp, char *list,
2207 size_t size)
2209 VFS_FIND(flistxattr);
2210 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2213 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2214 const char *path, const char *name)
2216 VFS_FIND(removexattr);
2217 return handle->fns->removexattr_fn(handle, path, name);
2220 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2221 struct files_struct *fsp, const char *name)
2223 VFS_FIND(fremovexattr);
2224 return handle->fns->fremovexattr_fn(handle, fsp, name);
2227 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2228 const char *name, const void *value, size_t size,
2229 int flags)
2231 VFS_FIND(setxattr);
2232 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2235 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2236 struct files_struct *fsp, const char *name,
2237 const void *value, size_t size, int flags)
2239 VFS_FIND(fsetxattr);
2240 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2243 int smb_vfs_call_aio_read(struct vfs_handle_struct *handle,
2244 struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2246 VFS_FIND(aio_read);
2247 return handle->fns->aio_read_fn(handle, fsp, aiocb);
2250 int smb_vfs_call_aio_write(struct vfs_handle_struct *handle,
2251 struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2253 VFS_FIND(aio_write);
2254 return handle->fns->aio_write_fn(handle, fsp, aiocb);
2257 ssize_t smb_vfs_call_aio_return(struct vfs_handle_struct *handle,
2258 struct files_struct *fsp,
2259 SMB_STRUCT_AIOCB *aiocb)
2261 VFS_FIND(aio_return);
2262 return handle->fns->aio_return_fn(handle, fsp, aiocb);
2265 int smb_vfs_call_aio_cancel(struct vfs_handle_struct *handle,
2266 struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2268 VFS_FIND(aio_cancel);
2269 return handle->fns->aio_cancel_fn(handle, fsp, aiocb);
2272 int smb_vfs_call_aio_error(struct vfs_handle_struct *handle,
2273 struct files_struct *fsp,
2274 SMB_STRUCT_AIOCB *aiocb)
2276 VFS_FIND(aio_error);
2277 return handle->fns->aio_error_fn(handle, fsp, aiocb);
2280 int smb_vfs_call_aio_fsync(struct vfs_handle_struct *handle,
2281 struct files_struct *fsp, int op,
2282 SMB_STRUCT_AIOCB *aiocb)
2284 VFS_FIND(aio_fsync);
2285 return handle->fns->aio_fsync_fn(handle, fsp, op, aiocb);
2288 int smb_vfs_call_aio_suspend(struct vfs_handle_struct *handle,
2289 struct files_struct *fsp,
2290 const SMB_STRUCT_AIOCB * const aiocb[], int n,
2291 const struct timespec *timeout)
2293 VFS_FIND(aio_suspend);
2294 return handle->fns->aio_suspend_fn(handle, fsp, aiocb, n, timeout);
2297 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2298 struct files_struct *fsp)
2300 VFS_FIND(aio_force);
2301 return handle->fns->aio_force_fn(handle, fsp);
2304 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2305 const struct smb_filename *fname,
2306 SMB_STRUCT_STAT *sbuf)
2308 VFS_FIND(is_offline);
2309 return handle->fns->is_offline_fn(handle, fname, sbuf);
2312 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2313 const struct smb_filename *fname)
2315 VFS_FIND(set_offline);
2316 return handle->fns->set_offline_fn(handle, fname);