smbd: Convert vfs_stat_smb_fname to synthetic_smb_fname
[Samba/gebeck_regimport.git] / source3 / smbd / vfs.c
blob19a2788ffa9afdd9dd8744d9e1b6eec1e6e7ada3
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;
847 if (!lp_getwd_cache()) {
848 goto nocache;
851 smb_fname_dot = synthetic_smb_fname(ctx, ".", NULL, NULL);
852 if (smb_fname_dot == NULL) {
853 errno = ENOMEM;
854 goto out;
857 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
859 * Known to fail for root: the directory may be NFS-mounted
860 * and exported with root_squash (so has no root access).
862 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
863 "(NFS problem ?)\n", strerror(errno) ));
864 goto nocache;
867 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
869 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
870 data_blob_const(&key, sizeof(key)),
871 &cache_value)) {
872 goto nocache;
875 SMB_ASSERT((cache_value.length > 0)
876 && (cache_value.data[cache_value.length-1] == '\0'));
878 smb_fname_full = synthetic_smb_fname(ctx, (char *)cache_value.data,
879 NULL, NULL);
880 if (smb_fname_full == NULL) {
881 errno = ENOMEM;
882 goto out;
885 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
886 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
887 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
888 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
890 * Ok, we're done
892 result = talloc_strdup(ctx, smb_fname_full->base_name);
893 if (result == NULL) {
894 errno = ENOMEM;
896 goto out;
899 nocache:
902 * We don't have the information to hand so rely on traditional
903 * methods. The very slow getcwd, which spawns a process on some
904 * systems, or the not quite so bad getwd.
907 current_dir = SMB_VFS_GETWD(conn);
908 if (current_dir == NULL) {
909 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
910 strerror(errno)));
911 goto out;
914 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
915 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
917 memcache_add(smbd_memcache(), GETWD_CACHE,
918 data_blob_const(&key, sizeof(key)),
919 data_blob_const(current_dir,
920 strlen(current_dir)+1));
923 result = talloc_strdup(ctx, current_dir);
924 if (result == NULL) {
925 errno = ENOMEM;
928 out:
929 TALLOC_FREE(smb_fname_dot);
930 TALLOC_FREE(smb_fname_full);
931 SAFE_FREE(current_dir);
932 return result;
935 /*******************************************************************
936 Reduce a file name, removing .. elements and checking that
937 it is below dir in the heirachy. This uses realpath.
938 This function must run as root, and will return names
939 and valid stat structs that can be checked on open.
940 ********************************************************************/
942 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
943 const char *fname,
944 struct smb_request *smbreq)
946 NTSTATUS status;
947 TALLOC_CTX *ctx = talloc_tos();
948 const char *conn_rootdir;
949 size_t rootdir_len;
950 char *dir_name = NULL;
951 const char *last_component = NULL;
952 char *resolved_name = NULL;
953 char *saved_dir = NULL;
954 struct smb_filename *smb_fname_cwd = NULL;
955 struct privilege_paths *priv_paths = NULL;
956 int ret;
958 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
959 fname,
960 conn->connectpath));
963 priv_paths = talloc_zero(smbreq, struct privilege_paths);
964 if (!priv_paths) {
965 status = NT_STATUS_NO_MEMORY;
966 goto err;
969 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
970 status = NT_STATUS_NO_MEMORY;
971 goto err;
974 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
975 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
977 if (priv_paths->parent_name.base_name == NULL ||
978 priv_paths->file_name.base_name == NULL) {
979 status = NT_STATUS_NO_MEMORY;
980 goto err;
983 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
984 status = map_nt_error_from_unix(errno);
985 goto err;
987 /* Remember where we were. */
988 saved_dir = vfs_GetWd(ctx, conn);
989 if (!saved_dir) {
990 status = map_nt_error_from_unix(errno);
991 goto err;
994 /* Go to the parent directory to lock in memory. */
995 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
996 status = map_nt_error_from_unix(errno);
997 goto err;
1000 /* Get the absolute path of the parent directory. */
1001 resolved_name = SMB_VFS_REALPATH(conn,".");
1002 if (!resolved_name) {
1003 status = map_nt_error_from_unix(errno);
1004 goto err;
1007 if (*resolved_name != '/') {
1008 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1009 "doesn't return absolute paths !\n"));
1010 status = NT_STATUS_OBJECT_NAME_INVALID;
1011 goto err;
1014 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1015 priv_paths->parent_name.base_name,
1016 resolved_name));
1018 /* Now check the stat value is the same. */
1019 smb_fname_cwd = synthetic_smb_fname(talloc_tos(), ".", NULL, NULL);
1020 if (smb_fname_cwd == NULL) {
1021 status = NT_STATUS_NO_MEMORY;
1022 goto err;
1025 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1026 status = map_nt_error_from_unix(errno);
1027 goto err;
1030 /* Ensure we're pointing at the same place. */
1031 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1032 DEBUG(0,("check_reduced_name_with_privilege: "
1033 "device/inode/uid/gid on directory %s changed. "
1034 "Denying access !\n",
1035 priv_paths->parent_name.base_name));
1036 status = NT_STATUS_ACCESS_DENIED;
1037 goto err;
1040 /* Ensure we're below the connect path. */
1042 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1043 if (conn_rootdir == NULL) {
1044 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1045 "conn_rootdir\n"));
1046 status = NT_STATUS_ACCESS_DENIED;
1047 goto err;
1050 rootdir_len = strlen(conn_rootdir);
1051 if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1052 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1053 "attempt: %s is a symlink outside the "
1054 "share path\n",
1055 dir_name));
1056 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1057 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1058 status = NT_STATUS_ACCESS_DENIED;
1059 goto err;
1062 /* Now ensure that the last component either doesn't
1063 exist, or is *NOT* a symlink. */
1065 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1066 if (ret == -1) {
1067 /* Errno must be ENOENT for this be ok. */
1068 if (errno != ENOENT) {
1069 status = map_nt_error_from_unix(errno);
1070 DEBUG(2, ("check_reduced_name_with_privilege: "
1071 "LSTAT on %s failed with %s\n",
1072 priv_paths->file_name.base_name,
1073 nt_errstr(status)));
1074 goto err;
1078 if (VALID_STAT(priv_paths->file_name.st) &&
1079 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1080 DEBUG(2, ("check_reduced_name_with_privilege: "
1081 "Last component %s is a symlink. Denying"
1082 "access.\n",
1083 priv_paths->file_name.base_name));
1084 status = NT_STATUS_ACCESS_DENIED;
1085 goto err;
1088 smbreq->priv_paths = priv_paths;
1089 status = NT_STATUS_OK;
1091 err:
1093 if (saved_dir) {
1094 vfs_ChDir(conn, saved_dir);
1096 SAFE_FREE(resolved_name);
1097 if (!NT_STATUS_IS_OK(status)) {
1098 TALLOC_FREE(priv_paths);
1100 TALLOC_FREE(dir_name);
1101 return status;
1104 /*******************************************************************
1105 Reduce a file name, removing .. elements and checking that
1106 it is below dir in the heirachy. This uses realpath.
1107 ********************************************************************/
1109 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1111 char *resolved_name = NULL;
1112 bool allow_symlinks = true;
1113 bool allow_widelinks = false;
1115 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1117 resolved_name = SMB_VFS_REALPATH(conn,fname);
1119 if (!resolved_name) {
1120 switch (errno) {
1121 case ENOTDIR:
1122 DEBUG(3,("check_reduced_name: Component not a "
1123 "directory in getting realpath for "
1124 "%s\n", fname));
1125 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1126 case ENOENT:
1128 TALLOC_CTX *ctx = talloc_tos();
1129 char *dir_name = NULL;
1130 const char *last_component = NULL;
1131 char *new_name = NULL;
1132 int ret;
1134 /* Last component didn't exist.
1135 Remove it and try and canonicalise
1136 the directory name. */
1137 if (!parent_dirname(ctx, fname,
1138 &dir_name,
1139 &last_component)) {
1140 return NT_STATUS_NO_MEMORY;
1143 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1144 if (!resolved_name) {
1145 NTSTATUS status = map_nt_error_from_unix(errno);
1147 if (errno == ENOENT || errno == ENOTDIR) {
1148 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1151 DEBUG(3,("check_reduce_name: "
1152 "couldn't get realpath for "
1153 "%s (%s)\n",
1154 fname,
1155 nt_errstr(status)));
1156 return status;
1158 ret = asprintf(&new_name, "%s/%s",
1159 resolved_name, last_component);
1160 SAFE_FREE(resolved_name);
1161 if (ret == -1) {
1162 return NT_STATUS_NO_MEMORY;
1164 resolved_name = new_name;
1165 break;
1167 default:
1168 DEBUG(3,("check_reduced_name: couldn't get "
1169 "realpath for %s\n", fname));
1170 return map_nt_error_from_unix(errno);
1174 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1175 resolved_name));
1177 if (*resolved_name != '/') {
1178 DEBUG(0,("check_reduced_name: realpath doesn't return "
1179 "absolute paths !\n"));
1180 SAFE_FREE(resolved_name);
1181 return NT_STATUS_OBJECT_NAME_INVALID;
1184 allow_widelinks = lp_widelinks(SNUM(conn));
1185 allow_symlinks = lp_symlinks(SNUM(conn));
1187 /* Common widelinks and symlinks checks. */
1188 if (!allow_widelinks || !allow_symlinks) {
1189 const char *conn_rootdir;
1190 size_t rootdir_len;
1192 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1193 if (conn_rootdir == NULL) {
1194 DEBUG(2, ("check_reduced_name: Could not get "
1195 "conn_rootdir\n"));
1196 SAFE_FREE(resolved_name);
1197 return NT_STATUS_ACCESS_DENIED;
1200 rootdir_len = strlen(conn_rootdir);
1201 if (strncmp(conn_rootdir, resolved_name,
1202 rootdir_len) != 0) {
1203 DEBUG(2, ("check_reduced_name: Bad access "
1204 "attempt: %s is a symlink outside the "
1205 "share path\n", fname));
1206 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1207 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1208 SAFE_FREE(resolved_name);
1209 return NT_STATUS_ACCESS_DENIED;
1212 /* Extra checks if all symlinks are disallowed. */
1213 if (!allow_symlinks) {
1214 /* fname can't have changed in resolved_path. */
1215 const char *p = &resolved_name[rootdir_len];
1217 /* *p can be '\0' if fname was "." */
1218 if (*p == '\0' && ISDOT(fname)) {
1219 goto out;
1222 if (*p != '/') {
1223 DEBUG(2, ("check_reduced_name: logic error (%c) "
1224 "in resolved_name: %s\n",
1226 fname));
1227 SAFE_FREE(resolved_name);
1228 return NT_STATUS_ACCESS_DENIED;
1231 p++;
1232 if (strcmp(fname, p)!=0) {
1233 DEBUG(2, ("check_reduced_name: Bad access "
1234 "attempt: %s is a symlink to %s\n",
1235 fname, p));
1236 SAFE_FREE(resolved_name);
1237 return NT_STATUS_ACCESS_DENIED;
1242 out:
1244 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1245 resolved_name));
1246 SAFE_FREE(resolved_name);
1247 return NT_STATUS_OK;
1251 * XXX: This is temporary and there should be no callers of this once
1252 * smb_filename is plumbed through all path based operations.
1254 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1255 SMB_STRUCT_STAT *psbuf)
1257 struct smb_filename *smb_fname;
1258 int ret;
1260 smb_fname = synthetic_smb_fname_split(talloc_tos(), fname, NULL);
1261 if (smb_fname == NULL) {
1262 errno = ENOMEM;
1263 return -1;
1266 if (lp_posix_pathnames()) {
1267 ret = SMB_VFS_LSTAT(conn, smb_fname);
1268 } else {
1269 ret = SMB_VFS_STAT(conn, smb_fname);
1272 if (ret != -1) {
1273 *psbuf = smb_fname->st;
1276 TALLOC_FREE(smb_fname);
1277 return ret;
1281 * XXX: This is temporary and there should be no callers of this once
1282 * smb_filename is plumbed through all path based operations.
1284 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1285 SMB_STRUCT_STAT *psbuf)
1287 struct smb_filename *smb_fname = NULL;
1288 NTSTATUS status;
1289 int ret;
1291 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1292 &smb_fname);
1293 if (!NT_STATUS_IS_OK(status)) {
1294 errno = map_errno_from_nt_status(status);
1295 return -1;
1298 ret = SMB_VFS_LSTAT(conn, smb_fname);
1299 if (ret != -1) {
1300 *psbuf = smb_fname->st;
1303 TALLOC_FREE(smb_fname);
1304 return ret;
1308 * Ensure LSTAT is called for POSIX paths.
1311 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1313 int ret;
1315 if(fsp->fh->fd == -1) {
1316 if (fsp->posix_open) {
1317 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1318 } else {
1319 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1321 if (ret == -1) {
1322 return map_nt_error_from_unix(errno);
1324 } else {
1325 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1326 return map_nt_error_from_unix(errno);
1329 return NT_STATUS_OK;
1333 * Initialize num_streams and streams, then call VFS op streaminfo
1335 NTSTATUS vfs_streaminfo(connection_struct *conn,
1336 struct files_struct *fsp,
1337 const char *fname,
1338 TALLOC_CTX *mem_ctx,
1339 unsigned int *num_streams,
1340 struct stream_struct **streams)
1342 *num_streams = 0;
1343 *streams = NULL;
1344 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1348 generate a file_id from a stat structure
1350 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1352 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1355 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1356 const char *service, const char *user)
1358 VFS_FIND(connect);
1359 return handle->fns->connect_fn(handle, service, user);
1362 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1364 VFS_FIND(disconnect);
1365 handle->fns->disconnect_fn(handle);
1368 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1369 const char *path, bool small_query,
1370 uint64_t *bsize, uint64_t *dfree,
1371 uint64_t *dsize)
1373 VFS_FIND(disk_free);
1374 return handle->fns->disk_free_fn(handle, path, small_query, bsize,
1375 dfree, dsize);
1378 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1379 enum SMB_QUOTA_TYPE qtype, unid_t id,
1380 SMB_DISK_QUOTA *qt)
1382 VFS_FIND(get_quota);
1383 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1386 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1387 enum SMB_QUOTA_TYPE qtype, unid_t id,
1388 SMB_DISK_QUOTA *qt)
1390 VFS_FIND(set_quota);
1391 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1394 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1395 struct files_struct *fsp,
1396 struct shadow_copy_data *shadow_copy_data,
1397 bool labels)
1399 VFS_FIND(get_shadow_copy_data);
1400 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1401 shadow_copy_data,
1402 labels);
1404 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1405 struct vfs_statvfs_struct *statbuf)
1407 VFS_FIND(statvfs);
1408 return handle->fns->statvfs_fn(handle, path, statbuf);
1411 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1412 enum timestamp_set_resolution *p_ts_res)
1414 VFS_FIND(fs_capabilities);
1415 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1418 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1419 struct dfs_GetDFSReferral *r)
1421 VFS_FIND(get_dfs_referrals);
1422 return handle->fns->get_dfs_referrals_fn(handle, r);
1425 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1426 const char *fname, const char *mask,
1427 uint32 attributes)
1429 VFS_FIND(opendir);
1430 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1433 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1434 struct files_struct *fsp,
1435 const char *mask,
1436 uint32 attributes)
1438 VFS_FIND(fdopendir);
1439 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1442 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1443 DIR *dirp,
1444 SMB_STRUCT_STAT *sbuf)
1446 VFS_FIND(readdir);
1447 return handle->fns->readdir_fn(handle, dirp, sbuf);
1450 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1451 DIR *dirp, long offset)
1453 VFS_FIND(seekdir);
1454 handle->fns->seekdir_fn(handle, dirp, offset);
1457 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1458 DIR *dirp)
1460 VFS_FIND(telldir);
1461 return handle->fns->telldir_fn(handle, dirp);
1464 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1465 DIR *dirp)
1467 VFS_FIND(rewind_dir);
1468 handle->fns->rewind_dir_fn(handle, dirp);
1471 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1472 mode_t mode)
1474 VFS_FIND(mkdir);
1475 return handle->fns->mkdir_fn(handle, path, mode);
1478 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1480 VFS_FIND(rmdir);
1481 return handle->fns->rmdir_fn(handle, path);
1484 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1485 DIR *dir)
1487 VFS_FIND(closedir);
1488 return handle->fns->closedir_fn(handle, dir);
1491 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1492 DIR *dirp)
1494 VFS_FIND(init_search_op);
1495 handle->fns->init_search_op_fn(handle, dirp);
1498 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1499 struct smb_filename *smb_fname, struct files_struct *fsp,
1500 int flags, mode_t mode)
1502 VFS_FIND(open);
1503 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1506 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1507 struct smb_request *req,
1508 uint16_t root_dir_fid,
1509 struct smb_filename *smb_fname,
1510 uint32_t access_mask,
1511 uint32_t share_access,
1512 uint32_t create_disposition,
1513 uint32_t create_options,
1514 uint32_t file_attributes,
1515 uint32_t oplock_request,
1516 uint64_t allocation_size,
1517 uint32_t private_flags,
1518 struct security_descriptor *sd,
1519 struct ea_list *ea_list,
1520 files_struct **result,
1521 int *pinfo)
1523 VFS_FIND(create_file);
1524 return handle->fns->create_file_fn(
1525 handle, req, root_dir_fid, smb_fname, access_mask,
1526 share_access, create_disposition, create_options,
1527 file_attributes, oplock_request, allocation_size,
1528 private_flags, sd, ea_list,
1529 result, pinfo);
1532 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1533 struct files_struct *fsp)
1535 VFS_FIND(close);
1536 return handle->fns->close_fn(handle, fsp);
1539 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1540 struct files_struct *fsp, void *data, size_t n)
1542 VFS_FIND(read);
1543 return handle->fns->read_fn(handle, fsp, data, n);
1546 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1547 struct files_struct *fsp, void *data, size_t n,
1548 off_t offset)
1550 VFS_FIND(pread);
1551 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1554 struct smb_vfs_call_pread_state {
1555 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1556 ssize_t retval;
1559 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1561 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1562 TALLOC_CTX *mem_ctx,
1563 struct tevent_context *ev,
1564 struct files_struct *fsp,
1565 void *data,
1566 size_t n, off_t offset)
1568 struct tevent_req *req, *subreq;
1569 struct smb_vfs_call_pread_state *state;
1571 req = tevent_req_create(mem_ctx, &state,
1572 struct smb_vfs_call_pread_state);
1573 if (req == NULL) {
1574 return NULL;
1576 VFS_FIND(pread_send);
1577 state->recv_fn = handle->fns->pread_recv_fn;
1579 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1580 offset);
1581 if (tevent_req_nomem(subreq, req)) {
1582 return tevent_req_post(req, ev);
1584 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1585 return req;
1588 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1590 struct tevent_req *req = tevent_req_callback_data(
1591 subreq, struct tevent_req);
1592 struct smb_vfs_call_pread_state *state = tevent_req_data(
1593 req, struct smb_vfs_call_pread_state);
1594 int err;
1596 state->retval = state->recv_fn(subreq, &err);
1597 TALLOC_FREE(subreq);
1598 if (state->retval == -1) {
1599 tevent_req_error(req, err);
1600 return;
1602 tevent_req_done(req);
1605 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req, int *perrno)
1607 struct smb_vfs_call_pread_state *state = tevent_req_data(
1608 req, struct smb_vfs_call_pread_state);
1609 int err;
1611 if (tevent_req_is_unix_error(req, &err)) {
1612 *perrno = err;
1613 return -1;
1615 return state->retval;
1618 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1619 struct files_struct *fsp, const void *data,
1620 size_t n)
1622 VFS_FIND(write);
1623 return handle->fns->write_fn(handle, fsp, data, n);
1626 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1627 struct files_struct *fsp, const void *data,
1628 size_t n, off_t offset)
1630 VFS_FIND(pwrite);
1631 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1634 struct smb_vfs_call_pwrite_state {
1635 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1636 ssize_t retval;
1639 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1641 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1642 TALLOC_CTX *mem_ctx,
1643 struct tevent_context *ev,
1644 struct files_struct *fsp,
1645 const void *data,
1646 size_t n, off_t offset)
1648 struct tevent_req *req, *subreq;
1649 struct smb_vfs_call_pwrite_state *state;
1651 req = tevent_req_create(mem_ctx, &state,
1652 struct smb_vfs_call_pwrite_state);
1653 if (req == NULL) {
1654 return NULL;
1656 VFS_FIND(pwrite_send);
1657 state->recv_fn = handle->fns->pwrite_recv_fn;
1659 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1660 offset);
1661 if (tevent_req_nomem(subreq, req)) {
1662 return tevent_req_post(req, ev);
1664 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1665 return req;
1668 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1670 struct tevent_req *req = tevent_req_callback_data(
1671 subreq, struct tevent_req);
1672 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1673 req, struct smb_vfs_call_pwrite_state);
1674 int err;
1676 state->retval = state->recv_fn(subreq, &err);
1677 TALLOC_FREE(subreq);
1678 if (state->retval == -1) {
1679 tevent_req_error(req, err);
1680 return;
1682 tevent_req_done(req);
1685 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req, int *perrno)
1687 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1688 req, struct smb_vfs_call_pwrite_state);
1689 int err;
1691 if (tevent_req_is_unix_error(req, &err)) {
1692 *perrno = err;
1693 return -1;
1695 return state->retval;
1698 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1699 struct files_struct *fsp, off_t offset,
1700 int whence)
1702 VFS_FIND(lseek);
1703 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1706 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1707 files_struct *fromfsp, const DATA_BLOB *header,
1708 off_t offset, size_t count)
1710 VFS_FIND(sendfile);
1711 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1712 count);
1715 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1716 files_struct *tofsp, off_t offset,
1717 size_t count)
1719 VFS_FIND(recvfile);
1720 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1723 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1724 const struct smb_filename *smb_fname_src,
1725 const struct smb_filename *smb_fname_dst)
1727 VFS_FIND(rename);
1728 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1731 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1732 struct files_struct *fsp)
1734 VFS_FIND(fsync);
1735 return handle->fns->fsync_fn(handle, fsp);
1738 struct smb_vfs_call_fsync_state {
1739 int (*recv_fn)(struct tevent_req *req, int *err);
1740 int retval;
1743 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1745 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1746 TALLOC_CTX *mem_ctx,
1747 struct tevent_context *ev,
1748 struct files_struct *fsp)
1750 struct tevent_req *req, *subreq;
1751 struct smb_vfs_call_fsync_state *state;
1753 req = tevent_req_create(mem_ctx, &state,
1754 struct smb_vfs_call_fsync_state);
1755 if (req == NULL) {
1756 return NULL;
1758 VFS_FIND(fsync_send);
1759 state->recv_fn = handle->fns->fsync_recv_fn;
1761 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1762 if (tevent_req_nomem(subreq, req)) {
1763 return tevent_req_post(req, ev);
1765 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1766 return req;
1769 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1771 struct tevent_req *req = tevent_req_callback_data(
1772 subreq, struct tevent_req);
1773 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1774 req, struct smb_vfs_call_fsync_state);
1775 int err;
1777 state->retval = state->recv_fn(subreq, &err);
1778 TALLOC_FREE(subreq);
1779 if (state->retval == -1) {
1780 tevent_req_error(req, err);
1781 return;
1783 tevent_req_done(req);
1786 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, int *perrno)
1788 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1789 req, struct smb_vfs_call_fsync_state);
1790 int err;
1792 if (tevent_req_is_unix_error(req, &err)) {
1793 *perrno = err;
1794 return -1;
1796 return state->retval;
1800 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1801 struct smb_filename *smb_fname)
1803 VFS_FIND(stat);
1804 return handle->fns->stat_fn(handle, smb_fname);
1807 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1808 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1810 VFS_FIND(fstat);
1811 return handle->fns->fstat_fn(handle, fsp, sbuf);
1814 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1815 struct smb_filename *smb_filename)
1817 VFS_FIND(lstat);
1818 return handle->fns->lstat_fn(handle, smb_filename);
1821 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1822 struct files_struct *fsp,
1823 const SMB_STRUCT_STAT *sbuf)
1825 VFS_FIND(get_alloc_size);
1826 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1829 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1830 const struct smb_filename *smb_fname)
1832 VFS_FIND(unlink);
1833 return handle->fns->unlink_fn(handle, smb_fname);
1836 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1837 mode_t mode)
1839 VFS_FIND(chmod);
1840 return handle->fns->chmod_fn(handle, path, mode);
1843 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1844 struct files_struct *fsp, mode_t mode)
1846 VFS_FIND(fchmod);
1847 return handle->fns->fchmod_fn(handle, fsp, mode);
1850 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1851 uid_t uid, gid_t gid)
1853 VFS_FIND(chown);
1854 return handle->fns->chown_fn(handle, path, uid, gid);
1857 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1858 struct files_struct *fsp, uid_t uid, gid_t gid)
1860 VFS_FIND(fchown);
1861 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1864 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1865 uid_t uid, gid_t gid)
1867 VFS_FIND(lchown);
1868 return handle->fns->lchown_fn(handle, path, uid, gid);
1871 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1873 int ret;
1874 bool as_root = false;
1875 const char *path;
1876 char *saved_dir = NULL;
1877 char *parent_dir = NULL;
1878 NTSTATUS status;
1880 if (fsp->fh->fd != -1) {
1881 /* Try fchown. */
1882 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1883 if (ret == 0) {
1884 return NT_STATUS_OK;
1886 if (ret == -1 && errno != ENOSYS) {
1887 return map_nt_error_from_unix(errno);
1891 as_root = (geteuid() == 0);
1893 if (as_root) {
1895 * We are being asked to chown as root. Make
1896 * sure we chdir() into the path to pin it,
1897 * and always act using lchown to ensure we
1898 * don't deref any symbolic links.
1900 const char *final_component = NULL;
1901 struct smb_filename local_fname;
1903 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1904 if (!saved_dir) {
1905 status = map_nt_error_from_unix(errno);
1906 DEBUG(0,("vfs_chown_fsp: failed to get "
1907 "current working directory. Error was %s\n",
1908 strerror(errno)));
1909 return status;
1912 if (!parent_dirname(talloc_tos(),
1913 fsp->fsp_name->base_name,
1914 &parent_dir,
1915 &final_component)) {
1916 return NT_STATUS_NO_MEMORY;
1919 /* cd into the parent dir to pin it. */
1920 ret = vfs_ChDir(fsp->conn, parent_dir);
1921 if (ret == -1) {
1922 return map_nt_error_from_unix(errno);
1925 ZERO_STRUCT(local_fname);
1926 local_fname.base_name = discard_const_p(char, final_component);
1928 /* Must use lstat here. */
1929 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1930 if (ret == -1) {
1931 status = map_nt_error_from_unix(errno);
1932 goto out;
1935 /* Ensure it matches the fsp stat. */
1936 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1937 status = NT_STATUS_ACCESS_DENIED;
1938 goto out;
1940 path = final_component;
1941 } else {
1942 path = fsp->fsp_name->base_name;
1945 if (fsp->posix_open || as_root) {
1946 ret = SMB_VFS_LCHOWN(fsp->conn,
1947 path,
1948 uid, gid);
1949 } else {
1950 ret = SMB_VFS_CHOWN(fsp->conn,
1951 path,
1952 uid, gid);
1955 if (ret == 0) {
1956 status = NT_STATUS_OK;
1957 } else {
1958 status = map_nt_error_from_unix(errno);
1961 out:
1963 if (as_root) {
1964 vfs_ChDir(fsp->conn,saved_dir);
1965 TALLOC_FREE(saved_dir);
1966 TALLOC_FREE(parent_dir);
1968 return status;
1971 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1973 VFS_FIND(chdir);
1974 return handle->fns->chdir_fn(handle, path);
1977 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
1979 VFS_FIND(getwd);
1980 return handle->fns->getwd_fn(handle);
1983 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
1984 const struct smb_filename *smb_fname,
1985 struct smb_file_time *ft)
1987 VFS_FIND(ntimes);
1988 return handle->fns->ntimes_fn(handle, smb_fname, ft);
1991 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
1992 struct files_struct *fsp, off_t offset)
1994 VFS_FIND(ftruncate);
1995 return handle->fns->ftruncate_fn(handle, fsp, offset);
1998 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
1999 struct files_struct *fsp,
2000 enum vfs_fallocate_mode mode,
2001 off_t offset,
2002 off_t len)
2004 VFS_FIND(fallocate);
2005 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2008 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2009 struct files_struct *fsp, uint32 share_mode,
2010 uint32_t access_mask)
2012 VFS_FIND(kernel_flock);
2013 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2014 access_mask);
2017 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2018 struct files_struct *fsp, int leasetype)
2020 VFS_FIND(linux_setlease);
2021 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2024 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
2025 const char *newpath)
2027 VFS_FIND(symlink);
2028 return handle->fns->symlink_fn(handle, oldpath, newpath);
2031 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2032 const char *path, char *buf, size_t bufsiz)
2034 VFS_FIND(readlink);
2035 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
2038 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
2039 const char *newpath)
2041 VFS_FIND(link);
2042 return handle->fns->link_fn(handle, oldpath, newpath);
2045 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
2046 mode_t mode, SMB_DEV_T dev)
2048 VFS_FIND(mknod);
2049 return handle->fns->mknod_fn(handle, path, mode, dev);
2052 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
2054 VFS_FIND(realpath);
2055 return handle->fns->realpath_fn(handle, path);
2058 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
2059 struct sys_notify_context *ctx,
2060 const char *path,
2061 uint32_t *filter,
2062 uint32_t *subdir_filter,
2063 void (*callback)(struct sys_notify_context *ctx,
2064 void *private_data,
2065 struct notify_event *ev),
2066 void *private_data, void *handle_p)
2068 VFS_FIND(notify_watch);
2069 return handle->fns->notify_watch_fn(handle, ctx, path,
2070 filter, subdir_filter, callback,
2071 private_data, handle_p);
2074 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
2075 unsigned int flags)
2077 VFS_FIND(chflags);
2078 return handle->fns->chflags_fn(handle, path, flags);
2081 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2082 const SMB_STRUCT_STAT *sbuf)
2084 VFS_FIND(file_id_create);
2085 return handle->fns->file_id_create_fn(handle, sbuf);
2088 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2089 struct files_struct *fsp,
2090 const char *fname,
2091 TALLOC_CTX *mem_ctx,
2092 unsigned int *num_streams,
2093 struct stream_struct **streams)
2095 VFS_FIND(streaminfo);
2096 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
2097 num_streams, streams);
2100 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2101 const char *path, const char *name,
2102 TALLOC_CTX *mem_ctx, char **found_name)
2104 VFS_FIND(get_real_filename);
2105 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2106 found_name);
2109 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2110 const char *filename)
2112 VFS_FIND(connectpath);
2113 return handle->fns->connectpath_fn(handle, filename);
2116 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2117 struct files_struct *fsp,
2118 struct lock_struct *plock)
2120 VFS_FIND(strict_lock);
2121 return handle->fns->strict_lock_fn(handle, fsp, plock);
2124 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2125 struct files_struct *fsp,
2126 struct lock_struct *plock)
2128 VFS_FIND(strict_unlock);
2129 handle->fns->strict_unlock_fn(handle, fsp, plock);
2132 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2133 const char *name,
2134 enum vfs_translate_direction direction,
2135 TALLOC_CTX *mem_ctx,
2136 char **mapped_name)
2138 VFS_FIND(translate_name);
2139 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2140 mapped_name);
2143 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2144 struct files_struct *fsp,
2145 TALLOC_CTX *ctx,
2146 uint32_t function,
2147 uint16_t req_flags,
2148 const uint8_t *in_data,
2149 uint32_t in_len,
2150 uint8_t **out_data,
2151 uint32_t max_out_len,
2152 uint32_t *out_len)
2154 VFS_FIND(fsctl);
2155 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2156 in_data, in_len, out_data, max_out_len,
2157 out_len);
2160 struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle,
2161 TALLOC_CTX *mem_ctx,
2162 struct tevent_context *ev,
2163 struct files_struct *src_fsp,
2164 off_t src_off,
2165 struct files_struct *dest_fsp,
2166 off_t dest_off,
2167 off_t num)
2169 VFS_FIND(copy_chunk_send);
2170 return handle->fns->copy_chunk_send_fn(handle, mem_ctx, ev, src_fsp,
2171 src_off, dest_fsp, dest_off, num);
2174 NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,
2175 struct tevent_req *req,
2176 off_t *copied)
2178 VFS_FIND(copy_chunk_recv);
2179 return handle->fns->copy_chunk_recv_fn(handle, req, copied);
2182 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2183 struct files_struct *fsp,
2184 uint32 security_info,
2185 TALLOC_CTX *mem_ctx,
2186 struct security_descriptor **ppdesc)
2188 VFS_FIND(fget_nt_acl);
2189 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2190 mem_ctx, ppdesc);
2193 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2194 const char *name,
2195 uint32 security_info,
2196 TALLOC_CTX *mem_ctx,
2197 struct security_descriptor **ppdesc)
2199 VFS_FIND(get_nt_acl);
2200 return handle->fns->get_nt_acl_fn(handle, name, security_info, mem_ctx, ppdesc);
2203 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2204 struct files_struct *fsp,
2205 uint32 security_info_sent,
2206 const struct security_descriptor *psd)
2208 VFS_FIND(fset_nt_acl);
2209 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2210 psd);
2213 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2214 struct smb_filename *file,
2215 struct security_acl *sacl,
2216 uint32_t access_requested,
2217 uint32_t access_denied)
2219 VFS_FIND(audit_file);
2220 return handle->fns->audit_file_fn(handle,
2221 file,
2222 sacl,
2223 access_requested,
2224 access_denied);
2227 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2228 mode_t mode)
2230 VFS_FIND(chmod_acl);
2231 return handle->fns->chmod_acl_fn(handle, name, mode);
2234 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2235 struct files_struct *fsp, mode_t mode)
2237 VFS_FIND(fchmod_acl);
2238 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
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,
2244 TALLOC_CTX *mem_ctx)
2246 VFS_FIND(sys_acl_get_file);
2247 return handle->fns->sys_acl_get_file_fn(handle, path_p, type, mem_ctx);
2250 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2251 struct files_struct *fsp,
2252 TALLOC_CTX *mem_ctx)
2254 VFS_FIND(sys_acl_get_fd);
2255 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2258 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2259 const char *path_p,
2260 TALLOC_CTX *mem_ctx,
2261 char **blob_description,
2262 DATA_BLOB *blob)
2264 VFS_FIND(sys_acl_blob_get_file);
2265 return handle->fns->sys_acl_blob_get_file_fn(handle, path_p, mem_ctx, blob_description, blob);
2268 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2269 struct files_struct *fsp,
2270 TALLOC_CTX *mem_ctx,
2271 char **blob_description,
2272 DATA_BLOB *blob)
2274 VFS_FIND(sys_acl_blob_get_fd);
2275 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2278 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2279 const char *name, SMB_ACL_TYPE_T acltype,
2280 SMB_ACL_T theacl)
2282 VFS_FIND(sys_acl_set_file);
2283 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2286 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2287 struct files_struct *fsp, SMB_ACL_T theacl)
2289 VFS_FIND(sys_acl_set_fd);
2290 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2293 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2294 const char *path)
2296 VFS_FIND(sys_acl_delete_def_file);
2297 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2300 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2301 const char *path, const char *name, void *value,
2302 size_t size)
2304 VFS_FIND(getxattr);
2305 return handle->fns->getxattr_fn(handle, path, name, value, size);
2308 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2309 struct files_struct *fsp, const char *name,
2310 void *value, size_t size)
2312 VFS_FIND(fgetxattr);
2313 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2316 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2317 const char *path, char *list, size_t size)
2319 VFS_FIND(listxattr);
2320 return handle->fns->listxattr_fn(handle, path, list, size);
2323 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2324 struct files_struct *fsp, char *list,
2325 size_t size)
2327 VFS_FIND(flistxattr);
2328 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2331 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2332 const char *path, const char *name)
2334 VFS_FIND(removexattr);
2335 return handle->fns->removexattr_fn(handle, path, name);
2338 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2339 struct files_struct *fsp, const char *name)
2341 VFS_FIND(fremovexattr);
2342 return handle->fns->fremovexattr_fn(handle, fsp, name);
2345 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2346 const char *name, const void *value, size_t size,
2347 int flags)
2349 VFS_FIND(setxattr);
2350 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2353 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2354 struct files_struct *fsp, const char *name,
2355 const void *value, size_t size, int flags)
2357 VFS_FIND(fsetxattr);
2358 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2361 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2362 struct files_struct *fsp)
2364 VFS_FIND(aio_force);
2365 return handle->fns->aio_force_fn(handle, fsp);
2368 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2369 const struct smb_filename *fname,
2370 SMB_STRUCT_STAT *sbuf)
2372 VFS_FIND(is_offline);
2373 return handle->fns->is_offline_fn(handle, fname, sbuf);
2376 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2377 const struct smb_filename *fname)
2379 VFS_FIND(set_offline);
2380 return handle->fns->set_offline_fn(handle, fname);
2383 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2384 struct files_struct *fsp,
2385 TALLOC_CTX *mem_ctx,
2386 DATA_BLOB *cookie)
2388 VFS_FIND(durable_cookie);
2389 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2392 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2393 struct files_struct *fsp,
2394 const DATA_BLOB old_cookie,
2395 TALLOC_CTX *mem_ctx,
2396 DATA_BLOB *new_cookie)
2398 VFS_FIND(durable_disconnect);
2399 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2400 mem_ctx, new_cookie);
2403 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2404 struct smb_request *smb1req,
2405 struct smbXsrv_open *op,
2406 const DATA_BLOB old_cookie,
2407 TALLOC_CTX *mem_ctx,
2408 struct files_struct **fsp,
2409 DATA_BLOB *new_cookie)
2411 VFS_FIND(durable_reconnect);
2412 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2413 old_cookie, mem_ctx, fsp,
2414 new_cookie);