s3:libsmb/cliconnect: make use of ntlmssp_is_anonymous()
[Samba/gebeck_regimport.git] / source3 / smbd / vfs.c
blobb330c03bfc7e2a4a29fd79aa2522e9f8684ccfe6
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_init_function_entry {
40 char *name;
41 struct vfs_init_function_entry *prev, *next;
42 const struct vfs_fn_pointers *fns;
45 /****************************************************************************
46 maintain the list of available backends
47 ****************************************************************************/
49 static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
51 struct vfs_init_function_entry *entry = backends;
53 DEBUG(10, ("vfs_find_backend_entry called for %s\n", name));
55 while(entry) {
56 if (strcmp(entry->name, name)==0) return entry;
57 entry = entry->next;
60 return NULL;
63 NTSTATUS smb_register_vfs(int version, const char *name,
64 const struct vfs_fn_pointers *fns)
66 struct vfs_init_function_entry *entry = backends;
68 if ((version != SMB_VFS_INTERFACE_VERSION)) {
69 DEBUG(0, ("Failed to register vfs module.\n"
70 "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
71 "current SMB_VFS_INTERFACE_VERSION is %d.\n"
72 "Please recompile against the current Samba Version!\n",
73 version, SMB_VFS_INTERFACE_VERSION));
74 return NT_STATUS_OBJECT_TYPE_MISMATCH;
77 if (!name || !name[0]) {
78 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
79 return NT_STATUS_INVALID_PARAMETER;
82 if (vfs_find_backend_entry(name)) {
83 DEBUG(0,("VFS module %s already loaded!\n", name));
84 return NT_STATUS_OBJECT_NAME_COLLISION;
87 entry = SMB_XMALLOC_P(struct vfs_init_function_entry);
88 entry->name = smb_xstrdup(name);
89 entry->fns = fns;
91 DLIST_ADD(backends, entry);
92 DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
93 return NT_STATUS_OK;
96 /****************************************************************************
97 initialise default vfs hooks
98 ****************************************************************************/
100 static void vfs_init_default(connection_struct *conn)
102 DEBUG(3, ("Initialising default vfs hooks\n"));
103 vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME);
106 /****************************************************************************
107 initialise custom vfs hooks
108 ****************************************************************************/
110 bool vfs_init_custom(connection_struct *conn, const char *vfs_object)
112 char *module_path = NULL;
113 char *module_name = NULL;
114 char *module_param = NULL, *p;
115 vfs_handle_struct *handle;
116 const struct vfs_init_function_entry *entry;
118 if (!conn||!vfs_object||!vfs_object[0]) {
119 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
120 "empty vfs_object!\n"));
121 return False;
124 if(!backends) {
125 static_init_vfs;
128 DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
130 module_path = smb_xstrdup(vfs_object);
132 p = strchr_m(module_path, ':');
134 if (p) {
135 *p = 0;
136 module_param = p+1;
137 trim_char(module_param, ' ', ' ');
140 trim_char(module_path, ' ', ' ');
142 module_name = smb_xstrdup(module_path);
144 if ((module_name[0] == '/') &&
145 (strcmp(module_path, DEFAULT_VFS_MODULE_NAME) != 0)) {
148 * Extract the module name from the path. Just use the base
149 * name of the last path component.
152 SAFE_FREE(module_name);
153 module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
155 p = strchr_m(module_name, '.');
157 if (p != NULL) {
158 *p = '\0';
162 /* First, try to load the module with the new module system */
163 entry = vfs_find_backend_entry(module_name);
164 if (!entry) {
165 NTSTATUS status;
167 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
168 vfs_object));
170 status = smb_load_module("vfs", module_path);
171 if (!NT_STATUS_IS_OK(status)) {
172 DEBUG(0, ("error probing vfs module '%s': %s\n",
173 module_path, nt_errstr(status)));
174 goto fail;
177 entry = vfs_find_backend_entry(module_name);
178 if (!entry) {
179 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
180 goto fail;
184 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
186 handle = talloc_zero(conn, vfs_handle_struct);
187 if (!handle) {
188 DEBUG(0,("TALLOC_ZERO() failed!\n"));
189 goto fail;
191 handle->conn = conn;
192 handle->fns = entry->fns;
193 if (module_param) {
194 handle->param = talloc_strdup(conn, module_param);
196 DLIST_ADD(conn->vfs_handles, handle);
198 SAFE_FREE(module_path);
199 SAFE_FREE(module_name);
200 return True;
202 fail:
203 SAFE_FREE(module_path);
204 SAFE_FREE(module_name);
205 return False;
208 /*****************************************************************
209 Allow VFS modules to extend files_struct with VFS-specific state.
210 This will be ok for small numbers of extensions, but might need to
211 be refactored if it becomes more widely used.
212 ******************************************************************/
214 #define EXT_DATA_AREA(e) ((uint8 *)(e) + sizeof(struct vfs_fsp_data))
216 void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle,
217 files_struct *fsp, size_t ext_size,
218 void (*destroy_fn)(void *p_data))
220 struct vfs_fsp_data *ext;
221 void * ext_data;
223 /* Prevent VFS modules adding multiple extensions. */
224 if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
225 return ext_data;
228 ext = (struct vfs_fsp_data *)TALLOC_ZERO(
229 handle->conn, sizeof(struct vfs_fsp_data) + ext_size);
230 if (ext == NULL) {
231 return NULL;
234 ext->owner = handle;
235 ext->next = fsp->vfs_extension;
236 ext->destroy = destroy_fn;
237 fsp->vfs_extension = ext;
238 return EXT_DATA_AREA(ext);
241 void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
243 struct vfs_fsp_data *curr;
244 struct vfs_fsp_data *prev;
246 for (curr = fsp->vfs_extension, prev = NULL;
247 curr;
248 prev = curr, curr = curr->next) {
249 if (curr->owner == handle) {
250 if (prev) {
251 prev->next = curr->next;
252 } else {
253 fsp->vfs_extension = curr->next;
255 if (curr->destroy) {
256 curr->destroy(EXT_DATA_AREA(curr));
258 TALLOC_FREE(curr);
259 return;
264 void *vfs_memctx_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
266 struct vfs_fsp_data *head;
268 for (head = fsp->vfs_extension; head; head = head->next) {
269 if (head->owner == handle) {
270 return head;
274 return NULL;
277 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
279 struct vfs_fsp_data *head;
281 head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
282 if (head != NULL) {
283 return EXT_DATA_AREA(head);
286 return NULL;
289 #undef EXT_DATA_AREA
291 /*****************************************************************
292 Generic VFS init.
293 ******************************************************************/
295 bool smbd_vfs_init(connection_struct *conn)
297 const char **vfs_objects;
298 unsigned int i = 0;
299 int j = 0;
301 /* Normal share - initialise with disk access functions */
302 vfs_init_default(conn);
303 vfs_objects = lp_vfs_objects(SNUM(conn));
305 /* Override VFS functions if 'vfs object' was not specified*/
306 if (!vfs_objects || !vfs_objects[0])
307 return True;
309 for (i=0; vfs_objects[i] ;) {
310 i++;
313 for (j=i-1; j >= 0; j--) {
314 if (!vfs_init_custom(conn, vfs_objects[j])) {
315 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
316 return False;
319 return True;
322 /*******************************************************************
323 Check if a file exists in the vfs.
324 ********************************************************************/
326 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
328 /* Only return OK if stat was successful and S_ISREG */
329 if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
330 S_ISREG(smb_fname->st.st_ex_mode)) {
331 return NT_STATUS_OK;
334 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
337 /****************************************************************************
338 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
339 ****************************************************************************/
341 ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
343 size_t total=0;
345 while (total < byte_count)
347 ssize_t ret = SMB_VFS_READ(fsp, buf + total,
348 byte_count - total);
350 if (ret == 0) return total;
351 if (ret == -1) {
352 if (errno == EINTR)
353 continue;
354 else
355 return -1;
357 total += ret;
359 return (ssize_t)total;
362 ssize_t vfs_pread_data(files_struct *fsp, char *buf,
363 size_t byte_count, off_t offset)
365 size_t total=0;
367 while (total < byte_count)
369 ssize_t ret = SMB_VFS_PREAD(fsp, buf + total,
370 byte_count - total, offset + total);
372 if (ret == 0) return total;
373 if (ret == -1) {
374 if (errno == EINTR)
375 continue;
376 else
377 return -1;
379 total += ret;
381 return (ssize_t)total;
384 /****************************************************************************
385 Write data to a fd on the vfs.
386 ****************************************************************************/
388 ssize_t vfs_write_data(struct smb_request *req,
389 files_struct *fsp,
390 const char *buffer,
391 size_t N)
393 size_t total=0;
394 ssize_t ret;
396 if (req && req->unread_bytes) {
397 SMB_ASSERT(req->unread_bytes == N);
398 /* VFS_RECVFILE must drain the socket
399 * before returning. */
400 req->unread_bytes = 0;
401 return SMB_VFS_RECVFILE(req->sconn->sock,
402 fsp,
403 (off_t)-1,
407 while (total < N) {
408 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
410 if (ret == -1)
411 return -1;
412 if (ret == 0)
413 return total;
415 total += ret;
417 return (ssize_t)total;
420 ssize_t vfs_pwrite_data(struct smb_request *req,
421 files_struct *fsp,
422 const char *buffer,
423 size_t N,
424 off_t offset)
426 size_t total=0;
427 ssize_t ret;
429 if (req && req->unread_bytes) {
430 SMB_ASSERT(req->unread_bytes == N);
431 /* VFS_RECVFILE must drain the socket
432 * before returning. */
433 req->unread_bytes = 0;
434 return SMB_VFS_RECVFILE(req->sconn->sock,
435 fsp,
436 offset,
440 while (total < N) {
441 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
442 offset + total);
444 if (ret == -1)
445 return -1;
446 if (ret == 0)
447 return total;
449 total += ret;
451 return (ssize_t)total;
453 /****************************************************************************
454 An allocate file space call using the vfs interface.
455 Allocates space for a file from a filedescriptor.
456 Returns 0 on success, -1 on failure.
457 ****************************************************************************/
459 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
461 int ret;
462 connection_struct *conn = fsp->conn;
463 uint64_t space_avail;
464 uint64_t bsize,dfree,dsize;
465 NTSTATUS status;
468 * Actually try and commit the space on disk....
471 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
472 fsp_str_dbg(fsp), (double)len));
474 if (((off_t)len) < 0) {
475 DEBUG(0,("vfs_allocate_file_space: %s negative len "
476 "requested.\n", fsp_str_dbg(fsp)));
477 errno = EINVAL;
478 return -1;
481 status = vfs_stat_fsp(fsp);
482 if (!NT_STATUS_IS_OK(status)) {
483 return -1;
486 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
487 return 0;
489 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
490 /* Shrink - use ftruncate. */
492 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
493 "size %.0f\n", fsp_str_dbg(fsp),
494 (double)fsp->fsp_name->st.st_ex_size));
496 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
498 flush_write_cache(fsp, SIZECHANGE_FLUSH);
499 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
500 set_filelen_write_cache(fsp, len);
503 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
505 return ret;
508 if (!lp_strict_allocate(SNUM(fsp->conn)))
509 return 0;
511 /* Grow - we need to test if we have enough space. */
513 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
515 /* See if we have a syscall that will allocate beyond end-of-file
516 without changing EOF. */
517 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
519 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
521 if (ret == 0) {
522 /* We changed the allocation size on disk, but not
523 EOF - exactly as required. We're done ! */
524 return 0;
527 len -= fsp->fsp_name->st.st_ex_size;
528 len /= 1024; /* Len is now number of 1k blocks needed. */
529 space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
530 &bsize, &dfree, &dsize);
531 if (space_avail == (uint64_t)-1) {
532 return -1;
535 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
536 "needed blocks = %.0f, space avail = %.0f\n",
537 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
538 (double)space_avail));
540 if (len > space_avail) {
541 errno = ENOSPC;
542 return -1;
545 return 0;
548 /****************************************************************************
549 A vfs set_filelen call.
550 set the length of a file from a filedescriptor.
551 Returns 0 on success, -1 on failure.
552 ****************************************************************************/
554 int vfs_set_filelen(files_struct *fsp, off_t len)
556 int ret;
558 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
560 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
561 fsp_str_dbg(fsp), (double)len));
562 flush_write_cache(fsp, SIZECHANGE_FLUSH);
563 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
564 set_filelen_write_cache(fsp, len);
565 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
566 FILE_NOTIFY_CHANGE_SIZE
567 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
568 fsp->fsp_name->base_name);
571 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
573 return ret;
576 /****************************************************************************
577 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
578 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
579 as this is also called from the default SMB_VFS_FTRUNCATE code.
580 Always extends the file size.
581 Returns 0 on success, errno on failure.
582 ****************************************************************************/
584 #define SPARSE_BUF_WRITE_SIZE (32*1024)
586 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
588 ssize_t pwrite_ret;
589 size_t total = 0;
591 if (!sparse_buf) {
592 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
593 if (!sparse_buf) {
594 errno = ENOMEM;
595 return ENOMEM;
599 while (total < len) {
600 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
602 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
603 if (pwrite_ret == -1) {
604 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
605 "%s failed with error %s\n",
606 fsp_str_dbg(fsp), strerror(errno)));
607 return errno;
609 total += pwrite_ret;
612 return 0;
615 /****************************************************************************
616 A vfs fill sparse call.
617 Writes zeros from the end of file to len, if len is greater than EOF.
618 Used only by strict_sync.
619 Returns 0 on success, -1 on failure.
620 ****************************************************************************/
622 int vfs_fill_sparse(files_struct *fsp, off_t len)
624 int ret;
625 NTSTATUS status;
626 off_t offset;
627 size_t num_to_write;
629 status = vfs_stat_fsp(fsp);
630 if (!NT_STATUS_IS_OK(status)) {
631 return -1;
634 if (len <= fsp->fsp_name->st.st_ex_size) {
635 return 0;
638 #ifdef S_ISFIFO
639 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
640 return 0;
642 #endif
644 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
645 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
646 (double)fsp->fsp_name->st.st_ex_size, (double)len,
647 (double)(len - fsp->fsp_name->st.st_ex_size)));
649 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
651 flush_write_cache(fsp, SIZECHANGE_FLUSH);
653 offset = fsp->fsp_name->st.st_ex_size;
654 num_to_write = len - fsp->fsp_name->st.st_ex_size;
656 /* Only do this on non-stream file handles. */
657 if (fsp->base_fsp == NULL) {
658 /* for allocation try fallocate first. This can fail on some
659 * platforms e.g. when the filesystem doesn't support it and no
660 * emulation is being done by the libc (like on AIX with JFS1). In that
661 * case we do our own emulation. fallocate implementations can
662 * return ENOTSUP or EINVAL in cases like that. */
663 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
664 offset, num_to_write);
665 if (ret == ENOSPC) {
666 errno = ENOSPC;
667 ret = -1;
668 goto out;
670 if (ret == 0) {
671 goto out;
673 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
674 "error %d. Falling back to slow manual allocation\n", ret));
677 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
678 if (ret != 0) {
679 errno = ret;
680 ret = -1;
683 out:
685 if (ret == 0) {
686 set_filelen_write_cache(fsp, len);
689 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
690 return ret;
693 /****************************************************************************
694 Transfer some data (n bytes) between two file_struct's.
695 ****************************************************************************/
697 static ssize_t vfs_read_fn(void *file, void *buf, size_t len)
699 struct files_struct *fsp = (struct files_struct *)file;
701 return SMB_VFS_READ(fsp, buf, len);
704 static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
706 struct files_struct *fsp = (struct files_struct *)file;
708 return SMB_VFS_WRITE(fsp, buf, len);
711 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
713 return transfer_file_internal((void *)in, (void *)out, n,
714 vfs_read_fn, vfs_write_fn);
717 /*******************************************************************
718 A vfs_readdir wrapper which just returns the file name.
719 ********************************************************************/
721 const char *vfs_readdirname(connection_struct *conn, void *p,
722 SMB_STRUCT_STAT *sbuf, char **talloced)
724 struct dirent *ptr= NULL;
725 const char *dname;
726 char *translated;
727 NTSTATUS status;
729 if (!p)
730 return(NULL);
732 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
733 if (!ptr)
734 return(NULL);
736 dname = ptr->d_name;
739 #ifdef NEXT2
740 if (telldir(p) < 0)
741 return(NULL);
742 #endif
744 #ifdef HAVE_BROKEN_READDIR_NAME
745 /* using /usr/ucb/cc is BAD */
746 dname = dname - 2;
747 #endif
749 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
750 talloc_tos(), &translated);
751 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
752 *talloced = NULL;
753 return dname;
755 *talloced = translated;
756 if (!NT_STATUS_IS_OK(status)) {
757 return NULL;
759 return translated;
762 /*******************************************************************
763 A wrapper for vfs_chdir().
764 ********************************************************************/
766 int vfs_ChDir(connection_struct *conn, const char *path)
768 int res;
770 if (!LastDir) {
771 LastDir = SMB_STRDUP("");
774 if (strcsequal(path,"."))
775 return(0);
777 if (*path == '/' && strcsequal(LastDir,path))
778 return(0);
780 DEBUG(4,("vfs_ChDir to %s\n",path));
782 res = SMB_VFS_CHDIR(conn,path);
783 if (!res) {
784 SAFE_FREE(LastDir);
785 LastDir = SMB_STRDUP(path);
787 return(res);
790 /*******************************************************************
791 Return the absolute current directory path - given a UNIX pathname.
792 Note that this path is returned in DOS format, not UNIX
793 format. Note this can be called with conn == NULL.
794 ********************************************************************/
796 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
798 char *current_dir = NULL;
799 char *result = NULL;
800 DATA_BLOB cache_value;
801 struct file_id key;
802 struct smb_filename *smb_fname_dot = NULL;
803 struct smb_filename *smb_fname_full = NULL;
804 NTSTATUS status;
806 if (!lp_getwd_cache()) {
807 goto nocache;
810 status = create_synthetic_smb_fname(ctx, ".", NULL, NULL,
811 &smb_fname_dot);
812 if (!NT_STATUS_IS_OK(status)) {
813 errno = map_errno_from_nt_status(status);
814 goto out;
817 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
819 * Known to fail for root: the directory may be NFS-mounted
820 * and exported with root_squash (so has no root access).
822 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
823 "(NFS problem ?)\n", strerror(errno) ));
824 goto nocache;
827 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
829 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
830 data_blob_const(&key, sizeof(key)),
831 &cache_value)) {
832 goto nocache;
835 SMB_ASSERT((cache_value.length > 0)
836 && (cache_value.data[cache_value.length-1] == '\0'));
838 status = create_synthetic_smb_fname(ctx, (char *)cache_value.data,
839 NULL, NULL, &smb_fname_full);
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_full) == 0) &&
846 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
847 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
848 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
850 * Ok, we're done
852 result = talloc_strdup(ctx, smb_fname_full->base_name);
853 if (result == NULL) {
854 errno = ENOMEM;
856 goto out;
859 nocache:
862 * We don't have the information to hand so rely on traditional
863 * methods. The very slow getcwd, which spawns a process on some
864 * systems, or the not quite so bad getwd.
867 current_dir = SMB_VFS_GETWD(conn);
868 if (current_dir == NULL) {
869 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
870 strerror(errno)));
871 goto out;
874 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
875 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
877 memcache_add(smbd_memcache(), GETWD_CACHE,
878 data_blob_const(&key, sizeof(key)),
879 data_blob_const(current_dir,
880 strlen(current_dir)+1));
883 result = talloc_strdup(ctx, current_dir);
884 if (result == NULL) {
885 errno = ENOMEM;
888 out:
889 TALLOC_FREE(smb_fname_dot);
890 TALLOC_FREE(smb_fname_full);
891 SAFE_FREE(current_dir);
892 return result;
895 /*******************************************************************
896 Reduce a file name, removing .. elements and checking that
897 it is below dir in the heirachy. This uses realpath.
898 This function must run as root, and will return names
899 and valid stat structs that can be checked on open.
900 ********************************************************************/
902 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
903 const char *fname,
904 struct smb_request *smbreq)
906 NTSTATUS status;
907 TALLOC_CTX *ctx = talloc_tos();
908 const char *conn_rootdir;
909 size_t rootdir_len;
910 char *dir_name = NULL;
911 const char *last_component = NULL;
912 char *resolved_name = NULL;
913 char *saved_dir = NULL;
914 struct smb_filename *smb_fname_cwd = NULL;
915 struct privilege_paths *priv_paths = NULL;
916 int ret;
918 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
919 fname,
920 conn->connectpath));
923 priv_paths = talloc_zero(smbreq, struct privilege_paths);
924 if (!priv_paths) {
925 status = NT_STATUS_NO_MEMORY;
926 goto err;
929 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
930 status = NT_STATUS_NO_MEMORY;
931 goto err;
934 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
935 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
937 if (priv_paths->parent_name.base_name == NULL ||
938 priv_paths->file_name.base_name == NULL) {
939 status = NT_STATUS_NO_MEMORY;
940 goto err;
943 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
944 status = map_nt_error_from_unix(errno);
945 goto err;
947 /* Remember where we were. */
948 saved_dir = vfs_GetWd(ctx, conn);
949 if (!saved_dir) {
950 status = map_nt_error_from_unix(errno);
951 goto err;
954 /* Go to the parent directory to lock in memory. */
955 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
956 status = map_nt_error_from_unix(errno);
957 goto err;
960 /* Get the absolute path of the parent directory. */
961 resolved_name = SMB_VFS_REALPATH(conn,".");
962 if (!resolved_name) {
963 status = map_nt_error_from_unix(errno);
964 goto err;
967 if (*resolved_name != '/') {
968 DEBUG(0,("check_reduced_name_with_privilege: realpath "
969 "doesn't return absolute paths !\n"));
970 status = NT_STATUS_OBJECT_NAME_INVALID;
971 goto err;
974 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
975 priv_paths->parent_name.base_name,
976 resolved_name));
978 /* Now check the stat value is the same. */
979 status = create_synthetic_smb_fname(talloc_tos(), ".",
980 NULL, NULL,
981 &smb_fname_cwd);
982 if (!NT_STATUS_IS_OK(status)) {
983 goto err;
986 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
987 status = map_nt_error_from_unix(errno);
988 goto err;
991 /* Ensure we're pointing at the same place. */
992 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
993 DEBUG(0,("check_reduced_name_with_privilege: "
994 "device/inode/uid/gid on directory %s changed. "
995 "Denying access !\n",
996 priv_paths->parent_name.base_name));
997 status = NT_STATUS_ACCESS_DENIED;
998 goto err;
1001 /* Ensure we're below the connect path. */
1003 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1004 if (conn_rootdir == NULL) {
1005 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1006 "conn_rootdir\n"));
1007 status = NT_STATUS_ACCESS_DENIED;
1008 goto err;
1011 rootdir_len = strlen(conn_rootdir);
1012 if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1013 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1014 "attempt: %s is a symlink outside the "
1015 "share path\n",
1016 dir_name));
1017 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1018 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1019 status = NT_STATUS_ACCESS_DENIED;
1020 goto err;
1023 /* Now ensure that the last component either doesn't
1024 exist, or is *NOT* a symlink. */
1026 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1027 if (ret == -1) {
1028 /* Errno must be ENOENT for this be ok. */
1029 if (errno != ENOENT) {
1030 status = map_nt_error_from_unix(errno);
1031 DEBUG(2, ("check_reduced_name_with_privilege: "
1032 "LSTAT on %s failed with %s\n",
1033 priv_paths->file_name.base_name,
1034 nt_errstr(status)));
1035 goto err;
1039 if (VALID_STAT(priv_paths->file_name.st) &&
1040 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1041 DEBUG(2, ("check_reduced_name_with_privilege: "
1042 "Last component %s is a symlink. Denying"
1043 "access.\n",
1044 priv_paths->file_name.base_name));
1045 status = NT_STATUS_ACCESS_DENIED;
1046 goto err;
1049 smbreq->priv_paths = priv_paths;
1050 status = NT_STATUS_OK;
1052 err:
1054 if (saved_dir) {
1055 vfs_ChDir(conn, saved_dir);
1057 SAFE_FREE(resolved_name);
1058 if (!NT_STATUS_IS_OK(status)) {
1059 TALLOC_FREE(priv_paths);
1061 return status;
1064 /*******************************************************************
1065 Reduce a file name, removing .. elements and checking that
1066 it is below dir in the heirachy. This uses realpath.
1067 ********************************************************************/
1069 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1071 char *resolved_name = NULL;
1072 bool allow_symlinks = true;
1073 bool allow_widelinks = false;
1075 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1077 resolved_name = SMB_VFS_REALPATH(conn,fname);
1079 if (!resolved_name) {
1080 switch (errno) {
1081 case ENOTDIR:
1082 DEBUG(3,("check_reduced_name: Component not a "
1083 "directory in getting realpath for "
1084 "%s\n", fname));
1085 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1086 case ENOENT:
1088 TALLOC_CTX *ctx = talloc_tos();
1089 char *dir_name = NULL;
1090 const char *last_component = NULL;
1091 char *new_name = NULL;
1093 /* Last component didn't exist.
1094 Remove it and try and canonicalise
1095 the directory name. */
1096 if (!parent_dirname(ctx, fname,
1097 &dir_name,
1098 &last_component)) {
1099 return NT_STATUS_NO_MEMORY;
1102 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1103 if (!resolved_name) {
1104 NTSTATUS status = map_nt_error_from_unix(errno);
1106 if (errno == ENOENT || errno == ENOTDIR) {
1107 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1110 DEBUG(3,("check_reduce_name: "
1111 "couldn't get realpath for "
1112 "%s (%s)\n",
1113 fname,
1114 nt_errstr(status)));
1115 return status;
1117 new_name = talloc_asprintf(ctx,
1118 "%s/%s",
1119 resolved_name,
1120 last_component);
1121 if (!new_name) {
1122 return NT_STATUS_NO_MEMORY;
1124 SAFE_FREE(resolved_name);
1125 resolved_name = SMB_STRDUP(new_name);
1126 if (!resolved_name) {
1127 return NT_STATUS_NO_MEMORY;
1129 break;
1131 default:
1132 DEBUG(3,("check_reduced_name: couldn't get "
1133 "realpath for %s\n", fname));
1134 return map_nt_error_from_unix(errno);
1138 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1139 resolved_name));
1141 if (*resolved_name != '/') {
1142 DEBUG(0,("check_reduced_name: realpath doesn't return "
1143 "absolute paths !\n"));
1144 SAFE_FREE(resolved_name);
1145 return NT_STATUS_OBJECT_NAME_INVALID;
1148 allow_widelinks = lp_widelinks(SNUM(conn));
1149 allow_symlinks = lp_symlinks(SNUM(conn));
1151 /* Common widelinks and symlinks checks. */
1152 if (!allow_widelinks || !allow_symlinks) {
1153 const char *conn_rootdir;
1154 size_t rootdir_len;
1156 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1157 if (conn_rootdir == NULL) {
1158 DEBUG(2, ("check_reduced_name: Could not get "
1159 "conn_rootdir\n"));
1160 SAFE_FREE(resolved_name);
1161 return NT_STATUS_ACCESS_DENIED;
1164 rootdir_len = strlen(conn_rootdir);
1165 if (strncmp(conn_rootdir, resolved_name,
1166 rootdir_len) != 0) {
1167 DEBUG(2, ("check_reduced_name: Bad access "
1168 "attempt: %s is a symlink outside the "
1169 "share path\n", fname));
1170 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1171 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1172 SAFE_FREE(resolved_name);
1173 return NT_STATUS_ACCESS_DENIED;
1176 /* Extra checks if all symlinks are disallowed. */
1177 if (!allow_symlinks) {
1178 /* fname can't have changed in resolved_path. */
1179 const char *p = &resolved_name[rootdir_len];
1181 /* *p can be '\0' if fname was "." */
1182 if (*p == '\0' && ISDOT(fname)) {
1183 goto out;
1186 if (*p != '/') {
1187 DEBUG(2, ("check_reduced_name: logic error (%c) "
1188 "in resolved_name: %s\n",
1190 fname));
1191 SAFE_FREE(resolved_name);
1192 return NT_STATUS_ACCESS_DENIED;
1195 p++;
1196 if (strcmp(fname, p)!=0) {
1197 DEBUG(2, ("check_reduced_name: Bad access "
1198 "attempt: %s is a symlink\n",
1199 fname));
1200 SAFE_FREE(resolved_name);
1201 return NT_STATUS_ACCESS_DENIED;
1206 out:
1208 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1209 resolved_name));
1210 SAFE_FREE(resolved_name);
1211 return NT_STATUS_OK;
1215 * XXX: This is temporary and there should be no callers of this once
1216 * smb_filename is plumbed through all path based operations.
1218 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1219 SMB_STRUCT_STAT *psbuf)
1221 struct smb_filename *smb_fname = NULL;
1222 NTSTATUS status;
1223 int ret;
1225 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1226 &smb_fname);
1227 if (!NT_STATUS_IS_OK(status)) {
1228 errno = map_errno_from_nt_status(status);
1229 return -1;
1232 if (lp_posix_pathnames()) {
1233 ret = SMB_VFS_LSTAT(conn, smb_fname);
1234 } else {
1235 ret = SMB_VFS_STAT(conn, smb_fname);
1238 if (ret != -1) {
1239 *psbuf = smb_fname->st;
1242 TALLOC_FREE(smb_fname);
1243 return ret;
1247 * XXX: This is temporary and there should be no callers of this once
1248 * smb_filename is plumbed through all path based operations.
1250 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1251 SMB_STRUCT_STAT *psbuf)
1253 struct smb_filename *smb_fname = NULL;
1254 NTSTATUS status;
1255 int ret;
1257 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1258 &smb_fname);
1259 if (!NT_STATUS_IS_OK(status)) {
1260 errno = map_errno_from_nt_status(status);
1261 return -1;
1264 ret = SMB_VFS_LSTAT(conn, smb_fname);
1265 if (ret != -1) {
1266 *psbuf = smb_fname->st;
1269 TALLOC_FREE(smb_fname);
1270 return ret;
1274 * Ensure LSTAT is called for POSIX paths.
1277 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1279 int ret;
1281 if(fsp->fh->fd == -1) {
1282 if (fsp->posix_open) {
1283 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1284 } else {
1285 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1287 if (ret == -1) {
1288 return map_nt_error_from_unix(errno);
1290 } else {
1291 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1292 return map_nt_error_from_unix(errno);
1295 return NT_STATUS_OK;
1299 * Initialize num_streams and streams, then call VFS op streaminfo
1301 NTSTATUS vfs_streaminfo(connection_struct *conn,
1302 struct files_struct *fsp,
1303 const char *fname,
1304 TALLOC_CTX *mem_ctx,
1305 unsigned int *num_streams,
1306 struct stream_struct **streams)
1308 *num_streams = 0;
1309 *streams = NULL;
1310 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1314 generate a file_id from a stat structure
1316 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1318 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1321 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1322 const char *service, const char *user)
1324 VFS_FIND(connect);
1325 return handle->fns->connect_fn(handle, service, user);
1328 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1330 VFS_FIND(disconnect);
1331 handle->fns->disconnect_fn(handle);
1334 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1335 const char *path, bool small_query,
1336 uint64_t *bsize, uint64_t *dfree,
1337 uint64_t *dsize)
1339 VFS_FIND(disk_free);
1340 return handle->fns->disk_free_fn(handle, path, small_query, bsize,
1341 dfree, dsize);
1344 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1345 enum SMB_QUOTA_TYPE qtype, unid_t id,
1346 SMB_DISK_QUOTA *qt)
1348 VFS_FIND(get_quota);
1349 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1352 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1353 enum SMB_QUOTA_TYPE qtype, unid_t id,
1354 SMB_DISK_QUOTA *qt)
1356 VFS_FIND(set_quota);
1357 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1360 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1361 struct files_struct *fsp,
1362 struct shadow_copy_data *shadow_copy_data,
1363 bool labels)
1365 VFS_FIND(get_shadow_copy_data);
1366 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1367 shadow_copy_data,
1368 labels);
1370 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1371 struct vfs_statvfs_struct *statbuf)
1373 VFS_FIND(statvfs);
1374 return handle->fns->statvfs_fn(handle, path, statbuf);
1377 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1378 enum timestamp_set_resolution *p_ts_res)
1380 VFS_FIND(fs_capabilities);
1381 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1384 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1385 struct dfs_GetDFSReferral *r)
1387 VFS_FIND(get_dfs_referrals);
1388 return handle->fns->get_dfs_referrals_fn(handle, r);
1391 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1392 const char *fname, const char *mask,
1393 uint32 attributes)
1395 VFS_FIND(opendir);
1396 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1399 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1400 struct files_struct *fsp,
1401 const char *mask,
1402 uint32 attributes)
1404 VFS_FIND(fdopendir);
1405 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1408 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1409 DIR *dirp,
1410 SMB_STRUCT_STAT *sbuf)
1412 VFS_FIND(readdir);
1413 return handle->fns->readdir_fn(handle, dirp, sbuf);
1416 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1417 DIR *dirp, long offset)
1419 VFS_FIND(seekdir);
1420 handle->fns->seekdir_fn(handle, dirp, offset);
1423 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1424 DIR *dirp)
1426 VFS_FIND(telldir);
1427 return handle->fns->telldir_fn(handle, dirp);
1430 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1431 DIR *dirp)
1433 VFS_FIND(rewind_dir);
1434 handle->fns->rewind_dir_fn(handle, dirp);
1437 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1438 mode_t mode)
1440 VFS_FIND(mkdir);
1441 return handle->fns->mkdir_fn(handle, path, mode);
1444 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1446 VFS_FIND(rmdir);
1447 return handle->fns->rmdir_fn(handle, path);
1450 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1451 DIR *dir)
1453 VFS_FIND(closedir);
1454 return handle->fns->closedir_fn(handle, dir);
1457 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1458 DIR *dirp)
1460 VFS_FIND(init_search_op);
1461 handle->fns->init_search_op_fn(handle, dirp);
1464 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1465 struct smb_filename *smb_fname, struct files_struct *fsp,
1466 int flags, mode_t mode)
1468 VFS_FIND(open);
1469 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1472 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1473 struct smb_request *req,
1474 uint16_t root_dir_fid,
1475 struct smb_filename *smb_fname,
1476 uint32_t access_mask,
1477 uint32_t share_access,
1478 uint32_t create_disposition,
1479 uint32_t create_options,
1480 uint32_t file_attributes,
1481 uint32_t oplock_request,
1482 uint64_t allocation_size,
1483 uint32_t private_flags,
1484 struct security_descriptor *sd,
1485 struct ea_list *ea_list,
1486 files_struct **result,
1487 int *pinfo)
1489 VFS_FIND(create_file);
1490 return handle->fns->create_file_fn(
1491 handle, req, root_dir_fid, smb_fname, access_mask,
1492 share_access, create_disposition, create_options,
1493 file_attributes, oplock_request, allocation_size,
1494 private_flags, sd, ea_list,
1495 result, pinfo);
1498 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1499 struct files_struct *fsp)
1501 VFS_FIND(close);
1502 return handle->fns->close_fn(handle, fsp);
1505 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1506 struct files_struct *fsp, void *data, size_t n)
1508 VFS_FIND(read);
1509 return handle->fns->read_fn(handle, fsp, data, n);
1512 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1513 struct files_struct *fsp, void *data, size_t n,
1514 off_t offset)
1516 VFS_FIND(pread);
1517 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1520 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1521 struct files_struct *fsp, const void *data,
1522 size_t n)
1524 VFS_FIND(write);
1525 return handle->fns->write_fn(handle, fsp, data, n);
1528 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1529 struct files_struct *fsp, const void *data,
1530 size_t n, off_t offset)
1532 VFS_FIND(pwrite);
1533 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1536 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1537 struct files_struct *fsp, off_t offset,
1538 int whence)
1540 VFS_FIND(lseek);
1541 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1544 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1545 files_struct *fromfsp, const DATA_BLOB *header,
1546 off_t offset, size_t count)
1548 VFS_FIND(sendfile);
1549 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1550 count);
1553 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1554 files_struct *tofsp, off_t offset,
1555 size_t count)
1557 VFS_FIND(recvfile);
1558 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1561 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1562 const struct smb_filename *smb_fname_src,
1563 const struct smb_filename *smb_fname_dst)
1565 VFS_FIND(rename);
1566 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1569 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1570 struct files_struct *fsp)
1572 VFS_FIND(fsync);
1573 return handle->fns->fsync_fn(handle, fsp);
1576 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1577 struct smb_filename *smb_fname)
1579 VFS_FIND(stat);
1580 return handle->fns->stat_fn(handle, smb_fname);
1583 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1584 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1586 VFS_FIND(fstat);
1587 return handle->fns->fstat_fn(handle, fsp, sbuf);
1590 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1591 struct smb_filename *smb_filename)
1593 VFS_FIND(lstat);
1594 return handle->fns->lstat_fn(handle, smb_filename);
1597 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1598 struct files_struct *fsp,
1599 const SMB_STRUCT_STAT *sbuf)
1601 VFS_FIND(get_alloc_size);
1602 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1605 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1606 const struct smb_filename *smb_fname)
1608 VFS_FIND(unlink);
1609 return handle->fns->unlink_fn(handle, smb_fname);
1612 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1613 mode_t mode)
1615 VFS_FIND(chmod);
1616 return handle->fns->chmod_fn(handle, path, mode);
1619 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1620 struct files_struct *fsp, mode_t mode)
1622 VFS_FIND(fchmod);
1623 return handle->fns->fchmod_fn(handle, fsp, mode);
1626 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1627 uid_t uid, gid_t gid)
1629 VFS_FIND(chown);
1630 return handle->fns->chown_fn(handle, path, uid, gid);
1633 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1634 struct files_struct *fsp, uid_t uid, gid_t gid)
1636 VFS_FIND(fchown);
1637 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1640 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1641 uid_t uid, gid_t gid)
1643 VFS_FIND(lchown);
1644 return handle->fns->lchown_fn(handle, path, uid, gid);
1647 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1649 int ret;
1650 bool as_root = false;
1651 const char *path;
1652 char *saved_dir = NULL;
1653 char *parent_dir = NULL;
1654 NTSTATUS status;
1656 if (fsp->fh->fd != -1) {
1657 /* Try fchown. */
1658 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1659 if (ret == 0) {
1660 return NT_STATUS_OK;
1662 if (ret == -1 && errno != ENOSYS) {
1663 return map_nt_error_from_unix(errno);
1667 as_root = (geteuid() == 0);
1669 if (as_root) {
1671 * We are being asked to chown as root. Make
1672 * sure we chdir() into the path to pin it,
1673 * and always act using lchown to ensure we
1674 * don't deref any symbolic links.
1676 const char *final_component = NULL;
1677 struct smb_filename local_fname;
1679 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1680 if (!saved_dir) {
1681 status = map_nt_error_from_unix(errno);
1682 DEBUG(0,("vfs_chown_fsp: failed to get "
1683 "current working directory. Error was %s\n",
1684 strerror(errno)));
1685 return status;
1688 if (!parent_dirname(talloc_tos(),
1689 fsp->fsp_name->base_name,
1690 &parent_dir,
1691 &final_component)) {
1692 return NT_STATUS_NO_MEMORY;
1695 /* cd into the parent dir to pin it. */
1696 ret = vfs_ChDir(fsp->conn, parent_dir);
1697 if (ret == -1) {
1698 return map_nt_error_from_unix(errno);
1701 ZERO_STRUCT(local_fname);
1702 local_fname.base_name = discard_const_p(char, final_component);
1704 /* Must use lstat here. */
1705 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1706 if (ret == -1) {
1707 status = map_nt_error_from_unix(errno);
1708 goto out;
1711 /* Ensure it matches the fsp stat. */
1712 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1713 status = NT_STATUS_ACCESS_DENIED;
1714 goto out;
1716 path = final_component;
1717 } else {
1718 path = fsp->fsp_name->base_name;
1721 if (fsp->posix_open || as_root) {
1722 ret = SMB_VFS_LCHOWN(fsp->conn,
1723 path,
1724 uid, gid);
1725 } else {
1726 ret = SMB_VFS_CHOWN(fsp->conn,
1727 path,
1728 uid, gid);
1731 if (ret == 0) {
1732 status = NT_STATUS_OK;
1733 } else {
1734 status = map_nt_error_from_unix(errno);
1737 out:
1739 if (as_root) {
1740 vfs_ChDir(fsp->conn,saved_dir);
1741 TALLOC_FREE(saved_dir);
1742 TALLOC_FREE(parent_dir);
1744 return status;
1747 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1749 VFS_FIND(chdir);
1750 return handle->fns->chdir_fn(handle, path);
1753 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
1755 VFS_FIND(getwd);
1756 return handle->fns->getwd_fn(handle);
1759 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
1760 const struct smb_filename *smb_fname,
1761 struct smb_file_time *ft)
1763 VFS_FIND(ntimes);
1764 return handle->fns->ntimes_fn(handle, smb_fname, ft);
1767 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
1768 struct files_struct *fsp, off_t offset)
1770 VFS_FIND(ftruncate);
1771 return handle->fns->ftruncate_fn(handle, fsp, offset);
1774 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
1775 struct files_struct *fsp,
1776 enum vfs_fallocate_mode mode,
1777 off_t offset,
1778 off_t len)
1780 VFS_FIND(fallocate);
1781 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
1784 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
1785 struct files_struct *fsp, uint32 share_mode,
1786 uint32_t access_mask)
1788 VFS_FIND(kernel_flock);
1789 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
1790 access_mask);
1793 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
1794 struct files_struct *fsp, int leasetype)
1796 VFS_FIND(linux_setlease);
1797 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
1800 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
1801 const char *newpath)
1803 VFS_FIND(symlink);
1804 return handle->fns->symlink_fn(handle, oldpath, newpath);
1807 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
1808 const char *path, char *buf, size_t bufsiz)
1810 VFS_FIND(readlink);
1811 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
1814 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
1815 const char *newpath)
1817 VFS_FIND(link);
1818 return handle->fns->link_fn(handle, oldpath, newpath);
1821 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
1822 mode_t mode, SMB_DEV_T dev)
1824 VFS_FIND(mknod);
1825 return handle->fns->mknod_fn(handle, path, mode, dev);
1828 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
1830 VFS_FIND(realpath);
1831 return handle->fns->realpath_fn(handle, path);
1834 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
1835 struct sys_notify_context *ctx,
1836 const char *path,
1837 uint32_t *filter,
1838 uint32_t *subdir_filter,
1839 void (*callback)(struct sys_notify_context *ctx,
1840 void *private_data,
1841 struct notify_event *ev),
1842 void *private_data, void *handle_p)
1844 VFS_FIND(notify_watch);
1845 return handle->fns->notify_watch_fn(handle, ctx, path,
1846 filter, subdir_filter, callback,
1847 private_data, handle_p);
1850 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
1851 unsigned int flags)
1853 VFS_FIND(chflags);
1854 return handle->fns->chflags_fn(handle, path, flags);
1857 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
1858 const SMB_STRUCT_STAT *sbuf)
1860 VFS_FIND(file_id_create);
1861 return handle->fns->file_id_create_fn(handle, sbuf);
1864 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
1865 struct files_struct *fsp,
1866 const char *fname,
1867 TALLOC_CTX *mem_ctx,
1868 unsigned int *num_streams,
1869 struct stream_struct **streams)
1871 VFS_FIND(streaminfo);
1872 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
1873 num_streams, streams);
1876 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
1877 const char *path, const char *name,
1878 TALLOC_CTX *mem_ctx, char **found_name)
1880 VFS_FIND(get_real_filename);
1881 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
1882 found_name);
1885 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
1886 const char *filename)
1888 VFS_FIND(connectpath);
1889 return handle->fns->connectpath_fn(handle, filename);
1892 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
1893 struct files_struct *fsp,
1894 struct lock_struct *plock)
1896 VFS_FIND(strict_lock);
1897 return handle->fns->strict_lock_fn(handle, fsp, plock);
1900 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
1901 struct files_struct *fsp,
1902 struct lock_struct *plock)
1904 VFS_FIND(strict_unlock);
1905 handle->fns->strict_unlock_fn(handle, fsp, plock);
1908 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
1909 const char *name,
1910 enum vfs_translate_direction direction,
1911 TALLOC_CTX *mem_ctx,
1912 char **mapped_name)
1914 VFS_FIND(translate_name);
1915 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
1916 mapped_name);
1919 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
1920 struct files_struct *fsp,
1921 TALLOC_CTX *ctx,
1922 uint32_t function,
1923 uint16_t req_flags,
1924 const uint8_t *in_data,
1925 uint32_t in_len,
1926 uint8_t **out_data,
1927 uint32_t max_out_len,
1928 uint32_t *out_len)
1930 VFS_FIND(fsctl);
1931 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
1932 in_data, in_len, out_data, max_out_len,
1933 out_len);
1936 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
1937 struct files_struct *fsp,
1938 uint32 security_info,
1939 struct security_descriptor **ppdesc)
1941 VFS_FIND(fget_nt_acl);
1942 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
1943 ppdesc);
1946 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
1947 const char *name,
1948 uint32 security_info,
1949 struct security_descriptor **ppdesc)
1951 VFS_FIND(get_nt_acl);
1952 return handle->fns->get_nt_acl_fn(handle, name, security_info, ppdesc);
1955 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
1956 struct files_struct *fsp,
1957 uint32 security_info_sent,
1958 const struct security_descriptor *psd)
1960 VFS_FIND(fset_nt_acl);
1961 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
1962 psd);
1965 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
1966 mode_t mode)
1968 VFS_FIND(chmod_acl);
1969 return handle->fns->chmod_acl_fn(handle, name, mode);
1972 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
1973 struct files_struct *fsp, mode_t mode)
1975 VFS_FIND(fchmod_acl);
1976 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
1979 int smb_vfs_call_sys_acl_get_entry(struct vfs_handle_struct *handle,
1980 SMB_ACL_T theacl, int entry_id,
1981 SMB_ACL_ENTRY_T *entry_p)
1983 VFS_FIND(sys_acl_get_entry);
1984 return handle->fns->sys_acl_get_entry_fn(handle, theacl, entry_id,
1985 entry_p);
1988 int smb_vfs_call_sys_acl_get_tag_type(struct vfs_handle_struct *handle,
1989 SMB_ACL_ENTRY_T entry_d,
1990 SMB_ACL_TAG_T *tag_type_p)
1992 VFS_FIND(sys_acl_get_tag_type);
1993 return handle->fns->sys_acl_get_tag_type_fn(handle, entry_d,
1994 tag_type_p);
1997 int smb_vfs_call_sys_acl_get_permset(struct vfs_handle_struct *handle,
1998 SMB_ACL_ENTRY_T entry_d,
1999 SMB_ACL_PERMSET_T *permset_p)
2001 VFS_FIND(sys_acl_get_permset);
2002 return handle->fns->sys_acl_get_permset_fn(handle, entry_d, permset_p);
2005 void * smb_vfs_call_sys_acl_get_qualifier(struct vfs_handle_struct *handle,
2006 SMB_ACL_ENTRY_T entry_d)
2008 VFS_FIND(sys_acl_get_qualifier);
2009 return handle->fns->sys_acl_get_qualifier_fn(handle, entry_d);
2012 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2013 const char *path_p,
2014 SMB_ACL_TYPE_T type)
2016 VFS_FIND(sys_acl_get_file);
2017 return handle->fns->sys_acl_get_file_fn(handle, path_p, type);
2020 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2021 struct files_struct *fsp)
2023 VFS_FIND(sys_acl_get_fd);
2024 return handle->fns->sys_acl_get_fd_fn(handle, fsp);
2027 int smb_vfs_call_sys_acl_clear_perms(struct vfs_handle_struct *handle,
2028 SMB_ACL_PERMSET_T permset)
2030 VFS_FIND(sys_acl_clear_perms);
2031 return handle->fns->sys_acl_clear_perms_fn(handle, permset);
2034 int smb_vfs_call_sys_acl_add_perm(struct vfs_handle_struct *handle,
2035 SMB_ACL_PERMSET_T permset,
2036 SMB_ACL_PERM_T perm)
2038 VFS_FIND(sys_acl_add_perm);
2039 return handle->fns->sys_acl_add_perm_fn(handle, permset, perm);
2042 char * smb_vfs_call_sys_acl_to_text(struct vfs_handle_struct *handle,
2043 SMB_ACL_T theacl, ssize_t *plen)
2045 VFS_FIND(sys_acl_to_text);
2046 return handle->fns->sys_acl_to_text_fn(handle, theacl, plen);
2049 SMB_ACL_T smb_vfs_call_sys_acl_init(struct vfs_handle_struct *handle,
2050 int count)
2052 VFS_FIND(sys_acl_init);
2053 return handle->fns->sys_acl_init_fn(handle, count);
2056 int smb_vfs_call_sys_acl_create_entry(struct vfs_handle_struct *handle,
2057 SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2059 VFS_FIND(sys_acl_create_entry);
2060 return handle->fns->sys_acl_create_entry_fn(handle, pacl, pentry);
2063 int smb_vfs_call_sys_acl_set_tag_type(struct vfs_handle_struct *handle,
2064 SMB_ACL_ENTRY_T entry,
2065 SMB_ACL_TAG_T tagtype)
2067 VFS_FIND(sys_acl_set_tag_type);
2068 return handle->fns->sys_acl_set_tag_type_fn(handle, entry, tagtype);
2071 int smb_vfs_call_sys_acl_set_qualifier(struct vfs_handle_struct *handle,
2072 SMB_ACL_ENTRY_T entry, void *qual)
2074 VFS_FIND(sys_acl_set_qualifier);
2075 return handle->fns->sys_acl_set_qualifier_fn(handle, entry, qual);
2078 int smb_vfs_call_sys_acl_set_permset(struct vfs_handle_struct *handle,
2079 SMB_ACL_ENTRY_T entry,
2080 SMB_ACL_PERMSET_T permset)
2082 VFS_FIND(sys_acl_set_permset);
2083 return handle->fns->sys_acl_set_permset_fn(handle, entry, permset);
2086 int smb_vfs_call_sys_acl_valid(struct vfs_handle_struct *handle,
2087 SMB_ACL_T theacl)
2089 VFS_FIND(sys_acl_valid);
2090 return handle->fns->sys_acl_valid_fn(handle, theacl);
2093 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2094 const char *name, SMB_ACL_TYPE_T acltype,
2095 SMB_ACL_T theacl)
2097 VFS_FIND(sys_acl_set_file);
2098 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2101 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2102 struct files_struct *fsp, SMB_ACL_T theacl)
2104 VFS_FIND(sys_acl_set_fd);
2105 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2108 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2109 const char *path)
2111 VFS_FIND(sys_acl_delete_def_file);
2112 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2115 int smb_vfs_call_sys_acl_get_perm(struct vfs_handle_struct *handle,
2116 SMB_ACL_PERMSET_T permset,
2117 SMB_ACL_PERM_T perm)
2119 VFS_FIND(sys_acl_get_perm);
2120 return handle->fns->sys_acl_get_perm_fn(handle, permset, perm);
2123 int smb_vfs_call_sys_acl_free_text(struct vfs_handle_struct *handle,
2124 char *text)
2126 VFS_FIND(sys_acl_free_text);
2127 return handle->fns->sys_acl_free_text_fn(handle, text);
2130 int smb_vfs_call_sys_acl_free_acl(struct vfs_handle_struct *handle,
2131 SMB_ACL_T posix_acl)
2133 VFS_FIND(sys_acl_free_acl);
2134 return handle->fns->sys_acl_free_acl_fn(handle, posix_acl);
2137 int smb_vfs_call_sys_acl_free_qualifier(struct vfs_handle_struct *handle,
2138 void *qualifier, SMB_ACL_TAG_T tagtype)
2140 VFS_FIND(sys_acl_free_qualifier);
2141 return handle->fns->sys_acl_free_qualifier_fn(handle, qualifier,
2142 tagtype);
2145 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2146 const char *path, const char *name, void *value,
2147 size_t size)
2149 VFS_FIND(getxattr);
2150 return handle->fns->getxattr_fn(handle, path, name, value, size);
2153 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2154 struct files_struct *fsp, const char *name,
2155 void *value, size_t size)
2157 VFS_FIND(fgetxattr);
2158 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2161 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2162 const char *path, char *list, size_t size)
2164 VFS_FIND(listxattr);
2165 return handle->fns->listxattr_fn(handle, path, list, size);
2168 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2169 struct files_struct *fsp, char *list,
2170 size_t size)
2172 VFS_FIND(flistxattr);
2173 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2176 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2177 const char *path, const char *name)
2179 VFS_FIND(removexattr);
2180 return handle->fns->removexattr_fn(handle, path, name);
2183 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2184 struct files_struct *fsp, const char *name)
2186 VFS_FIND(fremovexattr);
2187 return handle->fns->fremovexattr_fn(handle, fsp, name);
2190 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2191 const char *name, const void *value, size_t size,
2192 int flags)
2194 VFS_FIND(setxattr);
2195 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2198 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2199 struct files_struct *fsp, const char *name,
2200 const void *value, size_t size, int flags)
2202 VFS_FIND(fsetxattr);
2203 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2206 int smb_vfs_call_aio_read(struct vfs_handle_struct *handle,
2207 struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2209 VFS_FIND(aio_read);
2210 return handle->fns->aio_read_fn(handle, fsp, aiocb);
2213 int smb_vfs_call_aio_write(struct vfs_handle_struct *handle,
2214 struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2216 VFS_FIND(aio_write);
2217 return handle->fns->aio_write_fn(handle, fsp, aiocb);
2220 ssize_t smb_vfs_call_aio_return(struct vfs_handle_struct *handle,
2221 struct files_struct *fsp,
2222 SMB_STRUCT_AIOCB *aiocb)
2224 VFS_FIND(aio_return);
2225 return handle->fns->aio_return_fn(handle, fsp, aiocb);
2228 int smb_vfs_call_aio_cancel(struct vfs_handle_struct *handle,
2229 struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2231 VFS_FIND(aio_cancel);
2232 return handle->fns->aio_cancel_fn(handle, fsp, aiocb);
2235 int smb_vfs_call_aio_error(struct vfs_handle_struct *handle,
2236 struct files_struct *fsp,
2237 SMB_STRUCT_AIOCB *aiocb)
2239 VFS_FIND(aio_error);
2240 return handle->fns->aio_error_fn(handle, fsp, aiocb);
2243 int smb_vfs_call_aio_fsync(struct vfs_handle_struct *handle,
2244 struct files_struct *fsp, int op,
2245 SMB_STRUCT_AIOCB *aiocb)
2247 VFS_FIND(aio_fsync);
2248 return handle->fns->aio_fsync_fn(handle, fsp, op, aiocb);
2251 int smb_vfs_call_aio_suspend(struct vfs_handle_struct *handle,
2252 struct files_struct *fsp,
2253 const SMB_STRUCT_AIOCB * const aiocb[], int n,
2254 const struct timespec *timeout)
2256 VFS_FIND(aio_suspend);
2257 return handle->fns->aio_suspend_fn(handle, fsp, aiocb, n, timeout);
2260 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2261 struct files_struct *fsp)
2263 VFS_FIND(aio_force);
2264 return handle->fns->aio_force_fn(handle, fsp);
2267 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2268 const struct smb_filename *fname,
2269 SMB_STRUCT_STAT *sbuf)
2271 VFS_FIND(is_offline);
2272 return handle->fns->is_offline_fn(handle, fname, sbuf);
2275 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2276 const struct smb_filename *fname)
2278 VFS_FIND(set_offline);
2279 return handle->fns->set_offline_fn(handle, fname);