s3: Fix a "Invalid (state->nread >= 0)" warning
[Samba/id10ts.git] / source3 / smbd / vfs.c
blob7da38818283961cadd255b774759f176c9b0087f
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_probe_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, SMB_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 (SMB_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 SMB_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 (((SMB_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, (SMB_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, SMB_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, SMB_OFF_T offset, SMB_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, SMB_OFF_T len)
624 int ret;
625 NTSTATUS status;
626 SMB_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 SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_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 SMB_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, (SMB_STRUCT_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 SMB_STRUCT_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 SMB_STRUCT_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 SMB_STRUCT_DIRENT *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1409 SMB_STRUCT_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 SMB_STRUCT_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 SMB_STRUCT_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 SMB_STRUCT_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 SMB_STRUCT_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 SMB_STRUCT_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 SMB_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, SMB_OFF_T offset)
1532 VFS_FIND(pwrite);
1533 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1536 SMB_OFF_T smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1537 struct files_struct *fsp, SMB_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 SMB_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, SMB_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, SMB_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 SMB_OFF_T offset,
1778 SMB_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 struct notify_entry *e,
1837 void (*callback)(struct sys_notify_context *ctx,
1838 void *private_data,
1839 struct notify_event *ev),
1840 void *private_data, void *handle_p)
1842 VFS_FIND(notify_watch);
1843 return handle->fns->notify_watch_fn(handle, ctx, e, callback,
1844 private_data, handle_p);
1847 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
1848 unsigned int flags)
1850 VFS_FIND(chflags);
1851 return handle->fns->chflags_fn(handle, path, flags);
1854 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
1855 const SMB_STRUCT_STAT *sbuf)
1857 VFS_FIND(file_id_create);
1858 return handle->fns->file_id_create_fn(handle, sbuf);
1861 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
1862 struct files_struct *fsp,
1863 const char *fname,
1864 TALLOC_CTX *mem_ctx,
1865 unsigned int *num_streams,
1866 struct stream_struct **streams)
1868 VFS_FIND(streaminfo);
1869 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
1870 num_streams, streams);
1873 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
1874 const char *path, const char *name,
1875 TALLOC_CTX *mem_ctx, char **found_name)
1877 VFS_FIND(get_real_filename);
1878 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
1879 found_name);
1882 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
1883 const char *filename)
1885 VFS_FIND(connectpath);
1886 return handle->fns->connectpath_fn(handle, filename);
1889 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
1890 struct files_struct *fsp,
1891 struct lock_struct *plock)
1893 VFS_FIND(strict_lock);
1894 return handle->fns->strict_lock_fn(handle, fsp, plock);
1897 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
1898 struct files_struct *fsp,
1899 struct lock_struct *plock)
1901 VFS_FIND(strict_unlock);
1902 handle->fns->strict_unlock_fn(handle, fsp, plock);
1905 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
1906 const char *name,
1907 enum vfs_translate_direction direction,
1908 TALLOC_CTX *mem_ctx,
1909 char **mapped_name)
1911 VFS_FIND(translate_name);
1912 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
1913 mapped_name);
1916 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
1917 struct files_struct *fsp,
1918 TALLOC_CTX *ctx,
1919 uint32_t function,
1920 uint16_t req_flags,
1921 const uint8_t *in_data,
1922 uint32_t in_len,
1923 uint8_t **out_data,
1924 uint32_t max_out_len,
1925 uint32_t *out_len)
1927 VFS_FIND(fsctl);
1928 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
1929 in_data, in_len, out_data, max_out_len,
1930 out_len);
1933 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
1934 struct files_struct *fsp,
1935 uint32 security_info,
1936 struct security_descriptor **ppdesc)
1938 VFS_FIND(fget_nt_acl);
1939 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
1940 ppdesc);
1943 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
1944 const char *name,
1945 uint32 security_info,
1946 struct security_descriptor **ppdesc)
1948 VFS_FIND(get_nt_acl);
1949 return handle->fns->get_nt_acl_fn(handle, name, security_info, ppdesc);
1952 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
1953 struct files_struct *fsp,
1954 uint32 security_info_sent,
1955 const struct security_descriptor *psd)
1957 VFS_FIND(fset_nt_acl);
1958 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
1959 psd);
1962 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
1963 mode_t mode)
1965 VFS_FIND(chmod_acl);
1966 return handle->fns->chmod_acl_fn(handle, name, mode);
1969 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
1970 struct files_struct *fsp, mode_t mode)
1972 VFS_FIND(fchmod_acl);
1973 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
1976 int smb_vfs_call_sys_acl_get_entry(struct vfs_handle_struct *handle,
1977 SMB_ACL_T theacl, int entry_id,
1978 SMB_ACL_ENTRY_T *entry_p)
1980 VFS_FIND(sys_acl_get_entry);
1981 return handle->fns->sys_acl_get_entry_fn(handle, theacl, entry_id,
1982 entry_p);
1985 int smb_vfs_call_sys_acl_get_tag_type(struct vfs_handle_struct *handle,
1986 SMB_ACL_ENTRY_T entry_d,
1987 SMB_ACL_TAG_T *tag_type_p)
1989 VFS_FIND(sys_acl_get_tag_type);
1990 return handle->fns->sys_acl_get_tag_type_fn(handle, entry_d,
1991 tag_type_p);
1994 int smb_vfs_call_sys_acl_get_permset(struct vfs_handle_struct *handle,
1995 SMB_ACL_ENTRY_T entry_d,
1996 SMB_ACL_PERMSET_T *permset_p)
1998 VFS_FIND(sys_acl_get_permset);
1999 return handle->fns->sys_acl_get_permset_fn(handle, entry_d, permset_p);
2002 void * smb_vfs_call_sys_acl_get_qualifier(struct vfs_handle_struct *handle,
2003 SMB_ACL_ENTRY_T entry_d)
2005 VFS_FIND(sys_acl_get_qualifier);
2006 return handle->fns->sys_acl_get_qualifier_fn(handle, entry_d);
2009 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2010 const char *path_p,
2011 SMB_ACL_TYPE_T type)
2013 VFS_FIND(sys_acl_get_file);
2014 return handle->fns->sys_acl_get_file_fn(handle, path_p, type);
2017 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2018 struct files_struct *fsp)
2020 VFS_FIND(sys_acl_get_fd);
2021 return handle->fns->sys_acl_get_fd_fn(handle, fsp);
2024 int smb_vfs_call_sys_acl_clear_perms(struct vfs_handle_struct *handle,
2025 SMB_ACL_PERMSET_T permset)
2027 VFS_FIND(sys_acl_clear_perms);
2028 return handle->fns->sys_acl_clear_perms_fn(handle, permset);
2031 int smb_vfs_call_sys_acl_add_perm(struct vfs_handle_struct *handle,
2032 SMB_ACL_PERMSET_T permset,
2033 SMB_ACL_PERM_T perm)
2035 VFS_FIND(sys_acl_add_perm);
2036 return handle->fns->sys_acl_add_perm_fn(handle, permset, perm);
2039 char * smb_vfs_call_sys_acl_to_text(struct vfs_handle_struct *handle,
2040 SMB_ACL_T theacl, ssize_t *plen)
2042 VFS_FIND(sys_acl_to_text);
2043 return handle->fns->sys_acl_to_text_fn(handle, theacl, plen);
2046 SMB_ACL_T smb_vfs_call_sys_acl_init(struct vfs_handle_struct *handle,
2047 int count)
2049 VFS_FIND(sys_acl_init);
2050 return handle->fns->sys_acl_init_fn(handle, count);
2053 int smb_vfs_call_sys_acl_create_entry(struct vfs_handle_struct *handle,
2054 SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2056 VFS_FIND(sys_acl_create_entry);
2057 return handle->fns->sys_acl_create_entry_fn(handle, pacl, pentry);
2060 int smb_vfs_call_sys_acl_set_tag_type(struct vfs_handle_struct *handle,
2061 SMB_ACL_ENTRY_T entry,
2062 SMB_ACL_TAG_T tagtype)
2064 VFS_FIND(sys_acl_set_tag_type);
2065 return handle->fns->sys_acl_set_tag_type_fn(handle, entry, tagtype);
2068 int smb_vfs_call_sys_acl_set_qualifier(struct vfs_handle_struct *handle,
2069 SMB_ACL_ENTRY_T entry, void *qual)
2071 VFS_FIND(sys_acl_set_qualifier);
2072 return handle->fns->sys_acl_set_qualifier_fn(handle, entry, qual);
2075 int smb_vfs_call_sys_acl_set_permset(struct vfs_handle_struct *handle,
2076 SMB_ACL_ENTRY_T entry,
2077 SMB_ACL_PERMSET_T permset)
2079 VFS_FIND(sys_acl_set_permset);
2080 return handle->fns->sys_acl_set_permset_fn(handle, entry, permset);
2083 int smb_vfs_call_sys_acl_valid(struct vfs_handle_struct *handle,
2084 SMB_ACL_T theacl)
2086 VFS_FIND(sys_acl_valid);
2087 return handle->fns->sys_acl_valid_fn(handle, theacl);
2090 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2091 const char *name, SMB_ACL_TYPE_T acltype,
2092 SMB_ACL_T theacl)
2094 VFS_FIND(sys_acl_set_file);
2095 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2098 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2099 struct files_struct *fsp, SMB_ACL_T theacl)
2101 VFS_FIND(sys_acl_set_fd);
2102 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2105 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2106 const char *path)
2108 VFS_FIND(sys_acl_delete_def_file);
2109 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2112 int smb_vfs_call_sys_acl_get_perm(struct vfs_handle_struct *handle,
2113 SMB_ACL_PERMSET_T permset,
2114 SMB_ACL_PERM_T perm)
2116 VFS_FIND(sys_acl_get_perm);
2117 return handle->fns->sys_acl_get_perm_fn(handle, permset, perm);
2120 int smb_vfs_call_sys_acl_free_text(struct vfs_handle_struct *handle,
2121 char *text)
2123 VFS_FIND(sys_acl_free_text);
2124 return handle->fns->sys_acl_free_text_fn(handle, text);
2127 int smb_vfs_call_sys_acl_free_acl(struct vfs_handle_struct *handle,
2128 SMB_ACL_T posix_acl)
2130 VFS_FIND(sys_acl_free_acl);
2131 return handle->fns->sys_acl_free_acl_fn(handle, posix_acl);
2134 int smb_vfs_call_sys_acl_free_qualifier(struct vfs_handle_struct *handle,
2135 void *qualifier, SMB_ACL_TAG_T tagtype)
2137 VFS_FIND(sys_acl_free_qualifier);
2138 return handle->fns->sys_acl_free_qualifier_fn(handle, qualifier,
2139 tagtype);
2142 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2143 const char *path, const char *name, void *value,
2144 size_t size)
2146 VFS_FIND(getxattr);
2147 return handle->fns->getxattr_fn(handle, path, name, value, size);
2150 ssize_t smb_vfs_call_lgetxattr(struct vfs_handle_struct *handle,
2151 const char *path, const char *name, void *value,
2152 size_t size)
2154 VFS_FIND(lgetxattr);
2155 return handle->fns->lgetxattr_fn(handle, path, name, value, size);
2158 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2159 struct files_struct *fsp, const char *name,
2160 void *value, size_t size)
2162 VFS_FIND(fgetxattr);
2163 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2166 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2167 const char *path, char *list, size_t size)
2169 VFS_FIND(listxattr);
2170 return handle->fns->listxattr_fn(handle, path, list, size);
2173 ssize_t smb_vfs_call_llistxattr(struct vfs_handle_struct *handle,
2174 const char *path, char *list, size_t size)
2176 VFS_FIND(llistxattr);
2177 return handle->fns->llistxattr_fn(handle, path, list, size);
2180 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2181 struct files_struct *fsp, char *list,
2182 size_t size)
2184 VFS_FIND(flistxattr);
2185 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2188 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2189 const char *path, const char *name)
2191 VFS_FIND(removexattr);
2192 return handle->fns->removexattr_fn(handle, path, name);
2195 int smb_vfs_call_lremovexattr(struct vfs_handle_struct *handle,
2196 const char *path, const char *name)
2198 VFS_FIND(lremovexattr);
2199 return handle->fns->lremovexattr_fn(handle, path, name);
2202 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2203 struct files_struct *fsp, const char *name)
2205 VFS_FIND(fremovexattr);
2206 return handle->fns->fremovexattr_fn(handle, fsp, name);
2209 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2210 const char *name, const void *value, size_t size,
2211 int flags)
2213 VFS_FIND(setxattr);
2214 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2217 int smb_vfs_call_lsetxattr(struct vfs_handle_struct *handle, const char *path,
2218 const char *name, const void *value, size_t size,
2219 int flags)
2221 VFS_FIND(lsetxattr);
2222 return handle->fns->lsetxattr_fn(handle, path, name, value, size,
2223 flags);
2226 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2227 struct files_struct *fsp, const char *name,
2228 const void *value, size_t size, int flags)
2230 VFS_FIND(fsetxattr);
2231 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2234 int smb_vfs_call_aio_read(struct vfs_handle_struct *handle,
2235 struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2237 VFS_FIND(aio_read);
2238 return handle->fns->aio_read_fn(handle, fsp, aiocb);
2241 int smb_vfs_call_aio_write(struct vfs_handle_struct *handle,
2242 struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2244 VFS_FIND(aio_write);
2245 return handle->fns->aio_write_fn(handle, fsp, aiocb);
2248 ssize_t smb_vfs_call_aio_return(struct vfs_handle_struct *handle,
2249 struct files_struct *fsp,
2250 SMB_STRUCT_AIOCB *aiocb)
2252 VFS_FIND(aio_return);
2253 return handle->fns->aio_return_fn(handle, fsp, aiocb);
2256 int smb_vfs_call_aio_cancel(struct vfs_handle_struct *handle,
2257 struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2259 VFS_FIND(aio_cancel);
2260 return handle->fns->aio_cancel_fn(handle, fsp, aiocb);
2263 int smb_vfs_call_aio_error(struct vfs_handle_struct *handle,
2264 struct files_struct *fsp,
2265 SMB_STRUCT_AIOCB *aiocb)
2267 VFS_FIND(aio_error);
2268 return handle->fns->aio_error_fn(handle, fsp, aiocb);
2271 int smb_vfs_call_aio_fsync(struct vfs_handle_struct *handle,
2272 struct files_struct *fsp, int op,
2273 SMB_STRUCT_AIOCB *aiocb)
2275 VFS_FIND(aio_fsync);
2276 return handle->fns->aio_fsync_fn(handle, fsp, op, aiocb);
2279 int smb_vfs_call_aio_suspend(struct vfs_handle_struct *handle,
2280 struct files_struct *fsp,
2281 const SMB_STRUCT_AIOCB * const aiocb[], int n,
2282 const struct timespec *timeout)
2284 VFS_FIND(aio_suspend);
2285 return handle->fns->aio_suspend_fn(handle, fsp, aiocb, n, timeout);
2288 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2289 struct files_struct *fsp)
2291 VFS_FIND(aio_force);
2292 return handle->fns->aio_force_fn(handle, fsp);
2295 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2296 const struct smb_filename *fname,
2297 SMB_STRUCT_STAT *sbuf)
2299 VFS_FIND(is_offline);
2300 return handle->fns->is_offline_fn(handle, fname, sbuf);
2303 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2304 const struct smb_filename *fname)
2306 VFS_FIND(set_offline);
2307 return handle->fns->set_offline_fn(handle, fname);