s3:smbXsrv_open: add smbXsrv_open_global_traverse()
[Samba/gbeck.git] / source3 / smbd / vfs.c
blobb81e8ded3f9c679e093d57723dc64df0e048ac20
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);
332 /* No need to load vfs modules for printer connections */
333 if (conn->printer) {
334 return True;
337 vfs_objects = lp_vfs_objects(SNUM(conn));
339 /* Override VFS functions if 'vfs object' was not specified*/
340 if (!vfs_objects || !vfs_objects[0])
341 return True;
343 for (i=0; vfs_objects[i] ;) {
344 i++;
347 for (j=i-1; j >= 0; j--) {
348 if (!vfs_init_custom(conn, vfs_objects[j])) {
349 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
350 return False;
353 return True;
356 /*******************************************************************
357 Check if a file exists in the vfs.
358 ********************************************************************/
360 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
362 /* Only return OK if stat was successful and S_ISREG */
363 if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
364 S_ISREG(smb_fname->st.st_ex_mode)) {
365 return NT_STATUS_OK;
368 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
371 /****************************************************************************
372 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
373 ****************************************************************************/
375 ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
377 size_t total=0;
379 while (total < byte_count)
381 ssize_t ret = SMB_VFS_READ(fsp, buf + total,
382 byte_count - total);
384 if (ret == 0) return total;
385 if (ret == -1) {
386 if (errno == EINTR)
387 continue;
388 else
389 return -1;
391 total += ret;
393 return (ssize_t)total;
396 ssize_t vfs_pread_data(files_struct *fsp, char *buf,
397 size_t byte_count, off_t offset)
399 size_t total=0;
401 while (total < byte_count)
403 ssize_t ret = SMB_VFS_PREAD(fsp, buf + total,
404 byte_count - total, offset + total);
406 if (ret == 0) return total;
407 if (ret == -1) {
408 if (errno == EINTR)
409 continue;
410 else
411 return -1;
413 total += ret;
415 return (ssize_t)total;
418 /****************************************************************************
419 Write data to a fd on the vfs.
420 ****************************************************************************/
422 ssize_t vfs_write_data(struct smb_request *req,
423 files_struct *fsp,
424 const char *buffer,
425 size_t N)
427 size_t total=0;
428 ssize_t ret;
430 if (req && req->unread_bytes) {
431 SMB_ASSERT(req->unread_bytes == N);
432 /* VFS_RECVFILE must drain the socket
433 * before returning. */
434 req->unread_bytes = 0;
435 return SMB_VFS_RECVFILE(req->sconn->sock,
436 fsp,
437 (off_t)-1,
441 while (total < N) {
442 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
444 if (ret == -1)
445 return -1;
446 if (ret == 0)
447 return total;
449 total += ret;
451 return (ssize_t)total;
454 ssize_t vfs_pwrite_data(struct smb_request *req,
455 files_struct *fsp,
456 const char *buffer,
457 size_t N,
458 off_t offset)
460 size_t total=0;
461 ssize_t ret;
463 if (req && req->unread_bytes) {
464 SMB_ASSERT(req->unread_bytes == N);
465 /* VFS_RECVFILE must drain the socket
466 * before returning. */
467 req->unread_bytes = 0;
468 return SMB_VFS_RECVFILE(req->sconn->sock,
469 fsp,
470 offset,
474 while (total < N) {
475 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
476 offset + total);
478 if (ret == -1)
479 return -1;
480 if (ret == 0)
481 return total;
483 total += ret;
485 return (ssize_t)total;
487 /****************************************************************************
488 An allocate file space call using the vfs interface.
489 Allocates space for a file from a filedescriptor.
490 Returns 0 on success, -1 on failure.
491 ****************************************************************************/
493 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
495 int ret;
496 connection_struct *conn = fsp->conn;
497 uint64_t space_avail;
498 uint64_t bsize,dfree,dsize;
499 NTSTATUS status;
502 * Actually try and commit the space on disk....
505 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
506 fsp_str_dbg(fsp), (double)len));
508 if (((off_t)len) < 0) {
509 DEBUG(0,("vfs_allocate_file_space: %s negative len "
510 "requested.\n", fsp_str_dbg(fsp)));
511 errno = EINVAL;
512 return -1;
515 status = vfs_stat_fsp(fsp);
516 if (!NT_STATUS_IS_OK(status)) {
517 return -1;
520 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
521 return 0;
523 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
524 /* Shrink - use ftruncate. */
526 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
527 "size %.0f\n", fsp_str_dbg(fsp),
528 (double)fsp->fsp_name->st.st_ex_size));
530 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
532 flush_write_cache(fsp, SIZECHANGE_FLUSH);
533 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
534 set_filelen_write_cache(fsp, len);
537 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
539 return ret;
542 if (!lp_strict_allocate(SNUM(fsp->conn)))
543 return 0;
545 /* Grow - we need to test if we have enough space. */
547 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
549 /* See if we have a syscall that will allocate beyond end-of-file
550 without changing EOF. */
551 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
553 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
555 if (ret == 0) {
556 /* We changed the allocation size on disk, but not
557 EOF - exactly as required. We're done ! */
558 return 0;
561 len -= fsp->fsp_name->st.st_ex_size;
562 len /= 1024; /* Len is now number of 1k blocks needed. */
563 space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
564 &bsize, &dfree, &dsize);
565 if (space_avail == (uint64_t)-1) {
566 return -1;
569 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
570 "needed blocks = %.0f, space avail = %.0f\n",
571 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
572 (double)space_avail));
574 if (len > space_avail) {
575 errno = ENOSPC;
576 return -1;
579 return 0;
582 /****************************************************************************
583 A vfs set_filelen call.
584 set the length of a file from a filedescriptor.
585 Returns 0 on success, -1 on failure.
586 ****************************************************************************/
588 int vfs_set_filelen(files_struct *fsp, off_t len)
590 int ret;
592 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
594 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
595 fsp_str_dbg(fsp), (double)len));
596 flush_write_cache(fsp, SIZECHANGE_FLUSH);
597 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
598 set_filelen_write_cache(fsp, len);
599 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
600 FILE_NOTIFY_CHANGE_SIZE
601 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
602 fsp->fsp_name->base_name);
605 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
607 return ret;
610 /****************************************************************************
611 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
612 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
613 as this is also called from the default SMB_VFS_FTRUNCATE code.
614 Always extends the file size.
615 Returns 0 on success, errno on failure.
616 ****************************************************************************/
618 #define SPARSE_BUF_WRITE_SIZE (32*1024)
620 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
622 ssize_t pwrite_ret;
623 size_t total = 0;
625 if (!sparse_buf) {
626 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
627 if (!sparse_buf) {
628 errno = ENOMEM;
629 return ENOMEM;
633 while (total < len) {
634 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
636 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
637 if (pwrite_ret == -1) {
638 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
639 "%s failed with error %s\n",
640 fsp_str_dbg(fsp), strerror(errno)));
641 return errno;
643 total += pwrite_ret;
646 return 0;
649 /****************************************************************************
650 A vfs fill sparse call.
651 Writes zeros from the end of file to len, if len is greater than EOF.
652 Used only by strict_sync.
653 Returns 0 on success, -1 on failure.
654 ****************************************************************************/
656 int vfs_fill_sparse(files_struct *fsp, off_t len)
658 int ret;
659 NTSTATUS status;
660 off_t offset;
661 size_t num_to_write;
663 status = vfs_stat_fsp(fsp);
664 if (!NT_STATUS_IS_OK(status)) {
665 return -1;
668 if (len <= fsp->fsp_name->st.st_ex_size) {
669 return 0;
672 #ifdef S_ISFIFO
673 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
674 return 0;
676 #endif
678 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
679 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
680 (double)fsp->fsp_name->st.st_ex_size, (double)len,
681 (double)(len - fsp->fsp_name->st.st_ex_size)));
683 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
685 flush_write_cache(fsp, SIZECHANGE_FLUSH);
687 offset = fsp->fsp_name->st.st_ex_size;
688 num_to_write = len - fsp->fsp_name->st.st_ex_size;
690 /* Only do this on non-stream file handles. */
691 if (fsp->base_fsp == NULL) {
692 /* for allocation try fallocate first. This can fail on some
693 * platforms e.g. when the filesystem doesn't support it and no
694 * emulation is being done by the libc (like on AIX with JFS1). In that
695 * case we do our own emulation. fallocate implementations can
696 * return ENOTSUP or EINVAL in cases like that. */
697 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
698 offset, num_to_write);
699 if (ret == ENOSPC) {
700 errno = ENOSPC;
701 ret = -1;
702 goto out;
704 if (ret == 0) {
705 goto out;
707 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
708 "error %d. Falling back to slow manual allocation\n", ret));
711 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
712 if (ret != 0) {
713 errno = ret;
714 ret = -1;
717 out:
719 if (ret == 0) {
720 set_filelen_write_cache(fsp, len);
723 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
724 return ret;
727 /****************************************************************************
728 Transfer some data (n bytes) between two file_struct's.
729 ****************************************************************************/
731 static ssize_t vfs_read_fn(void *file, void *buf, size_t len)
733 struct files_struct *fsp = (struct files_struct *)file;
735 return SMB_VFS_READ(fsp, buf, len);
738 static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
740 struct files_struct *fsp = (struct files_struct *)file;
742 return SMB_VFS_WRITE(fsp, buf, len);
745 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
747 return transfer_file_internal((void *)in, (void *)out, n,
748 vfs_read_fn, vfs_write_fn);
751 /*******************************************************************
752 A vfs_readdir wrapper which just returns the file name.
753 ********************************************************************/
755 const char *vfs_readdirname(connection_struct *conn, void *p,
756 SMB_STRUCT_STAT *sbuf, char **talloced)
758 struct dirent *ptr= NULL;
759 const char *dname;
760 char *translated;
761 NTSTATUS status;
763 if (!p)
764 return(NULL);
766 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
767 if (!ptr)
768 return(NULL);
770 dname = ptr->d_name;
773 #ifdef NEXT2
774 if (telldir(p) < 0)
775 return(NULL);
776 #endif
778 #ifdef HAVE_BROKEN_READDIR_NAME
779 /* using /usr/ucb/cc is BAD */
780 dname = dname - 2;
781 #endif
783 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
784 talloc_tos(), &translated);
785 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
786 *talloced = NULL;
787 return dname;
789 *talloced = translated;
790 if (!NT_STATUS_IS_OK(status)) {
791 return NULL;
793 return translated;
796 /*******************************************************************
797 A wrapper for vfs_chdir().
798 ********************************************************************/
800 int vfs_ChDir(connection_struct *conn, const char *path)
802 int ret;
804 if (!LastDir) {
805 LastDir = SMB_STRDUP("");
808 if (strcsequal(path,".")) {
809 return 0;
812 if (*path == '/' && strcsequal(LastDir,path)) {
813 return 0;
816 DEBUG(4,("vfs_ChDir to %s\n",path));
818 ret = SMB_VFS_CHDIR(conn,path);
819 if (ret == 0) {
820 /* Global cache. */
821 SAFE_FREE(LastDir);
822 LastDir = SMB_STRDUP(path);
824 /* conn cache. */
825 TALLOC_FREE(conn->cwd);
826 conn->cwd = vfs_GetWd(conn, conn);
827 DEBUG(4,("vfs_ChDir got %s\n",conn->cwd));
829 return ret;
832 /*******************************************************************
833 Return the absolute current directory path - given a UNIX pathname.
834 Note that this path is returned in DOS format, not UNIX
835 format. Note this can be called with conn == NULL.
836 ********************************************************************/
838 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
840 char *current_dir = NULL;
841 char *result = NULL;
842 DATA_BLOB cache_value;
843 struct file_id key;
844 struct smb_filename *smb_fname_dot = NULL;
845 struct smb_filename *smb_fname_full = NULL;
846 NTSTATUS status;
848 if (!lp_getwd_cache()) {
849 goto nocache;
852 status = create_synthetic_smb_fname(ctx, ".", NULL, NULL,
853 &smb_fname_dot);
854 if (!NT_STATUS_IS_OK(status)) {
855 errno = map_errno_from_nt_status(status);
856 goto out;
859 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
861 * Known to fail for root: the directory may be NFS-mounted
862 * and exported with root_squash (so has no root access).
864 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
865 "(NFS problem ?)\n", strerror(errno) ));
866 goto nocache;
869 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
871 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
872 data_blob_const(&key, sizeof(key)),
873 &cache_value)) {
874 goto nocache;
877 SMB_ASSERT((cache_value.length > 0)
878 && (cache_value.data[cache_value.length-1] == '\0'));
880 status = create_synthetic_smb_fname(ctx, (char *)cache_value.data,
881 NULL, NULL, &smb_fname_full);
882 if (!NT_STATUS_IS_OK(status)) {
883 errno = map_errno_from_nt_status(status);
884 goto out;
887 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
888 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
889 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
890 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
892 * Ok, we're done
894 result = talloc_strdup(ctx, smb_fname_full->base_name);
895 if (result == NULL) {
896 errno = ENOMEM;
898 goto out;
901 nocache:
904 * We don't have the information to hand so rely on traditional
905 * methods. The very slow getcwd, which spawns a process on some
906 * systems, or the not quite so bad getwd.
909 current_dir = SMB_VFS_GETWD(conn);
910 if (current_dir == NULL) {
911 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
912 strerror(errno)));
913 goto out;
916 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
917 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
919 memcache_add(smbd_memcache(), GETWD_CACHE,
920 data_blob_const(&key, sizeof(key)),
921 data_blob_const(current_dir,
922 strlen(current_dir)+1));
925 result = talloc_strdup(ctx, current_dir);
926 if (result == NULL) {
927 errno = ENOMEM;
930 out:
931 TALLOC_FREE(smb_fname_dot);
932 TALLOC_FREE(smb_fname_full);
933 SAFE_FREE(current_dir);
934 return result;
937 /*******************************************************************
938 Reduce a file name, removing .. elements and checking that
939 it is below dir in the heirachy. This uses realpath.
940 This function must run as root, and will return names
941 and valid stat structs that can be checked on open.
942 ********************************************************************/
944 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
945 const char *fname,
946 struct smb_request *smbreq)
948 NTSTATUS status;
949 TALLOC_CTX *ctx = talloc_tos();
950 const char *conn_rootdir;
951 size_t rootdir_len;
952 char *dir_name = NULL;
953 const char *last_component = NULL;
954 char *resolved_name = NULL;
955 char *saved_dir = NULL;
956 struct smb_filename *smb_fname_cwd = NULL;
957 struct privilege_paths *priv_paths = NULL;
958 int ret;
960 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
961 fname,
962 conn->connectpath));
965 priv_paths = talloc_zero(smbreq, struct privilege_paths);
966 if (!priv_paths) {
967 status = NT_STATUS_NO_MEMORY;
968 goto err;
971 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
972 status = NT_STATUS_NO_MEMORY;
973 goto err;
976 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
977 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
979 if (priv_paths->parent_name.base_name == NULL ||
980 priv_paths->file_name.base_name == NULL) {
981 status = NT_STATUS_NO_MEMORY;
982 goto err;
985 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
986 status = map_nt_error_from_unix(errno);
987 goto err;
989 /* Remember where we were. */
990 saved_dir = vfs_GetWd(ctx, conn);
991 if (!saved_dir) {
992 status = map_nt_error_from_unix(errno);
993 goto err;
996 /* Go to the parent directory to lock in memory. */
997 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
998 status = map_nt_error_from_unix(errno);
999 goto err;
1002 /* Get the absolute path of the parent directory. */
1003 resolved_name = SMB_VFS_REALPATH(conn,".");
1004 if (!resolved_name) {
1005 status = map_nt_error_from_unix(errno);
1006 goto err;
1009 if (*resolved_name != '/') {
1010 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1011 "doesn't return absolute paths !\n"));
1012 status = NT_STATUS_OBJECT_NAME_INVALID;
1013 goto err;
1016 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1017 priv_paths->parent_name.base_name,
1018 resolved_name));
1020 /* Now check the stat value is the same. */
1021 status = create_synthetic_smb_fname(talloc_tos(), ".",
1022 NULL, NULL,
1023 &smb_fname_cwd);
1024 if (!NT_STATUS_IS_OK(status)) {
1025 goto err;
1028 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1029 status = map_nt_error_from_unix(errno);
1030 goto err;
1033 /* Ensure we're pointing at the same place. */
1034 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1035 DEBUG(0,("check_reduced_name_with_privilege: "
1036 "device/inode/uid/gid on directory %s changed. "
1037 "Denying access !\n",
1038 priv_paths->parent_name.base_name));
1039 status = NT_STATUS_ACCESS_DENIED;
1040 goto err;
1043 /* Ensure we're below the connect path. */
1045 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1046 if (conn_rootdir == NULL) {
1047 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1048 "conn_rootdir\n"));
1049 status = NT_STATUS_ACCESS_DENIED;
1050 goto err;
1053 rootdir_len = strlen(conn_rootdir);
1054 if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1055 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1056 "attempt: %s is a symlink outside the "
1057 "share path\n",
1058 dir_name));
1059 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1060 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1061 status = NT_STATUS_ACCESS_DENIED;
1062 goto err;
1065 /* Now ensure that the last component either doesn't
1066 exist, or is *NOT* a symlink. */
1068 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1069 if (ret == -1) {
1070 /* Errno must be ENOENT for this be ok. */
1071 if (errno != ENOENT) {
1072 status = map_nt_error_from_unix(errno);
1073 DEBUG(2, ("check_reduced_name_with_privilege: "
1074 "LSTAT on %s failed with %s\n",
1075 priv_paths->file_name.base_name,
1076 nt_errstr(status)));
1077 goto err;
1081 if (VALID_STAT(priv_paths->file_name.st) &&
1082 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1083 DEBUG(2, ("check_reduced_name_with_privilege: "
1084 "Last component %s is a symlink. Denying"
1085 "access.\n",
1086 priv_paths->file_name.base_name));
1087 status = NT_STATUS_ACCESS_DENIED;
1088 goto err;
1091 smbreq->priv_paths = priv_paths;
1092 status = NT_STATUS_OK;
1094 err:
1096 if (saved_dir) {
1097 vfs_ChDir(conn, saved_dir);
1099 SAFE_FREE(resolved_name);
1100 if (!NT_STATUS_IS_OK(status)) {
1101 TALLOC_FREE(priv_paths);
1103 TALLOC_FREE(dir_name);
1104 return status;
1107 /*******************************************************************
1108 Reduce a file name, removing .. elements and checking that
1109 it is below dir in the heirachy. This uses realpath.
1110 ********************************************************************/
1112 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1114 char *resolved_name = NULL;
1115 bool allow_symlinks = true;
1116 bool allow_widelinks = false;
1118 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1120 resolved_name = SMB_VFS_REALPATH(conn,fname);
1122 if (!resolved_name) {
1123 switch (errno) {
1124 case ENOTDIR:
1125 DEBUG(3,("check_reduced_name: Component not a "
1126 "directory in getting realpath for "
1127 "%s\n", fname));
1128 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1129 case ENOENT:
1131 TALLOC_CTX *ctx = talloc_tos();
1132 char *dir_name = NULL;
1133 const char *last_component = NULL;
1134 char *new_name = NULL;
1135 int ret;
1137 /* Last component didn't exist.
1138 Remove it and try and canonicalise
1139 the directory name. */
1140 if (!parent_dirname(ctx, fname,
1141 &dir_name,
1142 &last_component)) {
1143 return NT_STATUS_NO_MEMORY;
1146 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1147 if (!resolved_name) {
1148 NTSTATUS status = map_nt_error_from_unix(errno);
1150 if (errno == ENOENT || errno == ENOTDIR) {
1151 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1154 DEBUG(3,("check_reduce_name: "
1155 "couldn't get realpath for "
1156 "%s (%s)\n",
1157 fname,
1158 nt_errstr(status)));
1159 return status;
1161 ret = asprintf(&new_name, "%s/%s",
1162 resolved_name, last_component);
1163 SAFE_FREE(resolved_name);
1164 if (ret == -1) {
1165 return NT_STATUS_NO_MEMORY;
1167 resolved_name = new_name;
1168 break;
1170 default:
1171 DEBUG(3,("check_reduced_name: couldn't get "
1172 "realpath for %s\n", fname));
1173 return map_nt_error_from_unix(errno);
1177 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1178 resolved_name));
1180 if (*resolved_name != '/') {
1181 DEBUG(0,("check_reduced_name: realpath doesn't return "
1182 "absolute paths !\n"));
1183 SAFE_FREE(resolved_name);
1184 return NT_STATUS_OBJECT_NAME_INVALID;
1187 allow_widelinks = lp_widelinks(SNUM(conn));
1188 allow_symlinks = lp_symlinks(SNUM(conn));
1190 /* Common widelinks and symlinks checks. */
1191 if (!allow_widelinks || !allow_symlinks) {
1192 const char *conn_rootdir;
1193 size_t rootdir_len;
1195 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1196 if (conn_rootdir == NULL) {
1197 DEBUG(2, ("check_reduced_name: Could not get "
1198 "conn_rootdir\n"));
1199 SAFE_FREE(resolved_name);
1200 return NT_STATUS_ACCESS_DENIED;
1203 rootdir_len = strlen(conn_rootdir);
1204 if (strncmp(conn_rootdir, resolved_name,
1205 rootdir_len) != 0) {
1206 DEBUG(2, ("check_reduced_name: Bad access "
1207 "attempt: %s is a symlink outside the "
1208 "share path\n", fname));
1209 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1210 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1211 SAFE_FREE(resolved_name);
1212 return NT_STATUS_ACCESS_DENIED;
1215 /* Extra checks if all symlinks are disallowed. */
1216 if (!allow_symlinks) {
1217 /* fname can't have changed in resolved_path. */
1218 const char *p = &resolved_name[rootdir_len];
1220 /* *p can be '\0' if fname was "." */
1221 if (*p == '\0' && ISDOT(fname)) {
1222 goto out;
1225 if (*p != '/') {
1226 DEBUG(2, ("check_reduced_name: logic error (%c) "
1227 "in resolved_name: %s\n",
1229 fname));
1230 SAFE_FREE(resolved_name);
1231 return NT_STATUS_ACCESS_DENIED;
1234 p++;
1235 if (strcmp(fname, p)!=0) {
1236 DEBUG(2, ("check_reduced_name: Bad access "
1237 "attempt: %s is a symlink to %s\n",
1238 fname, p));
1239 SAFE_FREE(resolved_name);
1240 return NT_STATUS_ACCESS_DENIED;
1245 out:
1247 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1248 resolved_name));
1249 SAFE_FREE(resolved_name);
1250 return NT_STATUS_OK;
1254 * XXX: This is temporary and there should be no callers of this once
1255 * smb_filename is plumbed through all path based operations.
1257 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1258 SMB_STRUCT_STAT *psbuf)
1260 struct smb_filename *smb_fname = NULL;
1261 NTSTATUS status;
1262 int ret;
1264 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1265 &smb_fname);
1266 if (!NT_STATUS_IS_OK(status)) {
1267 errno = map_errno_from_nt_status(status);
1268 return -1;
1271 if (lp_posix_pathnames()) {
1272 ret = SMB_VFS_LSTAT(conn, smb_fname);
1273 } else {
1274 ret = SMB_VFS_STAT(conn, smb_fname);
1277 if (ret != -1) {
1278 *psbuf = smb_fname->st;
1281 TALLOC_FREE(smb_fname);
1282 return ret;
1286 * XXX: This is temporary and there should be no callers of this once
1287 * smb_filename is plumbed through all path based operations.
1289 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1290 SMB_STRUCT_STAT *psbuf)
1292 struct smb_filename *smb_fname = NULL;
1293 NTSTATUS status;
1294 int ret;
1296 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1297 &smb_fname);
1298 if (!NT_STATUS_IS_OK(status)) {
1299 errno = map_errno_from_nt_status(status);
1300 return -1;
1303 ret = SMB_VFS_LSTAT(conn, smb_fname);
1304 if (ret != -1) {
1305 *psbuf = smb_fname->st;
1308 TALLOC_FREE(smb_fname);
1309 return ret;
1313 * Ensure LSTAT is called for POSIX paths.
1316 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1318 int ret;
1320 if(fsp->fh->fd == -1) {
1321 if (fsp->posix_open) {
1322 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1323 } else {
1324 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1326 if (ret == -1) {
1327 return map_nt_error_from_unix(errno);
1329 } else {
1330 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1331 return map_nt_error_from_unix(errno);
1334 return NT_STATUS_OK;
1338 * Initialize num_streams and streams, then call VFS op streaminfo
1340 NTSTATUS vfs_streaminfo(connection_struct *conn,
1341 struct files_struct *fsp,
1342 const char *fname,
1343 TALLOC_CTX *mem_ctx,
1344 unsigned int *num_streams,
1345 struct stream_struct **streams)
1347 *num_streams = 0;
1348 *streams = NULL;
1349 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1353 generate a file_id from a stat structure
1355 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1357 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1360 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1361 const char *service, const char *user)
1363 VFS_FIND(connect);
1364 return handle->fns->connect_fn(handle, service, user);
1367 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1369 VFS_FIND(disconnect);
1370 handle->fns->disconnect_fn(handle);
1373 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1374 const char *path, bool small_query,
1375 uint64_t *bsize, uint64_t *dfree,
1376 uint64_t *dsize)
1378 VFS_FIND(disk_free);
1379 return handle->fns->disk_free_fn(handle, path, small_query, bsize,
1380 dfree, dsize);
1383 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1384 enum SMB_QUOTA_TYPE qtype, unid_t id,
1385 SMB_DISK_QUOTA *qt)
1387 VFS_FIND(get_quota);
1388 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1391 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1392 enum SMB_QUOTA_TYPE qtype, unid_t id,
1393 SMB_DISK_QUOTA *qt)
1395 VFS_FIND(set_quota);
1396 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1399 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1400 struct files_struct *fsp,
1401 struct shadow_copy_data *shadow_copy_data,
1402 bool labels)
1404 VFS_FIND(get_shadow_copy_data);
1405 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1406 shadow_copy_data,
1407 labels);
1409 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1410 struct vfs_statvfs_struct *statbuf)
1412 VFS_FIND(statvfs);
1413 return handle->fns->statvfs_fn(handle, path, statbuf);
1416 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1417 enum timestamp_set_resolution *p_ts_res)
1419 VFS_FIND(fs_capabilities);
1420 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1423 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1424 struct dfs_GetDFSReferral *r)
1426 VFS_FIND(get_dfs_referrals);
1427 return handle->fns->get_dfs_referrals_fn(handle, r);
1430 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1431 const char *fname, const char *mask,
1432 uint32 attributes)
1434 VFS_FIND(opendir);
1435 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1438 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1439 struct files_struct *fsp,
1440 const char *mask,
1441 uint32 attributes)
1443 VFS_FIND(fdopendir);
1444 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1447 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1448 DIR *dirp,
1449 SMB_STRUCT_STAT *sbuf)
1451 VFS_FIND(readdir);
1452 return handle->fns->readdir_fn(handle, dirp, sbuf);
1455 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1456 DIR *dirp, long offset)
1458 VFS_FIND(seekdir);
1459 handle->fns->seekdir_fn(handle, dirp, offset);
1462 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1463 DIR *dirp)
1465 VFS_FIND(telldir);
1466 return handle->fns->telldir_fn(handle, dirp);
1469 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1470 DIR *dirp)
1472 VFS_FIND(rewind_dir);
1473 handle->fns->rewind_dir_fn(handle, dirp);
1476 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1477 mode_t mode)
1479 VFS_FIND(mkdir);
1480 return handle->fns->mkdir_fn(handle, path, mode);
1483 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1485 VFS_FIND(rmdir);
1486 return handle->fns->rmdir_fn(handle, path);
1489 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1490 DIR *dir)
1492 VFS_FIND(closedir);
1493 return handle->fns->closedir_fn(handle, dir);
1496 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1497 DIR *dirp)
1499 VFS_FIND(init_search_op);
1500 handle->fns->init_search_op_fn(handle, dirp);
1503 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1504 struct smb_filename *smb_fname, struct files_struct *fsp,
1505 int flags, mode_t mode)
1507 VFS_FIND(open);
1508 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1511 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1512 struct smb_request *req,
1513 uint16_t root_dir_fid,
1514 struct smb_filename *smb_fname,
1515 uint32_t access_mask,
1516 uint32_t share_access,
1517 uint32_t create_disposition,
1518 uint32_t create_options,
1519 uint32_t file_attributes,
1520 uint32_t oplock_request,
1521 uint64_t allocation_size,
1522 uint32_t private_flags,
1523 struct security_descriptor *sd,
1524 struct ea_list *ea_list,
1525 files_struct **result,
1526 int *pinfo)
1528 VFS_FIND(create_file);
1529 return handle->fns->create_file_fn(
1530 handle, req, root_dir_fid, smb_fname, access_mask,
1531 share_access, create_disposition, create_options,
1532 file_attributes, oplock_request, allocation_size,
1533 private_flags, sd, ea_list,
1534 result, pinfo);
1537 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1538 struct files_struct *fsp)
1540 VFS_FIND(close);
1541 return handle->fns->close_fn(handle, fsp);
1544 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1545 struct files_struct *fsp, void *data, size_t n)
1547 VFS_FIND(read);
1548 return handle->fns->read_fn(handle, fsp, data, n);
1551 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1552 struct files_struct *fsp, void *data, size_t n,
1553 off_t offset)
1555 VFS_FIND(pread);
1556 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1559 struct smb_vfs_call_pread_state {
1560 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1561 ssize_t retval;
1564 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1566 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1567 TALLOC_CTX *mem_ctx,
1568 struct tevent_context *ev,
1569 struct files_struct *fsp,
1570 void *data,
1571 size_t n, off_t offset)
1573 struct tevent_req *req, *subreq;
1574 struct smb_vfs_call_pread_state *state;
1576 req = tevent_req_create(mem_ctx, &state,
1577 struct smb_vfs_call_pread_state);
1578 if (req == NULL) {
1579 return NULL;
1581 VFS_FIND(pread_send);
1582 state->recv_fn = handle->fns->pread_recv_fn;
1584 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1585 offset);
1586 if (tevent_req_nomem(subreq, req)) {
1587 return tevent_req_post(req, ev);
1589 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1590 return req;
1593 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1595 struct tevent_req *req = tevent_req_callback_data(
1596 subreq, struct tevent_req);
1597 struct smb_vfs_call_pread_state *state = tevent_req_data(
1598 req, struct smb_vfs_call_pread_state);
1599 int err;
1601 state->retval = state->recv_fn(subreq, &err);
1602 TALLOC_FREE(subreq);
1603 if (state->retval == -1) {
1604 tevent_req_error(req, err);
1605 return;
1607 tevent_req_done(req);
1610 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req, int *perrno)
1612 struct smb_vfs_call_pread_state *state = tevent_req_data(
1613 req, struct smb_vfs_call_pread_state);
1614 int err;
1616 if (tevent_req_is_unix_error(req, &err)) {
1617 *perrno = err;
1618 return -1;
1620 return state->retval;
1623 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1624 struct files_struct *fsp, const void *data,
1625 size_t n)
1627 VFS_FIND(write);
1628 return handle->fns->write_fn(handle, fsp, data, n);
1631 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1632 struct files_struct *fsp, const void *data,
1633 size_t n, off_t offset)
1635 VFS_FIND(pwrite);
1636 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1639 struct smb_vfs_call_pwrite_state {
1640 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1641 ssize_t retval;
1644 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1646 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1647 TALLOC_CTX *mem_ctx,
1648 struct tevent_context *ev,
1649 struct files_struct *fsp,
1650 const void *data,
1651 size_t n, off_t offset)
1653 struct tevent_req *req, *subreq;
1654 struct smb_vfs_call_pwrite_state *state;
1656 req = tevent_req_create(mem_ctx, &state,
1657 struct smb_vfs_call_pwrite_state);
1658 if (req == NULL) {
1659 return NULL;
1661 VFS_FIND(pwrite_send);
1662 state->recv_fn = handle->fns->pwrite_recv_fn;
1664 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1665 offset);
1666 if (tevent_req_nomem(subreq, req)) {
1667 return tevent_req_post(req, ev);
1669 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1670 return req;
1673 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1675 struct tevent_req *req = tevent_req_callback_data(
1676 subreq, struct tevent_req);
1677 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1678 req, struct smb_vfs_call_pwrite_state);
1679 int err;
1681 state->retval = state->recv_fn(subreq, &err);
1682 TALLOC_FREE(subreq);
1683 if (state->retval == -1) {
1684 tevent_req_error(req, err);
1685 return;
1687 tevent_req_done(req);
1690 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req, int *perrno)
1692 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1693 req, struct smb_vfs_call_pwrite_state);
1694 int err;
1696 if (tevent_req_is_unix_error(req, &err)) {
1697 *perrno = err;
1698 return -1;
1700 return state->retval;
1703 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1704 struct files_struct *fsp, off_t offset,
1705 int whence)
1707 VFS_FIND(lseek);
1708 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1711 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1712 files_struct *fromfsp, const DATA_BLOB *header,
1713 off_t offset, size_t count)
1715 VFS_FIND(sendfile);
1716 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1717 count);
1720 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1721 files_struct *tofsp, off_t offset,
1722 size_t count)
1724 VFS_FIND(recvfile);
1725 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1728 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1729 const struct smb_filename *smb_fname_src,
1730 const struct smb_filename *smb_fname_dst)
1732 VFS_FIND(rename);
1733 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1736 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1737 struct files_struct *fsp)
1739 VFS_FIND(fsync);
1740 return handle->fns->fsync_fn(handle, fsp);
1743 struct smb_vfs_call_fsync_state {
1744 int (*recv_fn)(struct tevent_req *req, int *err);
1745 int retval;
1748 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1750 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1751 TALLOC_CTX *mem_ctx,
1752 struct tevent_context *ev,
1753 struct files_struct *fsp)
1755 struct tevent_req *req, *subreq;
1756 struct smb_vfs_call_fsync_state *state;
1758 req = tevent_req_create(mem_ctx, &state,
1759 struct smb_vfs_call_fsync_state);
1760 if (req == NULL) {
1761 return NULL;
1763 VFS_FIND(fsync_send);
1764 state->recv_fn = handle->fns->fsync_recv_fn;
1766 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1767 if (tevent_req_nomem(subreq, req)) {
1768 return tevent_req_post(req, ev);
1770 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1771 return req;
1774 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1776 struct tevent_req *req = tevent_req_callback_data(
1777 subreq, struct tevent_req);
1778 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1779 req, struct smb_vfs_call_fsync_state);
1780 int err;
1782 state->retval = state->recv_fn(subreq, &err);
1783 TALLOC_FREE(subreq);
1784 if (state->retval == -1) {
1785 tevent_req_error(req, err);
1786 return;
1788 tevent_req_done(req);
1791 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, int *perrno)
1793 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1794 req, struct smb_vfs_call_fsync_state);
1795 int err;
1797 if (tevent_req_is_unix_error(req, &err)) {
1798 *perrno = err;
1799 return -1;
1801 return state->retval;
1805 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1806 struct smb_filename *smb_fname)
1808 VFS_FIND(stat);
1809 return handle->fns->stat_fn(handle, smb_fname);
1812 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1813 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1815 VFS_FIND(fstat);
1816 return handle->fns->fstat_fn(handle, fsp, sbuf);
1819 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1820 struct smb_filename *smb_filename)
1822 VFS_FIND(lstat);
1823 return handle->fns->lstat_fn(handle, smb_filename);
1826 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1827 struct files_struct *fsp,
1828 const SMB_STRUCT_STAT *sbuf)
1830 VFS_FIND(get_alloc_size);
1831 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1834 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1835 const struct smb_filename *smb_fname)
1837 VFS_FIND(unlink);
1838 return handle->fns->unlink_fn(handle, smb_fname);
1841 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1842 mode_t mode)
1844 VFS_FIND(chmod);
1845 return handle->fns->chmod_fn(handle, path, mode);
1848 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1849 struct files_struct *fsp, mode_t mode)
1851 VFS_FIND(fchmod);
1852 return handle->fns->fchmod_fn(handle, fsp, mode);
1855 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1856 uid_t uid, gid_t gid)
1858 VFS_FIND(chown);
1859 return handle->fns->chown_fn(handle, path, uid, gid);
1862 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1863 struct files_struct *fsp, uid_t uid, gid_t gid)
1865 VFS_FIND(fchown);
1866 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1869 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1870 uid_t uid, gid_t gid)
1872 VFS_FIND(lchown);
1873 return handle->fns->lchown_fn(handle, path, uid, gid);
1876 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1878 int ret;
1879 bool as_root = false;
1880 const char *path;
1881 char *saved_dir = NULL;
1882 char *parent_dir = NULL;
1883 NTSTATUS status;
1885 if (fsp->fh->fd != -1) {
1886 /* Try fchown. */
1887 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1888 if (ret == 0) {
1889 return NT_STATUS_OK;
1891 if (ret == -1 && errno != ENOSYS) {
1892 return map_nt_error_from_unix(errno);
1896 as_root = (geteuid() == 0);
1898 if (as_root) {
1900 * We are being asked to chown as root. Make
1901 * sure we chdir() into the path to pin it,
1902 * and always act using lchown to ensure we
1903 * don't deref any symbolic links.
1905 const char *final_component = NULL;
1906 struct smb_filename local_fname;
1908 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1909 if (!saved_dir) {
1910 status = map_nt_error_from_unix(errno);
1911 DEBUG(0,("vfs_chown_fsp: failed to get "
1912 "current working directory. Error was %s\n",
1913 strerror(errno)));
1914 return status;
1917 if (!parent_dirname(talloc_tos(),
1918 fsp->fsp_name->base_name,
1919 &parent_dir,
1920 &final_component)) {
1921 return NT_STATUS_NO_MEMORY;
1924 /* cd into the parent dir to pin it. */
1925 ret = vfs_ChDir(fsp->conn, parent_dir);
1926 if (ret == -1) {
1927 return map_nt_error_from_unix(errno);
1930 ZERO_STRUCT(local_fname);
1931 local_fname.base_name = discard_const_p(char, final_component);
1933 /* Must use lstat here. */
1934 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1935 if (ret == -1) {
1936 status = map_nt_error_from_unix(errno);
1937 goto out;
1940 /* Ensure it matches the fsp stat. */
1941 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1942 status = NT_STATUS_ACCESS_DENIED;
1943 goto out;
1945 path = final_component;
1946 } else {
1947 path = fsp->fsp_name->base_name;
1950 if (fsp->posix_open || as_root) {
1951 ret = SMB_VFS_LCHOWN(fsp->conn,
1952 path,
1953 uid, gid);
1954 } else {
1955 ret = SMB_VFS_CHOWN(fsp->conn,
1956 path,
1957 uid, gid);
1960 if (ret == 0) {
1961 status = NT_STATUS_OK;
1962 } else {
1963 status = map_nt_error_from_unix(errno);
1966 out:
1968 if (as_root) {
1969 vfs_ChDir(fsp->conn,saved_dir);
1970 TALLOC_FREE(saved_dir);
1971 TALLOC_FREE(parent_dir);
1973 return status;
1976 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1978 VFS_FIND(chdir);
1979 return handle->fns->chdir_fn(handle, path);
1982 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
1984 VFS_FIND(getwd);
1985 return handle->fns->getwd_fn(handle);
1988 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
1989 const struct smb_filename *smb_fname,
1990 struct smb_file_time *ft)
1992 VFS_FIND(ntimes);
1993 return handle->fns->ntimes_fn(handle, smb_fname, ft);
1996 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
1997 struct files_struct *fsp, off_t offset)
1999 VFS_FIND(ftruncate);
2000 return handle->fns->ftruncate_fn(handle, fsp, offset);
2003 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2004 struct files_struct *fsp,
2005 enum vfs_fallocate_mode mode,
2006 off_t offset,
2007 off_t len)
2009 VFS_FIND(fallocate);
2010 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2013 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2014 struct files_struct *fsp, uint32 share_mode,
2015 uint32_t access_mask)
2017 VFS_FIND(kernel_flock);
2018 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2019 access_mask);
2022 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2023 struct files_struct *fsp, int leasetype)
2025 VFS_FIND(linux_setlease);
2026 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2029 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
2030 const char *newpath)
2032 VFS_FIND(symlink);
2033 return handle->fns->symlink_fn(handle, oldpath, newpath);
2036 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2037 const char *path, char *buf, size_t bufsiz)
2039 VFS_FIND(readlink);
2040 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
2043 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
2044 const char *newpath)
2046 VFS_FIND(link);
2047 return handle->fns->link_fn(handle, oldpath, newpath);
2050 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
2051 mode_t mode, SMB_DEV_T dev)
2053 VFS_FIND(mknod);
2054 return handle->fns->mknod_fn(handle, path, mode, dev);
2057 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
2059 VFS_FIND(realpath);
2060 return handle->fns->realpath_fn(handle, path);
2063 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
2064 struct sys_notify_context *ctx,
2065 const char *path,
2066 uint32_t *filter,
2067 uint32_t *subdir_filter,
2068 void (*callback)(struct sys_notify_context *ctx,
2069 void *private_data,
2070 struct notify_event *ev),
2071 void *private_data, void *handle_p)
2073 VFS_FIND(notify_watch);
2074 return handle->fns->notify_watch_fn(handle, ctx, path,
2075 filter, subdir_filter, callback,
2076 private_data, handle_p);
2079 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
2080 unsigned int flags)
2082 VFS_FIND(chflags);
2083 return handle->fns->chflags_fn(handle, path, flags);
2086 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2087 const SMB_STRUCT_STAT *sbuf)
2089 VFS_FIND(file_id_create);
2090 return handle->fns->file_id_create_fn(handle, sbuf);
2093 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2094 struct files_struct *fsp,
2095 const char *fname,
2096 TALLOC_CTX *mem_ctx,
2097 unsigned int *num_streams,
2098 struct stream_struct **streams)
2100 VFS_FIND(streaminfo);
2101 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
2102 num_streams, streams);
2105 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2106 const char *path, const char *name,
2107 TALLOC_CTX *mem_ctx, char **found_name)
2109 VFS_FIND(get_real_filename);
2110 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2111 found_name);
2114 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2115 const char *filename)
2117 VFS_FIND(connectpath);
2118 return handle->fns->connectpath_fn(handle, filename);
2121 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2122 struct files_struct *fsp,
2123 struct lock_struct *plock)
2125 VFS_FIND(strict_lock);
2126 return handle->fns->strict_lock_fn(handle, fsp, plock);
2129 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2130 struct files_struct *fsp,
2131 struct lock_struct *plock)
2133 VFS_FIND(strict_unlock);
2134 handle->fns->strict_unlock_fn(handle, fsp, plock);
2137 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2138 const char *name,
2139 enum vfs_translate_direction direction,
2140 TALLOC_CTX *mem_ctx,
2141 char **mapped_name)
2143 VFS_FIND(translate_name);
2144 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2145 mapped_name);
2148 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2149 struct files_struct *fsp,
2150 TALLOC_CTX *ctx,
2151 uint32_t function,
2152 uint16_t req_flags,
2153 const uint8_t *in_data,
2154 uint32_t in_len,
2155 uint8_t **out_data,
2156 uint32_t max_out_len,
2157 uint32_t *out_len)
2159 VFS_FIND(fsctl);
2160 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2161 in_data, in_len, out_data, max_out_len,
2162 out_len);
2165 struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle,
2166 TALLOC_CTX *mem_ctx,
2167 struct tevent_context *ev,
2168 struct files_struct *src_fsp,
2169 off_t src_off,
2170 struct files_struct *dest_fsp,
2171 off_t dest_off,
2172 off_t num)
2174 VFS_FIND(copy_chunk_send);
2175 return handle->fns->copy_chunk_send_fn(handle, mem_ctx, ev, src_fsp,
2176 src_off, dest_fsp, dest_off, num);
2179 NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,
2180 struct tevent_req *req,
2181 off_t *copied)
2183 VFS_FIND(copy_chunk_recv);
2184 return handle->fns->copy_chunk_recv_fn(handle, req, copied);
2187 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2188 struct files_struct *fsp,
2189 uint32 security_info,
2190 TALLOC_CTX *mem_ctx,
2191 struct security_descriptor **ppdesc)
2193 VFS_FIND(fget_nt_acl);
2194 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2195 mem_ctx, ppdesc);
2198 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2199 const char *name,
2200 uint32 security_info,
2201 TALLOC_CTX *mem_ctx,
2202 struct security_descriptor **ppdesc)
2204 VFS_FIND(get_nt_acl);
2205 return handle->fns->get_nt_acl_fn(handle, name, security_info, mem_ctx, ppdesc);
2208 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2209 struct files_struct *fsp,
2210 uint32 security_info_sent,
2211 const struct security_descriptor *psd)
2213 VFS_FIND(fset_nt_acl);
2214 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2215 psd);
2218 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2219 struct smb_filename *file,
2220 struct security_acl *sacl,
2221 uint32_t access_requested,
2222 uint32_t access_denied)
2224 VFS_FIND(audit_file);
2225 return handle->fns->audit_file_fn(handle,
2226 file,
2227 sacl,
2228 access_requested,
2229 access_denied);
2232 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2233 mode_t mode)
2235 VFS_FIND(chmod_acl);
2236 return handle->fns->chmod_acl_fn(handle, name, mode);
2239 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2240 struct files_struct *fsp, mode_t mode)
2242 VFS_FIND(fchmod_acl);
2243 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2246 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2247 const char *path_p,
2248 SMB_ACL_TYPE_T type,
2249 TALLOC_CTX *mem_ctx)
2251 VFS_FIND(sys_acl_get_file);
2252 return handle->fns->sys_acl_get_file_fn(handle, path_p, type, mem_ctx);
2255 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2256 struct files_struct *fsp,
2257 TALLOC_CTX *mem_ctx)
2259 VFS_FIND(sys_acl_get_fd);
2260 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2263 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2264 const char *path_p,
2265 TALLOC_CTX *mem_ctx,
2266 char **blob_description,
2267 DATA_BLOB *blob)
2269 VFS_FIND(sys_acl_blob_get_file);
2270 return handle->fns->sys_acl_blob_get_file_fn(handle, path_p, mem_ctx, blob_description, blob);
2273 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2274 struct files_struct *fsp,
2275 TALLOC_CTX *mem_ctx,
2276 char **blob_description,
2277 DATA_BLOB *blob)
2279 VFS_FIND(sys_acl_blob_get_fd);
2280 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2283 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2284 const char *name, SMB_ACL_TYPE_T acltype,
2285 SMB_ACL_T theacl)
2287 VFS_FIND(sys_acl_set_file);
2288 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2291 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2292 struct files_struct *fsp, SMB_ACL_T theacl)
2294 VFS_FIND(sys_acl_set_fd);
2295 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2298 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2299 const char *path)
2301 VFS_FIND(sys_acl_delete_def_file);
2302 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2305 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2306 const char *path, const char *name, void *value,
2307 size_t size)
2309 VFS_FIND(getxattr);
2310 return handle->fns->getxattr_fn(handle, path, name, value, size);
2313 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2314 struct files_struct *fsp, const char *name,
2315 void *value, size_t size)
2317 VFS_FIND(fgetxattr);
2318 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2321 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2322 const char *path, char *list, size_t size)
2324 VFS_FIND(listxattr);
2325 return handle->fns->listxattr_fn(handle, path, list, size);
2328 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2329 struct files_struct *fsp, char *list,
2330 size_t size)
2332 VFS_FIND(flistxattr);
2333 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2336 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2337 const char *path, const char *name)
2339 VFS_FIND(removexattr);
2340 return handle->fns->removexattr_fn(handle, path, name);
2343 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2344 struct files_struct *fsp, const char *name)
2346 VFS_FIND(fremovexattr);
2347 return handle->fns->fremovexattr_fn(handle, fsp, name);
2350 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2351 const char *name, const void *value, size_t size,
2352 int flags)
2354 VFS_FIND(setxattr);
2355 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2358 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2359 struct files_struct *fsp, const char *name,
2360 const void *value, size_t size, int flags)
2362 VFS_FIND(fsetxattr);
2363 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2366 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2367 struct files_struct *fsp)
2369 VFS_FIND(aio_force);
2370 return handle->fns->aio_force_fn(handle, fsp);
2373 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2374 const struct smb_filename *fname,
2375 SMB_STRUCT_STAT *sbuf)
2377 VFS_FIND(is_offline);
2378 return handle->fns->is_offline_fn(handle, fname, sbuf);
2381 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2382 const struct smb_filename *fname)
2384 VFS_FIND(set_offline);
2385 return handle->fns->set_offline_fn(handle, fname);
2388 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2389 struct files_struct *fsp,
2390 TALLOC_CTX *mem_ctx,
2391 DATA_BLOB *cookie)
2393 VFS_FIND(durable_cookie);
2394 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2397 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2398 struct files_struct *fsp,
2399 const DATA_BLOB old_cookie,
2400 TALLOC_CTX *mem_ctx,
2401 DATA_BLOB *new_cookie)
2403 VFS_FIND(durable_disconnect);
2404 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2405 mem_ctx, new_cookie);
2408 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2409 struct smb_request *smb1req,
2410 struct smbXsrv_open *op,
2411 const DATA_BLOB old_cookie,
2412 TALLOC_CTX *mem_ctx,
2413 struct files_struct **fsp,
2414 DATA_BLOB *new_cookie)
2416 VFS_FIND(durable_reconnect);
2417 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2418 old_cookie, mem_ctx, fsp,
2419 new_cookie);