s3: Fix Coverity ID 710827 Resource leak
[Samba/gebeck_regimport.git] / source3 / smbd / vfs.c
blob474e476f3d525d56aa498b37ba8869c9278909fb
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 VFS initialisation and support functions
5 Copyright (C) Tim Potter 1999
6 Copyright (C) Alexander Bokovoy 2002
7 Copyright (C) James Peach 2006
8 Copyright (C) Volker Lendecke 2009
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 This work was sponsored by Optifacio Software Services, Inc.
26 #include "includes.h"
27 #include "system/filesys.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "memcache.h"
31 #include "transfer_file.h"
32 #include "ntioctl.h"
33 #include "lib/util/tevent_unix.h"
35 #undef DBGC_CLASS
36 #define DBGC_CLASS DBGC_VFS
38 static_decl_vfs;
40 struct vfs_fsp_data {
41 struct vfs_fsp_data *next;
42 struct vfs_handle_struct *owner;
43 void (*destroy)(void *p_data);
44 void *_dummy_;
45 /* NOTE: This structure contains four pointers so that we can guarantee
46 * that the end of the structure is always both 4-byte and 8-byte aligned.
50 struct vfs_init_function_entry {
51 char *name;
52 struct vfs_init_function_entry *prev, *next;
53 const struct vfs_fn_pointers *fns;
56 /****************************************************************************
57 maintain the list of available backends
58 ****************************************************************************/
60 static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
62 struct vfs_init_function_entry *entry = backends;
64 DEBUG(10, ("vfs_find_backend_entry called for %s\n", name));
66 while(entry) {
67 if (strcmp(entry->name, name)==0) return entry;
68 entry = entry->next;
71 return NULL;
74 NTSTATUS smb_register_vfs(int version, const char *name,
75 const struct vfs_fn_pointers *fns)
77 struct vfs_init_function_entry *entry = backends;
79 if ((version != SMB_VFS_INTERFACE_VERSION)) {
80 DEBUG(0, ("Failed to register vfs module.\n"
81 "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
82 "current SMB_VFS_INTERFACE_VERSION is %d.\n"
83 "Please recompile against the current Samba Version!\n",
84 version, SMB_VFS_INTERFACE_VERSION));
85 return NT_STATUS_OBJECT_TYPE_MISMATCH;
88 if (!name || !name[0]) {
89 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
90 return NT_STATUS_INVALID_PARAMETER;
93 if (vfs_find_backend_entry(name)) {
94 DEBUG(0,("VFS module %s already loaded!\n", name));
95 return NT_STATUS_OBJECT_NAME_COLLISION;
98 entry = SMB_XMALLOC_P(struct vfs_init_function_entry);
99 entry->name = smb_xstrdup(name);
100 entry->fns = fns;
102 DLIST_ADD(backends, entry);
103 DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
104 return NT_STATUS_OK;
107 /****************************************************************************
108 initialise default vfs hooks
109 ****************************************************************************/
111 static void vfs_init_default(connection_struct *conn)
113 DEBUG(3, ("Initialising default vfs hooks\n"));
114 vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME);
117 /****************************************************************************
118 initialise custom vfs hooks
119 ****************************************************************************/
121 bool vfs_init_custom(connection_struct *conn, const char *vfs_object)
123 char *module_path = NULL;
124 char *module_name = NULL;
125 char *module_param = NULL, *p;
126 vfs_handle_struct *handle;
127 const struct vfs_init_function_entry *entry;
129 if (!conn||!vfs_object||!vfs_object[0]) {
130 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
131 "empty vfs_object!\n"));
132 return False;
135 if(!backends) {
136 static_init_vfs;
139 DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
141 module_path = smb_xstrdup(vfs_object);
143 p = strchr_m(module_path, ':');
145 if (p) {
146 *p = 0;
147 module_param = p+1;
148 trim_char(module_param, ' ', ' ');
151 trim_char(module_path, ' ', ' ');
153 module_name = smb_xstrdup(module_path);
155 if ((module_name[0] == '/') &&
156 (strcmp(module_path, DEFAULT_VFS_MODULE_NAME) != 0)) {
159 * Extract the module name from the path. Just use the base
160 * name of the last path component.
163 SAFE_FREE(module_name);
164 module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
166 p = strchr_m(module_name, '.');
168 if (p != NULL) {
169 *p = '\0';
173 /* First, try to load the module with the new module system */
174 entry = vfs_find_backend_entry(module_name);
175 if (!entry) {
176 NTSTATUS status;
178 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
179 vfs_object));
181 status = smb_load_module("vfs", module_path);
182 if (!NT_STATUS_IS_OK(status)) {
183 DEBUG(0, ("error probing vfs module '%s': %s\n",
184 module_path, nt_errstr(status)));
185 goto fail;
188 entry = vfs_find_backend_entry(module_name);
189 if (!entry) {
190 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
191 goto fail;
195 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
197 handle = talloc_zero(conn, vfs_handle_struct);
198 if (!handle) {
199 DEBUG(0,("TALLOC_ZERO() failed!\n"));
200 goto fail;
202 handle->conn = conn;
203 handle->fns = entry->fns;
204 if (module_param) {
205 handle->param = talloc_strdup(conn, module_param);
207 DLIST_ADD(conn->vfs_handles, handle);
209 SAFE_FREE(module_path);
210 SAFE_FREE(module_name);
211 return True;
213 fail:
214 SAFE_FREE(module_path);
215 SAFE_FREE(module_name);
216 return False;
219 /*****************************************************************
220 Allow VFS modules to extend files_struct with VFS-specific state.
221 This will be ok for small numbers of extensions, but might need to
222 be refactored if it becomes more widely used.
223 ******************************************************************/
225 #define EXT_DATA_AREA(e) ((uint8 *)(e) + sizeof(struct vfs_fsp_data))
227 void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle,
228 files_struct *fsp, size_t ext_size,
229 void (*destroy_fn)(void *p_data))
231 struct vfs_fsp_data *ext;
232 void * ext_data;
234 /* Prevent VFS modules adding multiple extensions. */
235 if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
236 return ext_data;
239 ext = (struct vfs_fsp_data *)TALLOC_ZERO(
240 handle->conn, sizeof(struct vfs_fsp_data) + ext_size);
241 if (ext == NULL) {
242 return NULL;
245 ext->owner = handle;
246 ext->next = fsp->vfs_extension;
247 ext->destroy = destroy_fn;
248 fsp->vfs_extension = ext;
249 return EXT_DATA_AREA(ext);
252 void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
254 struct vfs_fsp_data *curr;
255 struct vfs_fsp_data *prev;
257 for (curr = fsp->vfs_extension, prev = NULL;
258 curr;
259 prev = curr, curr = curr->next) {
260 if (curr->owner == handle) {
261 if (prev) {
262 prev->next = curr->next;
263 } else {
264 fsp->vfs_extension = curr->next;
266 if (curr->destroy) {
267 curr->destroy(EXT_DATA_AREA(curr));
269 TALLOC_FREE(curr);
270 return;
275 void vfs_remove_all_fsp_extensions(files_struct *fsp)
277 struct vfs_fsp_data *curr;
278 struct vfs_fsp_data *next;
280 for (curr = fsp->vfs_extension; curr; curr = next) {
282 next = curr->next;
283 fsp->vfs_extension = next;
285 if (curr->destroy) {
286 curr->destroy(EXT_DATA_AREA(curr));
288 TALLOC_FREE(curr);
292 void *vfs_memctx_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
294 struct vfs_fsp_data *head;
296 for (head = fsp->vfs_extension; head; head = head->next) {
297 if (head->owner == handle) {
298 return head;
302 return NULL;
305 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
307 struct vfs_fsp_data *head;
309 head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
310 if (head != NULL) {
311 return EXT_DATA_AREA(head);
314 return NULL;
317 #undef EXT_DATA_AREA
319 /*****************************************************************
320 Generic VFS init.
321 ******************************************************************/
323 bool smbd_vfs_init(connection_struct *conn)
325 const char **vfs_objects;
326 unsigned int i = 0;
327 int j = 0;
329 /* Normal share - initialise with disk access functions */
330 vfs_init_default(conn);
331 vfs_objects = lp_vfs_objects(SNUM(conn));
333 /* Override VFS functions if 'vfs object' was not specified*/
334 if (!vfs_objects || !vfs_objects[0])
335 return True;
337 for (i=0; vfs_objects[i] ;) {
338 i++;
341 for (j=i-1; j >= 0; j--) {
342 if (!vfs_init_custom(conn, vfs_objects[j])) {
343 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
344 return False;
347 return True;
350 /*******************************************************************
351 Check if a file exists in the vfs.
352 ********************************************************************/
354 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
356 /* Only return OK if stat was successful and S_ISREG */
357 if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
358 S_ISREG(smb_fname->st.st_ex_mode)) {
359 return NT_STATUS_OK;
362 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
365 /****************************************************************************
366 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
367 ****************************************************************************/
369 ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
371 size_t total=0;
373 while (total < byte_count)
375 ssize_t ret = SMB_VFS_READ(fsp, buf + total,
376 byte_count - total);
378 if (ret == 0) return total;
379 if (ret == -1) {
380 if (errno == EINTR)
381 continue;
382 else
383 return -1;
385 total += ret;
387 return (ssize_t)total;
390 ssize_t vfs_pread_data(files_struct *fsp, char *buf,
391 size_t byte_count, off_t offset)
393 size_t total=0;
395 while (total < byte_count)
397 ssize_t ret = SMB_VFS_PREAD(fsp, buf + total,
398 byte_count - total, offset + total);
400 if (ret == 0) return total;
401 if (ret == -1) {
402 if (errno == EINTR)
403 continue;
404 else
405 return -1;
407 total += ret;
409 return (ssize_t)total;
412 /****************************************************************************
413 Write data to a fd on the vfs.
414 ****************************************************************************/
416 ssize_t vfs_write_data(struct smb_request *req,
417 files_struct *fsp,
418 const char *buffer,
419 size_t N)
421 size_t total=0;
422 ssize_t ret;
424 if (req && req->unread_bytes) {
425 SMB_ASSERT(req->unread_bytes == N);
426 /* VFS_RECVFILE must drain the socket
427 * before returning. */
428 req->unread_bytes = 0;
429 return SMB_VFS_RECVFILE(req->sconn->sock,
430 fsp,
431 (off_t)-1,
435 while (total < N) {
436 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
438 if (ret == -1)
439 return -1;
440 if (ret == 0)
441 return total;
443 total += ret;
445 return (ssize_t)total;
448 ssize_t vfs_pwrite_data(struct smb_request *req,
449 files_struct *fsp,
450 const char *buffer,
451 size_t N,
452 off_t offset)
454 size_t total=0;
455 ssize_t ret;
457 if (req && req->unread_bytes) {
458 SMB_ASSERT(req->unread_bytes == N);
459 /* VFS_RECVFILE must drain the socket
460 * before returning. */
461 req->unread_bytes = 0;
462 return SMB_VFS_RECVFILE(req->sconn->sock,
463 fsp,
464 offset,
468 while (total < N) {
469 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
470 offset + total);
472 if (ret == -1)
473 return -1;
474 if (ret == 0)
475 return total;
477 total += ret;
479 return (ssize_t)total;
481 /****************************************************************************
482 An allocate file space call using the vfs interface.
483 Allocates space for a file from a filedescriptor.
484 Returns 0 on success, -1 on failure.
485 ****************************************************************************/
487 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
489 int ret;
490 connection_struct *conn = fsp->conn;
491 uint64_t space_avail;
492 uint64_t bsize,dfree,dsize;
493 NTSTATUS status;
496 * Actually try and commit the space on disk....
499 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
500 fsp_str_dbg(fsp), (double)len));
502 if (((off_t)len) < 0) {
503 DEBUG(0,("vfs_allocate_file_space: %s negative len "
504 "requested.\n", fsp_str_dbg(fsp)));
505 errno = EINVAL;
506 return -1;
509 status = vfs_stat_fsp(fsp);
510 if (!NT_STATUS_IS_OK(status)) {
511 return -1;
514 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
515 return 0;
517 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
518 /* Shrink - use ftruncate. */
520 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
521 "size %.0f\n", fsp_str_dbg(fsp),
522 (double)fsp->fsp_name->st.st_ex_size));
524 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
526 flush_write_cache(fsp, SIZECHANGE_FLUSH);
527 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
528 set_filelen_write_cache(fsp, len);
531 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
533 return ret;
536 if (!lp_strict_allocate(SNUM(fsp->conn)))
537 return 0;
539 /* Grow - we need to test if we have enough space. */
541 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
543 /* See if we have a syscall that will allocate beyond end-of-file
544 without changing EOF. */
545 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
547 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
549 if (ret == 0) {
550 /* We changed the allocation size on disk, but not
551 EOF - exactly as required. We're done ! */
552 return 0;
555 len -= fsp->fsp_name->st.st_ex_size;
556 len /= 1024; /* Len is now number of 1k blocks needed. */
557 space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
558 &bsize, &dfree, &dsize);
559 if (space_avail == (uint64_t)-1) {
560 return -1;
563 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
564 "needed blocks = %.0f, space avail = %.0f\n",
565 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
566 (double)space_avail));
568 if (len > space_avail) {
569 errno = ENOSPC;
570 return -1;
573 return 0;
576 /****************************************************************************
577 A vfs set_filelen call.
578 set the length of a file from a filedescriptor.
579 Returns 0 on success, -1 on failure.
580 ****************************************************************************/
582 int vfs_set_filelen(files_struct *fsp, off_t len)
584 int ret;
586 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
588 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
589 fsp_str_dbg(fsp), (double)len));
590 flush_write_cache(fsp, SIZECHANGE_FLUSH);
591 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
592 set_filelen_write_cache(fsp, len);
593 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
594 FILE_NOTIFY_CHANGE_SIZE
595 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
596 fsp->fsp_name->base_name);
599 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
601 return ret;
604 /****************************************************************************
605 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
606 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
607 as this is also called from the default SMB_VFS_FTRUNCATE code.
608 Always extends the file size.
609 Returns 0 on success, errno on failure.
610 ****************************************************************************/
612 #define SPARSE_BUF_WRITE_SIZE (32*1024)
614 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
616 ssize_t pwrite_ret;
617 size_t total = 0;
619 if (!sparse_buf) {
620 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
621 if (!sparse_buf) {
622 errno = ENOMEM;
623 return ENOMEM;
627 while (total < len) {
628 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
630 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
631 if (pwrite_ret == -1) {
632 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
633 "%s failed with error %s\n",
634 fsp_str_dbg(fsp), strerror(errno)));
635 return errno;
637 total += pwrite_ret;
640 return 0;
643 /****************************************************************************
644 A vfs fill sparse call.
645 Writes zeros from the end of file to len, if len is greater than EOF.
646 Used only by strict_sync.
647 Returns 0 on success, -1 on failure.
648 ****************************************************************************/
650 int vfs_fill_sparse(files_struct *fsp, off_t len)
652 int ret;
653 NTSTATUS status;
654 off_t offset;
655 size_t num_to_write;
657 status = vfs_stat_fsp(fsp);
658 if (!NT_STATUS_IS_OK(status)) {
659 return -1;
662 if (len <= fsp->fsp_name->st.st_ex_size) {
663 return 0;
666 #ifdef S_ISFIFO
667 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
668 return 0;
670 #endif
672 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
673 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
674 (double)fsp->fsp_name->st.st_ex_size, (double)len,
675 (double)(len - fsp->fsp_name->st.st_ex_size)));
677 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
679 flush_write_cache(fsp, SIZECHANGE_FLUSH);
681 offset = fsp->fsp_name->st.st_ex_size;
682 num_to_write = len - fsp->fsp_name->st.st_ex_size;
684 /* Only do this on non-stream file handles. */
685 if (fsp->base_fsp == NULL) {
686 /* for allocation try fallocate first. This can fail on some
687 * platforms e.g. when the filesystem doesn't support it and no
688 * emulation is being done by the libc (like on AIX with JFS1). In that
689 * case we do our own emulation. fallocate implementations can
690 * return ENOTSUP or EINVAL in cases like that. */
691 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
692 offset, num_to_write);
693 if (ret == ENOSPC) {
694 errno = ENOSPC;
695 ret = -1;
696 goto out;
698 if (ret == 0) {
699 goto out;
701 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
702 "error %d. Falling back to slow manual allocation\n", ret));
705 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
706 if (ret != 0) {
707 errno = ret;
708 ret = -1;
711 out:
713 if (ret == 0) {
714 set_filelen_write_cache(fsp, len);
717 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
718 return ret;
721 /****************************************************************************
722 Transfer some data (n bytes) between two file_struct's.
723 ****************************************************************************/
725 static ssize_t vfs_read_fn(void *file, void *buf, size_t len)
727 struct files_struct *fsp = (struct files_struct *)file;
729 return SMB_VFS_READ(fsp, buf, len);
732 static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
734 struct files_struct *fsp = (struct files_struct *)file;
736 return SMB_VFS_WRITE(fsp, buf, len);
739 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
741 return transfer_file_internal((void *)in, (void *)out, n,
742 vfs_read_fn, vfs_write_fn);
745 /*******************************************************************
746 A vfs_readdir wrapper which just returns the file name.
747 ********************************************************************/
749 const char *vfs_readdirname(connection_struct *conn, void *p,
750 SMB_STRUCT_STAT *sbuf, char **talloced)
752 struct dirent *ptr= NULL;
753 const char *dname;
754 char *translated;
755 NTSTATUS status;
757 if (!p)
758 return(NULL);
760 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
761 if (!ptr)
762 return(NULL);
764 dname = ptr->d_name;
767 #ifdef NEXT2
768 if (telldir(p) < 0)
769 return(NULL);
770 #endif
772 #ifdef HAVE_BROKEN_READDIR_NAME
773 /* using /usr/ucb/cc is BAD */
774 dname = dname - 2;
775 #endif
777 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
778 talloc_tos(), &translated);
779 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
780 *talloced = NULL;
781 return dname;
783 *talloced = translated;
784 if (!NT_STATUS_IS_OK(status)) {
785 return NULL;
787 return translated;
790 /*******************************************************************
791 A wrapper for vfs_chdir().
792 ********************************************************************/
794 int vfs_ChDir(connection_struct *conn, const char *path)
796 int res;
798 if (!LastDir) {
799 LastDir = SMB_STRDUP("");
802 if (strcsequal(path,"."))
803 return(0);
805 if (*path == '/' && strcsequal(LastDir,path))
806 return(0);
808 DEBUG(4,("vfs_ChDir to %s\n",path));
810 res = SMB_VFS_CHDIR(conn,path);
811 if (!res) {
812 SAFE_FREE(LastDir);
813 LastDir = SMB_STRDUP(path);
815 return(res);
818 /*******************************************************************
819 Return the absolute current directory path - given a UNIX pathname.
820 Note that this path is returned in DOS format, not UNIX
821 format. Note this can be called with conn == NULL.
822 ********************************************************************/
824 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
826 char *current_dir = NULL;
827 char *result = NULL;
828 DATA_BLOB cache_value;
829 struct file_id key;
830 struct smb_filename *smb_fname_dot = NULL;
831 struct smb_filename *smb_fname_full = NULL;
832 NTSTATUS status;
834 if (!lp_getwd_cache()) {
835 goto nocache;
838 status = create_synthetic_smb_fname(ctx, ".", NULL, NULL,
839 &smb_fname_dot);
840 if (!NT_STATUS_IS_OK(status)) {
841 errno = map_errno_from_nt_status(status);
842 goto out;
845 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
847 * Known to fail for root: the directory may be NFS-mounted
848 * and exported with root_squash (so has no root access).
850 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
851 "(NFS problem ?)\n", strerror(errno) ));
852 goto nocache;
855 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
857 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
858 data_blob_const(&key, sizeof(key)),
859 &cache_value)) {
860 goto nocache;
863 SMB_ASSERT((cache_value.length > 0)
864 && (cache_value.data[cache_value.length-1] == '\0'));
866 status = create_synthetic_smb_fname(ctx, (char *)cache_value.data,
867 NULL, NULL, &smb_fname_full);
868 if (!NT_STATUS_IS_OK(status)) {
869 errno = map_errno_from_nt_status(status);
870 goto out;
873 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
874 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
875 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
876 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
878 * Ok, we're done
880 result = talloc_strdup(ctx, smb_fname_full->base_name);
881 if (result == NULL) {
882 errno = ENOMEM;
884 goto out;
887 nocache:
890 * We don't have the information to hand so rely on traditional
891 * methods. The very slow getcwd, which spawns a process on some
892 * systems, or the not quite so bad getwd.
895 current_dir = SMB_VFS_GETWD(conn);
896 if (current_dir == NULL) {
897 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
898 strerror(errno)));
899 goto out;
902 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
903 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
905 memcache_add(smbd_memcache(), GETWD_CACHE,
906 data_blob_const(&key, sizeof(key)),
907 data_blob_const(current_dir,
908 strlen(current_dir)+1));
911 result = talloc_strdup(ctx, current_dir);
912 if (result == NULL) {
913 errno = ENOMEM;
916 out:
917 TALLOC_FREE(smb_fname_dot);
918 TALLOC_FREE(smb_fname_full);
919 SAFE_FREE(current_dir);
920 return result;
923 /*******************************************************************
924 Reduce a file name, removing .. elements and checking that
925 it is below dir in the heirachy. This uses realpath.
926 This function must run as root, and will return names
927 and valid stat structs that can be checked on open.
928 ********************************************************************/
930 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
931 const char *fname,
932 struct smb_request *smbreq)
934 NTSTATUS status;
935 TALLOC_CTX *ctx = talloc_tos();
936 const char *conn_rootdir;
937 size_t rootdir_len;
938 char *dir_name = NULL;
939 const char *last_component = NULL;
940 char *resolved_name = NULL;
941 char *saved_dir = NULL;
942 struct smb_filename *smb_fname_cwd = NULL;
943 struct privilege_paths *priv_paths = NULL;
944 int ret;
946 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
947 fname,
948 conn->connectpath));
951 priv_paths = talloc_zero(smbreq, struct privilege_paths);
952 if (!priv_paths) {
953 status = NT_STATUS_NO_MEMORY;
954 goto err;
957 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
958 status = NT_STATUS_NO_MEMORY;
959 goto err;
962 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
963 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
965 if (priv_paths->parent_name.base_name == NULL ||
966 priv_paths->file_name.base_name == NULL) {
967 status = NT_STATUS_NO_MEMORY;
968 goto err;
971 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
972 status = map_nt_error_from_unix(errno);
973 goto err;
975 /* Remember where we were. */
976 saved_dir = vfs_GetWd(ctx, conn);
977 if (!saved_dir) {
978 status = map_nt_error_from_unix(errno);
979 goto err;
982 /* Go to the parent directory to lock in memory. */
983 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
984 status = map_nt_error_from_unix(errno);
985 goto err;
988 /* Get the absolute path of the parent directory. */
989 resolved_name = SMB_VFS_REALPATH(conn,".");
990 if (!resolved_name) {
991 status = map_nt_error_from_unix(errno);
992 goto err;
995 if (*resolved_name != '/') {
996 DEBUG(0,("check_reduced_name_with_privilege: realpath "
997 "doesn't return absolute paths !\n"));
998 status = NT_STATUS_OBJECT_NAME_INVALID;
999 goto err;
1002 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1003 priv_paths->parent_name.base_name,
1004 resolved_name));
1006 /* Now check the stat value is the same. */
1007 status = create_synthetic_smb_fname(talloc_tos(), ".",
1008 NULL, NULL,
1009 &smb_fname_cwd);
1010 if (!NT_STATUS_IS_OK(status)) {
1011 goto err;
1014 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1015 status = map_nt_error_from_unix(errno);
1016 goto err;
1019 /* Ensure we're pointing at the same place. */
1020 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1021 DEBUG(0,("check_reduced_name_with_privilege: "
1022 "device/inode/uid/gid on directory %s changed. "
1023 "Denying access !\n",
1024 priv_paths->parent_name.base_name));
1025 status = NT_STATUS_ACCESS_DENIED;
1026 goto err;
1029 /* Ensure we're below the connect path. */
1031 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1032 if (conn_rootdir == NULL) {
1033 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1034 "conn_rootdir\n"));
1035 status = NT_STATUS_ACCESS_DENIED;
1036 goto err;
1039 rootdir_len = strlen(conn_rootdir);
1040 if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1041 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1042 "attempt: %s is a symlink outside the "
1043 "share path\n",
1044 dir_name));
1045 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1046 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1047 status = NT_STATUS_ACCESS_DENIED;
1048 goto err;
1051 /* Now ensure that the last component either doesn't
1052 exist, or is *NOT* a symlink. */
1054 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1055 if (ret == -1) {
1056 /* Errno must be ENOENT for this be ok. */
1057 if (errno != ENOENT) {
1058 status = map_nt_error_from_unix(errno);
1059 DEBUG(2, ("check_reduced_name_with_privilege: "
1060 "LSTAT on %s failed with %s\n",
1061 priv_paths->file_name.base_name,
1062 nt_errstr(status)));
1063 goto err;
1067 if (VALID_STAT(priv_paths->file_name.st) &&
1068 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1069 DEBUG(2, ("check_reduced_name_with_privilege: "
1070 "Last component %s is a symlink. Denying"
1071 "access.\n",
1072 priv_paths->file_name.base_name));
1073 status = NT_STATUS_ACCESS_DENIED;
1074 goto err;
1077 smbreq->priv_paths = priv_paths;
1078 status = NT_STATUS_OK;
1080 err:
1082 if (saved_dir) {
1083 vfs_ChDir(conn, saved_dir);
1085 SAFE_FREE(resolved_name);
1086 if (!NT_STATUS_IS_OK(status)) {
1087 TALLOC_FREE(priv_paths);
1089 TALLOC_FREE(dir_name);
1090 return status;
1093 /*******************************************************************
1094 Reduce a file name, removing .. elements and checking that
1095 it is below dir in the heirachy. This uses realpath.
1096 ********************************************************************/
1098 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1100 char *resolved_name = NULL;
1101 bool allow_symlinks = true;
1102 bool allow_widelinks = false;
1104 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1106 resolved_name = SMB_VFS_REALPATH(conn,fname);
1108 if (!resolved_name) {
1109 switch (errno) {
1110 case ENOTDIR:
1111 DEBUG(3,("check_reduced_name: Component not a "
1112 "directory in getting realpath for "
1113 "%s\n", fname));
1114 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1115 case ENOENT:
1117 TALLOC_CTX *ctx = talloc_tos();
1118 char *dir_name = NULL;
1119 const char *last_component = NULL;
1120 char *new_name = NULL;
1121 int ret;
1123 /* Last component didn't exist.
1124 Remove it and try and canonicalise
1125 the directory name. */
1126 if (!parent_dirname(ctx, fname,
1127 &dir_name,
1128 &last_component)) {
1129 return NT_STATUS_NO_MEMORY;
1132 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1133 if (!resolved_name) {
1134 NTSTATUS status = map_nt_error_from_unix(errno);
1136 if (errno == ENOENT || errno == ENOTDIR) {
1137 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1140 DEBUG(3,("check_reduce_name: "
1141 "couldn't get realpath for "
1142 "%s (%s)\n",
1143 fname,
1144 nt_errstr(status)));
1145 return status;
1147 ret = asprintf(&new_name, "%s/%s",
1148 resolved_name, last_component);
1149 SAFE_FREE(resolved_name);
1150 if (ret == -1) {
1151 return NT_STATUS_NO_MEMORY;
1153 resolved_name = new_name;
1154 break;
1156 default:
1157 DEBUG(3,("check_reduced_name: couldn't get "
1158 "realpath for %s\n", fname));
1159 return map_nt_error_from_unix(errno);
1163 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1164 resolved_name));
1166 if (*resolved_name != '/') {
1167 DEBUG(0,("check_reduced_name: realpath doesn't return "
1168 "absolute paths !\n"));
1169 SAFE_FREE(resolved_name);
1170 return NT_STATUS_OBJECT_NAME_INVALID;
1173 allow_widelinks = lp_widelinks(SNUM(conn));
1174 allow_symlinks = lp_symlinks(SNUM(conn));
1176 /* Common widelinks and symlinks checks. */
1177 if (!allow_widelinks || !allow_symlinks) {
1178 const char *conn_rootdir;
1179 size_t rootdir_len;
1181 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1182 if (conn_rootdir == NULL) {
1183 DEBUG(2, ("check_reduced_name: Could not get "
1184 "conn_rootdir\n"));
1185 SAFE_FREE(resolved_name);
1186 return NT_STATUS_ACCESS_DENIED;
1189 rootdir_len = strlen(conn_rootdir);
1190 if (strncmp(conn_rootdir, resolved_name,
1191 rootdir_len) != 0) {
1192 DEBUG(2, ("check_reduced_name: Bad access "
1193 "attempt: %s is a symlink outside the "
1194 "share path\n", fname));
1195 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1196 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1197 SAFE_FREE(resolved_name);
1198 return NT_STATUS_ACCESS_DENIED;
1201 /* Extra checks if all symlinks are disallowed. */
1202 if (!allow_symlinks) {
1203 /* fname can't have changed in resolved_path. */
1204 const char *p = &resolved_name[rootdir_len];
1206 /* *p can be '\0' if fname was "." */
1207 if (*p == '\0' && ISDOT(fname)) {
1208 goto out;
1211 if (*p != '/') {
1212 DEBUG(2, ("check_reduced_name: logic error (%c) "
1213 "in resolved_name: %s\n",
1215 fname));
1216 SAFE_FREE(resolved_name);
1217 return NT_STATUS_ACCESS_DENIED;
1220 p++;
1221 if (strcmp(fname, p)!=0) {
1222 DEBUG(2, ("check_reduced_name: Bad access "
1223 "attempt: %s is a symlink\n",
1224 fname));
1225 SAFE_FREE(resolved_name);
1226 return NT_STATUS_ACCESS_DENIED;
1231 out:
1233 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1234 resolved_name));
1235 SAFE_FREE(resolved_name);
1236 return NT_STATUS_OK;
1240 * XXX: This is temporary and there should be no callers of this once
1241 * smb_filename is plumbed through all path based operations.
1243 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1244 SMB_STRUCT_STAT *psbuf)
1246 struct smb_filename *smb_fname = NULL;
1247 NTSTATUS status;
1248 int ret;
1250 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1251 &smb_fname);
1252 if (!NT_STATUS_IS_OK(status)) {
1253 errno = map_errno_from_nt_status(status);
1254 return -1;
1257 if (lp_posix_pathnames()) {
1258 ret = SMB_VFS_LSTAT(conn, smb_fname);
1259 } else {
1260 ret = SMB_VFS_STAT(conn, smb_fname);
1263 if (ret != -1) {
1264 *psbuf = smb_fname->st;
1267 TALLOC_FREE(smb_fname);
1268 return ret;
1272 * XXX: This is temporary and there should be no callers of this once
1273 * smb_filename is plumbed through all path based operations.
1275 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1276 SMB_STRUCT_STAT *psbuf)
1278 struct smb_filename *smb_fname = NULL;
1279 NTSTATUS status;
1280 int ret;
1282 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1283 &smb_fname);
1284 if (!NT_STATUS_IS_OK(status)) {
1285 errno = map_errno_from_nt_status(status);
1286 return -1;
1289 ret = SMB_VFS_LSTAT(conn, smb_fname);
1290 if (ret != -1) {
1291 *psbuf = smb_fname->st;
1294 TALLOC_FREE(smb_fname);
1295 return ret;
1299 * Ensure LSTAT is called for POSIX paths.
1302 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1304 int ret;
1306 if(fsp->fh->fd == -1) {
1307 if (fsp->posix_open) {
1308 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1309 } else {
1310 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1312 if (ret == -1) {
1313 return map_nt_error_from_unix(errno);
1315 } else {
1316 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1317 return map_nt_error_from_unix(errno);
1320 return NT_STATUS_OK;
1324 * Initialize num_streams and streams, then call VFS op streaminfo
1326 NTSTATUS vfs_streaminfo(connection_struct *conn,
1327 struct files_struct *fsp,
1328 const char *fname,
1329 TALLOC_CTX *mem_ctx,
1330 unsigned int *num_streams,
1331 struct stream_struct **streams)
1333 *num_streams = 0;
1334 *streams = NULL;
1335 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1339 generate a file_id from a stat structure
1341 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1343 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1346 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1347 const char *service, const char *user)
1349 VFS_FIND(connect);
1350 return handle->fns->connect_fn(handle, service, user);
1353 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1355 VFS_FIND(disconnect);
1356 handle->fns->disconnect_fn(handle);
1359 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1360 const char *path, bool small_query,
1361 uint64_t *bsize, uint64_t *dfree,
1362 uint64_t *dsize)
1364 VFS_FIND(disk_free);
1365 return handle->fns->disk_free_fn(handle, path, small_query, bsize,
1366 dfree, dsize);
1369 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1370 enum SMB_QUOTA_TYPE qtype, unid_t id,
1371 SMB_DISK_QUOTA *qt)
1373 VFS_FIND(get_quota);
1374 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1377 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1378 enum SMB_QUOTA_TYPE qtype, unid_t id,
1379 SMB_DISK_QUOTA *qt)
1381 VFS_FIND(set_quota);
1382 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1385 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1386 struct files_struct *fsp,
1387 struct shadow_copy_data *shadow_copy_data,
1388 bool labels)
1390 VFS_FIND(get_shadow_copy_data);
1391 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1392 shadow_copy_data,
1393 labels);
1395 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1396 struct vfs_statvfs_struct *statbuf)
1398 VFS_FIND(statvfs);
1399 return handle->fns->statvfs_fn(handle, path, statbuf);
1402 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1403 enum timestamp_set_resolution *p_ts_res)
1405 VFS_FIND(fs_capabilities);
1406 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1409 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1410 struct dfs_GetDFSReferral *r)
1412 VFS_FIND(get_dfs_referrals);
1413 return handle->fns->get_dfs_referrals_fn(handle, r);
1416 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1417 const char *fname, const char *mask,
1418 uint32 attributes)
1420 VFS_FIND(opendir);
1421 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1424 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1425 struct files_struct *fsp,
1426 const char *mask,
1427 uint32 attributes)
1429 VFS_FIND(fdopendir);
1430 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1433 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1434 DIR *dirp,
1435 SMB_STRUCT_STAT *sbuf)
1437 VFS_FIND(readdir);
1438 return handle->fns->readdir_fn(handle, dirp, sbuf);
1441 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1442 DIR *dirp, long offset)
1444 VFS_FIND(seekdir);
1445 handle->fns->seekdir_fn(handle, dirp, offset);
1448 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1449 DIR *dirp)
1451 VFS_FIND(telldir);
1452 return handle->fns->telldir_fn(handle, dirp);
1455 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1456 DIR *dirp)
1458 VFS_FIND(rewind_dir);
1459 handle->fns->rewind_dir_fn(handle, dirp);
1462 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1463 mode_t mode)
1465 VFS_FIND(mkdir);
1466 return handle->fns->mkdir_fn(handle, path, mode);
1469 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1471 VFS_FIND(rmdir);
1472 return handle->fns->rmdir_fn(handle, path);
1475 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1476 DIR *dir)
1478 VFS_FIND(closedir);
1479 return handle->fns->closedir_fn(handle, dir);
1482 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1483 DIR *dirp)
1485 VFS_FIND(init_search_op);
1486 handle->fns->init_search_op_fn(handle, dirp);
1489 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1490 struct smb_filename *smb_fname, struct files_struct *fsp,
1491 int flags, mode_t mode)
1493 VFS_FIND(open);
1494 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1497 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1498 struct smb_request *req,
1499 uint16_t root_dir_fid,
1500 struct smb_filename *smb_fname,
1501 uint32_t access_mask,
1502 uint32_t share_access,
1503 uint32_t create_disposition,
1504 uint32_t create_options,
1505 uint32_t file_attributes,
1506 uint32_t oplock_request,
1507 uint64_t allocation_size,
1508 uint32_t private_flags,
1509 struct security_descriptor *sd,
1510 struct ea_list *ea_list,
1511 files_struct **result,
1512 int *pinfo)
1514 VFS_FIND(create_file);
1515 return handle->fns->create_file_fn(
1516 handle, req, root_dir_fid, smb_fname, access_mask,
1517 share_access, create_disposition, create_options,
1518 file_attributes, oplock_request, allocation_size,
1519 private_flags, sd, ea_list,
1520 result, pinfo);
1523 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1524 struct files_struct *fsp)
1526 VFS_FIND(close);
1527 return handle->fns->close_fn(handle, fsp);
1530 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1531 struct files_struct *fsp, void *data, size_t n)
1533 VFS_FIND(read);
1534 return handle->fns->read_fn(handle, fsp, data, n);
1537 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1538 struct files_struct *fsp, void *data, size_t n,
1539 off_t offset)
1541 VFS_FIND(pread);
1542 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1545 struct smb_vfs_call_pread_state {
1546 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1547 ssize_t retval;
1550 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1552 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1553 TALLOC_CTX *mem_ctx,
1554 struct tevent_context *ev,
1555 struct files_struct *fsp,
1556 void *data,
1557 size_t n, off_t offset)
1559 struct tevent_req *req, *subreq;
1560 struct smb_vfs_call_pread_state *state;
1562 req = tevent_req_create(mem_ctx, &state,
1563 struct smb_vfs_call_pread_state);
1564 if (req == NULL) {
1565 return NULL;
1567 VFS_FIND(pread_send);
1568 state->recv_fn = handle->fns->pread_recv_fn;
1570 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1571 offset);
1572 if (tevent_req_nomem(subreq, req)) {
1573 return tevent_req_post(req, ev);
1575 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1576 return req;
1579 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1581 struct tevent_req *req = tevent_req_callback_data(
1582 subreq, struct tevent_req);
1583 struct smb_vfs_call_pread_state *state = tevent_req_data(
1584 req, struct smb_vfs_call_pread_state);
1585 int err;
1587 state->retval = state->recv_fn(subreq, &err);
1588 TALLOC_FREE(subreq);
1589 if (state->retval == -1) {
1590 tevent_req_error(req, err);
1591 return;
1593 tevent_req_done(req);
1596 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req, int *perrno)
1598 struct smb_vfs_call_pread_state *state = tevent_req_data(
1599 req, struct smb_vfs_call_pread_state);
1600 int err;
1602 if (tevent_req_is_unix_error(req, &err)) {
1603 *perrno = err;
1604 return -1;
1606 return state->retval;
1609 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1610 struct files_struct *fsp, const void *data,
1611 size_t n)
1613 VFS_FIND(write);
1614 return handle->fns->write_fn(handle, fsp, data, n);
1617 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1618 struct files_struct *fsp, const void *data,
1619 size_t n, off_t offset)
1621 VFS_FIND(pwrite);
1622 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1625 struct smb_vfs_call_pwrite_state {
1626 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1627 ssize_t retval;
1630 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1632 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1633 TALLOC_CTX *mem_ctx,
1634 struct tevent_context *ev,
1635 struct files_struct *fsp,
1636 const void *data,
1637 size_t n, off_t offset)
1639 struct tevent_req *req, *subreq;
1640 struct smb_vfs_call_pwrite_state *state;
1642 req = tevent_req_create(mem_ctx, &state,
1643 struct smb_vfs_call_pwrite_state);
1644 if (req == NULL) {
1645 return NULL;
1647 VFS_FIND(pwrite_send);
1648 state->recv_fn = handle->fns->pwrite_recv_fn;
1650 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1651 offset);
1652 if (tevent_req_nomem(subreq, req)) {
1653 return tevent_req_post(req, ev);
1655 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1656 return req;
1659 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1661 struct tevent_req *req = tevent_req_callback_data(
1662 subreq, struct tevent_req);
1663 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1664 req, struct smb_vfs_call_pwrite_state);
1665 int err;
1667 state->retval = state->recv_fn(subreq, &err);
1668 TALLOC_FREE(subreq);
1669 if (state->retval == -1) {
1670 tevent_req_error(req, err);
1671 return;
1673 tevent_req_done(req);
1676 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req, int *perrno)
1678 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1679 req, struct smb_vfs_call_pwrite_state);
1680 int err;
1682 if (tevent_req_is_unix_error(req, &err)) {
1683 *perrno = err;
1684 return -1;
1686 return state->retval;
1689 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1690 struct files_struct *fsp, off_t offset,
1691 int whence)
1693 VFS_FIND(lseek);
1694 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1697 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1698 files_struct *fromfsp, const DATA_BLOB *header,
1699 off_t offset, size_t count)
1701 VFS_FIND(sendfile);
1702 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1703 count);
1706 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1707 files_struct *tofsp, off_t offset,
1708 size_t count)
1710 VFS_FIND(recvfile);
1711 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1714 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1715 const struct smb_filename *smb_fname_src,
1716 const struct smb_filename *smb_fname_dst)
1718 VFS_FIND(rename);
1719 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1722 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1723 struct files_struct *fsp)
1725 VFS_FIND(fsync);
1726 return handle->fns->fsync_fn(handle, fsp);
1729 struct smb_vfs_call_fsync_state {
1730 int (*recv_fn)(struct tevent_req *req, int *err);
1731 int retval;
1734 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1736 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1737 TALLOC_CTX *mem_ctx,
1738 struct tevent_context *ev,
1739 struct files_struct *fsp)
1741 struct tevent_req *req, *subreq;
1742 struct smb_vfs_call_fsync_state *state;
1744 req = tevent_req_create(mem_ctx, &state,
1745 struct smb_vfs_call_fsync_state);
1746 if (req == NULL) {
1747 return NULL;
1749 VFS_FIND(fsync_send);
1750 state->recv_fn = handle->fns->fsync_recv_fn;
1752 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1753 if (tevent_req_nomem(subreq, req)) {
1754 return tevent_req_post(req, ev);
1756 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1757 return req;
1760 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1762 struct tevent_req *req = tevent_req_callback_data(
1763 subreq, struct tevent_req);
1764 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1765 req, struct smb_vfs_call_fsync_state);
1766 int err;
1768 state->retval = state->recv_fn(subreq, &err);
1769 TALLOC_FREE(subreq);
1770 if (state->retval == -1) {
1771 tevent_req_error(req, err);
1772 return;
1774 tevent_req_done(req);
1777 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, int *perrno)
1779 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1780 req, struct smb_vfs_call_fsync_state);
1781 int err;
1783 if (tevent_req_is_unix_error(req, &err)) {
1784 *perrno = err;
1785 return -1;
1787 return state->retval;
1791 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1792 struct smb_filename *smb_fname)
1794 VFS_FIND(stat);
1795 return handle->fns->stat_fn(handle, smb_fname);
1798 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1799 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1801 VFS_FIND(fstat);
1802 return handle->fns->fstat_fn(handle, fsp, sbuf);
1805 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1806 struct smb_filename *smb_filename)
1808 VFS_FIND(lstat);
1809 return handle->fns->lstat_fn(handle, smb_filename);
1812 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1813 struct files_struct *fsp,
1814 const SMB_STRUCT_STAT *sbuf)
1816 VFS_FIND(get_alloc_size);
1817 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1820 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1821 const struct smb_filename *smb_fname)
1823 VFS_FIND(unlink);
1824 return handle->fns->unlink_fn(handle, smb_fname);
1827 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1828 mode_t mode)
1830 VFS_FIND(chmod);
1831 return handle->fns->chmod_fn(handle, path, mode);
1834 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1835 struct files_struct *fsp, mode_t mode)
1837 VFS_FIND(fchmod);
1838 return handle->fns->fchmod_fn(handle, fsp, mode);
1841 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1842 uid_t uid, gid_t gid)
1844 VFS_FIND(chown);
1845 return handle->fns->chown_fn(handle, path, uid, gid);
1848 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1849 struct files_struct *fsp, uid_t uid, gid_t gid)
1851 VFS_FIND(fchown);
1852 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1855 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1856 uid_t uid, gid_t gid)
1858 VFS_FIND(lchown);
1859 return handle->fns->lchown_fn(handle, path, uid, gid);
1862 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1864 int ret;
1865 bool as_root = false;
1866 const char *path;
1867 char *saved_dir = NULL;
1868 char *parent_dir = NULL;
1869 NTSTATUS status;
1871 if (fsp->fh->fd != -1) {
1872 /* Try fchown. */
1873 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1874 if (ret == 0) {
1875 return NT_STATUS_OK;
1877 if (ret == -1 && errno != ENOSYS) {
1878 return map_nt_error_from_unix(errno);
1882 as_root = (geteuid() == 0);
1884 if (as_root) {
1886 * We are being asked to chown as root. Make
1887 * sure we chdir() into the path to pin it,
1888 * and always act using lchown to ensure we
1889 * don't deref any symbolic links.
1891 const char *final_component = NULL;
1892 struct smb_filename local_fname;
1894 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1895 if (!saved_dir) {
1896 status = map_nt_error_from_unix(errno);
1897 DEBUG(0,("vfs_chown_fsp: failed to get "
1898 "current working directory. Error was %s\n",
1899 strerror(errno)));
1900 return status;
1903 if (!parent_dirname(talloc_tos(),
1904 fsp->fsp_name->base_name,
1905 &parent_dir,
1906 &final_component)) {
1907 return NT_STATUS_NO_MEMORY;
1910 /* cd into the parent dir to pin it. */
1911 ret = vfs_ChDir(fsp->conn, parent_dir);
1912 if (ret == -1) {
1913 return map_nt_error_from_unix(errno);
1916 ZERO_STRUCT(local_fname);
1917 local_fname.base_name = discard_const_p(char, final_component);
1919 /* Must use lstat here. */
1920 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1921 if (ret == -1) {
1922 status = map_nt_error_from_unix(errno);
1923 goto out;
1926 /* Ensure it matches the fsp stat. */
1927 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1928 status = NT_STATUS_ACCESS_DENIED;
1929 goto out;
1931 path = final_component;
1932 } else {
1933 path = fsp->fsp_name->base_name;
1936 if (fsp->posix_open || as_root) {
1937 ret = SMB_VFS_LCHOWN(fsp->conn,
1938 path,
1939 uid, gid);
1940 } else {
1941 ret = SMB_VFS_CHOWN(fsp->conn,
1942 path,
1943 uid, gid);
1946 if (ret == 0) {
1947 status = NT_STATUS_OK;
1948 } else {
1949 status = map_nt_error_from_unix(errno);
1952 out:
1954 if (as_root) {
1955 vfs_ChDir(fsp->conn,saved_dir);
1956 TALLOC_FREE(saved_dir);
1957 TALLOC_FREE(parent_dir);
1959 return status;
1962 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1964 VFS_FIND(chdir);
1965 return handle->fns->chdir_fn(handle, path);
1968 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
1970 VFS_FIND(getwd);
1971 return handle->fns->getwd_fn(handle);
1974 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
1975 const struct smb_filename *smb_fname,
1976 struct smb_file_time *ft)
1978 VFS_FIND(ntimes);
1979 return handle->fns->ntimes_fn(handle, smb_fname, ft);
1982 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
1983 struct files_struct *fsp, off_t offset)
1985 VFS_FIND(ftruncate);
1986 return handle->fns->ftruncate_fn(handle, fsp, offset);
1989 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
1990 struct files_struct *fsp,
1991 enum vfs_fallocate_mode mode,
1992 off_t offset,
1993 off_t len)
1995 VFS_FIND(fallocate);
1996 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
1999 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2000 struct files_struct *fsp, uint32 share_mode,
2001 uint32_t access_mask)
2003 VFS_FIND(kernel_flock);
2004 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2005 access_mask);
2008 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2009 struct files_struct *fsp, int leasetype)
2011 VFS_FIND(linux_setlease);
2012 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2015 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
2016 const char *newpath)
2018 VFS_FIND(symlink);
2019 return handle->fns->symlink_fn(handle, oldpath, newpath);
2022 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2023 const char *path, char *buf, size_t bufsiz)
2025 VFS_FIND(readlink);
2026 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
2029 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
2030 const char *newpath)
2032 VFS_FIND(link);
2033 return handle->fns->link_fn(handle, oldpath, newpath);
2036 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
2037 mode_t mode, SMB_DEV_T dev)
2039 VFS_FIND(mknod);
2040 return handle->fns->mknod_fn(handle, path, mode, dev);
2043 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
2045 VFS_FIND(realpath);
2046 return handle->fns->realpath_fn(handle, path);
2049 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
2050 struct sys_notify_context *ctx,
2051 const char *path,
2052 uint32_t *filter,
2053 uint32_t *subdir_filter,
2054 void (*callback)(struct sys_notify_context *ctx,
2055 void *private_data,
2056 struct notify_event *ev),
2057 void *private_data, void *handle_p)
2059 VFS_FIND(notify_watch);
2060 return handle->fns->notify_watch_fn(handle, ctx, path,
2061 filter, subdir_filter, callback,
2062 private_data, handle_p);
2065 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
2066 unsigned int flags)
2068 VFS_FIND(chflags);
2069 return handle->fns->chflags_fn(handle, path, flags);
2072 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2073 const SMB_STRUCT_STAT *sbuf)
2075 VFS_FIND(file_id_create);
2076 return handle->fns->file_id_create_fn(handle, sbuf);
2079 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2080 struct files_struct *fsp,
2081 const char *fname,
2082 TALLOC_CTX *mem_ctx,
2083 unsigned int *num_streams,
2084 struct stream_struct **streams)
2086 VFS_FIND(streaminfo);
2087 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
2088 num_streams, streams);
2091 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2092 const char *path, const char *name,
2093 TALLOC_CTX *mem_ctx, char **found_name)
2095 VFS_FIND(get_real_filename);
2096 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2097 found_name);
2100 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2101 const char *filename)
2103 VFS_FIND(connectpath);
2104 return handle->fns->connectpath_fn(handle, filename);
2107 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2108 struct files_struct *fsp,
2109 struct lock_struct *plock)
2111 VFS_FIND(strict_lock);
2112 return handle->fns->strict_lock_fn(handle, fsp, plock);
2115 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2116 struct files_struct *fsp,
2117 struct lock_struct *plock)
2119 VFS_FIND(strict_unlock);
2120 handle->fns->strict_unlock_fn(handle, fsp, plock);
2123 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2124 const char *name,
2125 enum vfs_translate_direction direction,
2126 TALLOC_CTX *mem_ctx,
2127 char **mapped_name)
2129 VFS_FIND(translate_name);
2130 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2131 mapped_name);
2134 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2135 struct files_struct *fsp,
2136 TALLOC_CTX *ctx,
2137 uint32_t function,
2138 uint16_t req_flags,
2139 const uint8_t *in_data,
2140 uint32_t in_len,
2141 uint8_t **out_data,
2142 uint32_t max_out_len,
2143 uint32_t *out_len)
2145 VFS_FIND(fsctl);
2146 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2147 in_data, in_len, out_data, max_out_len,
2148 out_len);
2151 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2152 struct files_struct *fsp,
2153 uint32 security_info,
2154 struct security_descriptor **ppdesc)
2156 VFS_FIND(fget_nt_acl);
2157 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2158 ppdesc);
2161 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2162 const char *name,
2163 uint32 security_info,
2164 struct security_descriptor **ppdesc)
2166 VFS_FIND(get_nt_acl);
2167 return handle->fns->get_nt_acl_fn(handle, name, security_info, ppdesc);
2170 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2171 struct files_struct *fsp,
2172 uint32 security_info_sent,
2173 const struct security_descriptor *psd)
2175 VFS_FIND(fset_nt_acl);
2176 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2177 psd);
2180 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2181 struct smb_filename *file,
2182 struct security_acl *sacl,
2183 uint32_t access_requested,
2184 uint32_t access_denied)
2186 VFS_FIND(audit_file);
2187 return handle->fns->audit_file_fn(handle,
2188 file,
2189 sacl,
2190 access_requested,
2191 access_denied);
2194 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2195 mode_t mode)
2197 VFS_FIND(chmod_acl);
2198 return handle->fns->chmod_acl_fn(handle, name, mode);
2201 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2202 struct files_struct *fsp, mode_t mode)
2204 VFS_FIND(fchmod_acl);
2205 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2208 int smb_vfs_call_sys_acl_get_entry(struct vfs_handle_struct *handle,
2209 SMB_ACL_T theacl, int entry_id,
2210 SMB_ACL_ENTRY_T *entry_p)
2212 VFS_FIND(sys_acl_get_entry);
2213 return handle->fns->sys_acl_get_entry_fn(handle, theacl, entry_id,
2214 entry_p);
2217 int smb_vfs_call_sys_acl_get_tag_type(struct vfs_handle_struct *handle,
2218 SMB_ACL_ENTRY_T entry_d,
2219 SMB_ACL_TAG_T *tag_type_p)
2221 VFS_FIND(sys_acl_get_tag_type);
2222 return handle->fns->sys_acl_get_tag_type_fn(handle, entry_d,
2223 tag_type_p);
2226 int smb_vfs_call_sys_acl_get_permset(struct vfs_handle_struct *handle,
2227 SMB_ACL_ENTRY_T entry_d,
2228 SMB_ACL_PERMSET_T *permset_p)
2230 VFS_FIND(sys_acl_get_permset);
2231 return handle->fns->sys_acl_get_permset_fn(handle, entry_d, permset_p);
2234 void * smb_vfs_call_sys_acl_get_qualifier(struct vfs_handle_struct *handle,
2235 SMB_ACL_ENTRY_T entry_d)
2237 VFS_FIND(sys_acl_get_qualifier);
2238 return handle->fns->sys_acl_get_qualifier_fn(handle, entry_d);
2241 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2242 const char *path_p,
2243 SMB_ACL_TYPE_T type)
2245 VFS_FIND(sys_acl_get_file);
2246 return handle->fns->sys_acl_get_file_fn(handle, path_p, type);
2249 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2250 struct files_struct *fsp)
2252 VFS_FIND(sys_acl_get_fd);
2253 return handle->fns->sys_acl_get_fd_fn(handle, fsp);
2256 int smb_vfs_call_sys_acl_clear_perms(struct vfs_handle_struct *handle,
2257 SMB_ACL_PERMSET_T permset)
2259 VFS_FIND(sys_acl_clear_perms);
2260 return handle->fns->sys_acl_clear_perms_fn(handle, permset);
2263 int smb_vfs_call_sys_acl_add_perm(struct vfs_handle_struct *handle,
2264 SMB_ACL_PERMSET_T permset,
2265 SMB_ACL_PERM_T perm)
2267 VFS_FIND(sys_acl_add_perm);
2268 return handle->fns->sys_acl_add_perm_fn(handle, permset, perm);
2271 char * smb_vfs_call_sys_acl_to_text(struct vfs_handle_struct *handle,
2272 SMB_ACL_T theacl, ssize_t *plen)
2274 VFS_FIND(sys_acl_to_text);
2275 return handle->fns->sys_acl_to_text_fn(handle, theacl, plen);
2278 SMB_ACL_T smb_vfs_call_sys_acl_init(struct vfs_handle_struct *handle,
2279 int count)
2281 VFS_FIND(sys_acl_init);
2282 return handle->fns->sys_acl_init_fn(handle, count);
2285 int smb_vfs_call_sys_acl_create_entry(struct vfs_handle_struct *handle,
2286 SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2288 VFS_FIND(sys_acl_create_entry);
2289 return handle->fns->sys_acl_create_entry_fn(handle, pacl, pentry);
2292 int smb_vfs_call_sys_acl_set_tag_type(struct vfs_handle_struct *handle,
2293 SMB_ACL_ENTRY_T entry,
2294 SMB_ACL_TAG_T tagtype)
2296 VFS_FIND(sys_acl_set_tag_type);
2297 return handle->fns->sys_acl_set_tag_type_fn(handle, entry, tagtype);
2300 int smb_vfs_call_sys_acl_set_qualifier(struct vfs_handle_struct *handle,
2301 SMB_ACL_ENTRY_T entry, void *qual)
2303 VFS_FIND(sys_acl_set_qualifier);
2304 return handle->fns->sys_acl_set_qualifier_fn(handle, entry, qual);
2307 int smb_vfs_call_sys_acl_set_permset(struct vfs_handle_struct *handle,
2308 SMB_ACL_ENTRY_T entry,
2309 SMB_ACL_PERMSET_T permset)
2311 VFS_FIND(sys_acl_set_permset);
2312 return handle->fns->sys_acl_set_permset_fn(handle, entry, permset);
2315 int smb_vfs_call_sys_acl_valid(struct vfs_handle_struct *handle,
2316 SMB_ACL_T theacl)
2318 VFS_FIND(sys_acl_valid);
2319 return handle->fns->sys_acl_valid_fn(handle, theacl);
2322 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2323 const char *name, SMB_ACL_TYPE_T acltype,
2324 SMB_ACL_T theacl)
2326 VFS_FIND(sys_acl_set_file);
2327 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2330 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2331 struct files_struct *fsp, SMB_ACL_T theacl)
2333 VFS_FIND(sys_acl_set_fd);
2334 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2337 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2338 const char *path)
2340 VFS_FIND(sys_acl_delete_def_file);
2341 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2344 int smb_vfs_call_sys_acl_get_perm(struct vfs_handle_struct *handle,
2345 SMB_ACL_PERMSET_T permset,
2346 SMB_ACL_PERM_T perm)
2348 VFS_FIND(sys_acl_get_perm);
2349 return handle->fns->sys_acl_get_perm_fn(handle, permset, perm);
2352 int smb_vfs_call_sys_acl_free_text(struct vfs_handle_struct *handle,
2353 char *text)
2355 VFS_FIND(sys_acl_free_text);
2356 return handle->fns->sys_acl_free_text_fn(handle, text);
2359 int smb_vfs_call_sys_acl_free_acl(struct vfs_handle_struct *handle,
2360 SMB_ACL_T posix_acl)
2362 VFS_FIND(sys_acl_free_acl);
2363 return handle->fns->sys_acl_free_acl_fn(handle, posix_acl);
2366 int smb_vfs_call_sys_acl_free_qualifier(struct vfs_handle_struct *handle,
2367 void *qualifier, SMB_ACL_TAG_T tagtype)
2369 VFS_FIND(sys_acl_free_qualifier);
2370 return handle->fns->sys_acl_free_qualifier_fn(handle, qualifier,
2371 tagtype);
2374 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2375 const char *path, const char *name, void *value,
2376 size_t size)
2378 VFS_FIND(getxattr);
2379 return handle->fns->getxattr_fn(handle, path, name, value, size);
2382 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2383 struct files_struct *fsp, const char *name,
2384 void *value, size_t size)
2386 VFS_FIND(fgetxattr);
2387 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2390 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2391 const char *path, char *list, size_t size)
2393 VFS_FIND(listxattr);
2394 return handle->fns->listxattr_fn(handle, path, list, size);
2397 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2398 struct files_struct *fsp, char *list,
2399 size_t size)
2401 VFS_FIND(flistxattr);
2402 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2405 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2406 const char *path, const char *name)
2408 VFS_FIND(removexattr);
2409 return handle->fns->removexattr_fn(handle, path, name);
2412 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2413 struct files_struct *fsp, const char *name)
2415 VFS_FIND(fremovexattr);
2416 return handle->fns->fremovexattr_fn(handle, fsp, name);
2419 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2420 const char *name, const void *value, size_t size,
2421 int flags)
2423 VFS_FIND(setxattr);
2424 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2427 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2428 struct files_struct *fsp, const char *name,
2429 const void *value, size_t size, int flags)
2431 VFS_FIND(fsetxattr);
2432 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2435 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2436 struct files_struct *fsp)
2438 VFS_FIND(aio_force);
2439 return handle->fns->aio_force_fn(handle, fsp);
2442 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2443 const struct smb_filename *fname,
2444 SMB_STRUCT_STAT *sbuf)
2446 VFS_FIND(is_offline);
2447 return handle->fns->is_offline_fn(handle, fname, sbuf);
2450 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2451 const struct smb_filename *fname)
2453 VFS_FIND(set_offline);
2454 return handle->fns->set_offline_fn(handle, fname);