Rename the profile enums with a SAMBA_ prefix to avoid conflict with system files.
[Samba/wip.git] / source3 / smbd / vfs.c
blobde0cc97205697487630400d24697e8a39c6e02ef
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 int sockfd = req->sconn->sock;
432 int old_flags;
433 SMB_ASSERT(req->unread_bytes == N);
434 /* VFS_RECVFILE must drain the socket
435 * before returning. */
436 req->unread_bytes = 0;
437 /* Ensure the socket is blocking. */
438 old_flags = fcntl(sockfd, F_GETFL, 0);
439 if (set_blocking(sockfd, true) == -1) {
440 return (ssize_t)-1;
442 ret = SMB_VFS_RECVFILE(sockfd,
443 fsp,
444 (off_t)-1,
446 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
447 return (ssize_t)-1;
449 return ret;
452 while (total < N) {
453 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
455 if (ret == -1)
456 return -1;
457 if (ret == 0)
458 return total;
460 total += ret;
462 return (ssize_t)total;
465 ssize_t vfs_pwrite_data(struct smb_request *req,
466 files_struct *fsp,
467 const char *buffer,
468 size_t N,
469 off_t offset)
471 size_t total=0;
472 ssize_t ret;
474 if (req && req->unread_bytes) {
475 int sockfd = req->sconn->sock;
476 int old_flags;
477 SMB_ASSERT(req->unread_bytes == N);
478 /* VFS_RECVFILE must drain the socket
479 * before returning. */
480 req->unread_bytes = 0;
481 /* Ensure the socket is blocking. */
482 old_flags = fcntl(sockfd, F_GETFL, 0);
483 if (set_blocking(sockfd, true) == -1) {
484 return (ssize_t)-1;
486 ret = SMB_VFS_RECVFILE(sockfd,
487 fsp,
488 offset,
490 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
491 return (ssize_t)-1;
493 return ret;
496 while (total < N) {
497 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
498 offset + total);
500 if (ret == -1)
501 return -1;
502 if (ret == 0)
503 return total;
505 total += ret;
507 return (ssize_t)total;
509 /****************************************************************************
510 An allocate file space call using the vfs interface.
511 Allocates space for a file from a filedescriptor.
512 Returns 0 on success, -1 on failure.
513 ****************************************************************************/
515 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
517 int ret;
518 connection_struct *conn = fsp->conn;
519 uint64_t space_avail;
520 uint64_t bsize,dfree,dsize;
521 NTSTATUS status;
524 * Actually try and commit the space on disk....
527 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
528 fsp_str_dbg(fsp), (double)len));
530 if (((off_t)len) < 0) {
531 DEBUG(0,("vfs_allocate_file_space: %s negative len "
532 "requested.\n", fsp_str_dbg(fsp)));
533 errno = EINVAL;
534 return -1;
537 status = vfs_stat_fsp(fsp);
538 if (!NT_STATUS_IS_OK(status)) {
539 return -1;
542 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
543 return 0;
545 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
546 /* Shrink - use ftruncate. */
548 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
549 "size %.0f\n", fsp_str_dbg(fsp),
550 (double)fsp->fsp_name->st.st_ex_size));
552 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
554 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
555 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
556 set_filelen_write_cache(fsp, len);
559 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
561 return ret;
564 /* Grow - we need to test if we have enough space. */
566 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
568 if (lp_strict_allocate(SNUM(fsp->conn))) {
569 /* See if we have a syscall that will allocate beyond
570 end-of-file without changing EOF. */
571 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
572 } else {
573 ret = 0;
576 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
578 if (ret == 0) {
579 /* We changed the allocation size on disk, but not
580 EOF - exactly as required. We're done ! */
581 return 0;
584 len -= fsp->fsp_name->st.st_ex_size;
585 len /= 1024; /* Len is now number of 1k blocks needed. */
586 space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
587 &bsize, &dfree, &dsize);
588 if (space_avail == (uint64_t)-1) {
589 return -1;
592 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
593 "needed blocks = %.0f, space avail = %.0f\n",
594 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
595 (double)space_avail));
597 if (len > space_avail) {
598 errno = ENOSPC;
599 return -1;
602 return 0;
605 /****************************************************************************
606 A vfs set_filelen call.
607 set the length of a file from a filedescriptor.
608 Returns 0 on success, -1 on failure.
609 ****************************************************************************/
611 int vfs_set_filelen(files_struct *fsp, off_t len)
613 int ret;
615 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
617 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
618 fsp_str_dbg(fsp), (double)len));
619 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
620 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
621 set_filelen_write_cache(fsp, len);
622 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
623 FILE_NOTIFY_CHANGE_SIZE
624 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
625 fsp->fsp_name->base_name);
628 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
630 return ret;
633 /****************************************************************************
634 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
635 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
636 as this is also called from the default SMB_VFS_FTRUNCATE code.
637 Always extends the file size.
638 Returns 0 on success, errno on failure.
639 ****************************************************************************/
641 #define SPARSE_BUF_WRITE_SIZE (32*1024)
643 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
645 ssize_t pwrite_ret;
646 size_t total = 0;
648 if (!sparse_buf) {
649 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
650 if (!sparse_buf) {
651 errno = ENOMEM;
652 return ENOMEM;
656 while (total < len) {
657 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
659 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
660 if (pwrite_ret == -1) {
661 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
662 "%s failed with error %s\n",
663 fsp_str_dbg(fsp), strerror(errno)));
664 return errno;
666 total += pwrite_ret;
669 return 0;
672 /****************************************************************************
673 A vfs fill sparse call.
674 Writes zeros from the end of file to len, if len is greater than EOF.
675 Used only by strict_sync.
676 Returns 0 on success, -1 on failure.
677 ****************************************************************************/
679 int vfs_fill_sparse(files_struct *fsp, off_t len)
681 int ret;
682 NTSTATUS status;
683 off_t offset;
684 size_t num_to_write;
686 status = vfs_stat_fsp(fsp);
687 if (!NT_STATUS_IS_OK(status)) {
688 return -1;
691 if (len <= fsp->fsp_name->st.st_ex_size) {
692 return 0;
695 #ifdef S_ISFIFO
696 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
697 return 0;
699 #endif
701 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
702 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
703 (double)fsp->fsp_name->st.st_ex_size, (double)len,
704 (double)(len - fsp->fsp_name->st.st_ex_size)));
706 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
708 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
710 offset = fsp->fsp_name->st.st_ex_size;
711 num_to_write = len - fsp->fsp_name->st.st_ex_size;
713 /* Only do this on non-stream file handles. */
714 if (fsp->base_fsp == NULL) {
715 /* for allocation try fallocate first. This can fail on some
716 * platforms e.g. when the filesystem doesn't support it and no
717 * emulation is being done by the libc (like on AIX with JFS1). In that
718 * case we do our own emulation. fallocate implementations can
719 * return ENOTSUP or EINVAL in cases like that. */
720 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
721 offset, num_to_write);
722 if (ret == ENOSPC) {
723 errno = ENOSPC;
724 ret = -1;
725 goto out;
727 if (ret == 0) {
728 goto out;
730 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
731 "error %d. Falling back to slow manual allocation\n", ret));
734 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
735 if (ret != 0) {
736 errno = ret;
737 ret = -1;
740 out:
742 if (ret == 0) {
743 set_filelen_write_cache(fsp, len);
746 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
747 return ret;
750 /****************************************************************************
751 Transfer some data (n bytes) between two file_struct's.
752 ****************************************************************************/
754 static ssize_t vfs_read_fn(void *file, void *buf, size_t len)
756 struct files_struct *fsp = (struct files_struct *)file;
758 return SMB_VFS_READ(fsp, buf, len);
761 static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
763 struct files_struct *fsp = (struct files_struct *)file;
765 return SMB_VFS_WRITE(fsp, buf, len);
768 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
770 return transfer_file_internal((void *)in, (void *)out, n,
771 vfs_read_fn, vfs_write_fn);
774 /*******************************************************************
775 A vfs_readdir wrapper which just returns the file name.
776 ********************************************************************/
778 const char *vfs_readdirname(connection_struct *conn, void *p,
779 SMB_STRUCT_STAT *sbuf, char **talloced)
781 struct dirent *ptr= NULL;
782 const char *dname;
783 char *translated;
784 NTSTATUS status;
786 if (!p)
787 return(NULL);
789 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
790 if (!ptr)
791 return(NULL);
793 dname = ptr->d_name;
796 #ifdef NEXT2
797 if (telldir(p) < 0)
798 return(NULL);
799 #endif
801 #ifdef HAVE_BROKEN_READDIR_NAME
802 /* using /usr/ucb/cc is BAD */
803 dname = dname - 2;
804 #endif
806 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
807 talloc_tos(), &translated);
808 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
809 *talloced = NULL;
810 return dname;
812 *talloced = translated;
813 if (!NT_STATUS_IS_OK(status)) {
814 return NULL;
816 return translated;
819 /*******************************************************************
820 A wrapper for vfs_chdir().
821 ********************************************************************/
823 int vfs_ChDir(connection_struct *conn, const char *path)
825 int ret;
827 if (!LastDir) {
828 LastDir = SMB_STRDUP("");
831 if (strcsequal(path,".")) {
832 return 0;
835 if (*path == '/' && strcsequal(LastDir,path)) {
836 return 0;
839 DEBUG(4,("vfs_ChDir to %s\n",path));
841 ret = SMB_VFS_CHDIR(conn,path);
842 if (ret == 0) {
843 /* Global cache. */
844 SAFE_FREE(LastDir);
845 LastDir = SMB_STRDUP(path);
847 /* conn cache. */
848 TALLOC_FREE(conn->cwd);
849 conn->cwd = vfs_GetWd(conn, conn);
850 DEBUG(4,("vfs_ChDir got %s\n",conn->cwd));
852 return ret;
855 /*******************************************************************
856 Return the absolute current directory path - given a UNIX pathname.
857 Note that this path is returned in DOS format, not UNIX
858 format. Note this can be called with conn == NULL.
859 ********************************************************************/
861 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
863 char *current_dir = NULL;
864 char *result = NULL;
865 DATA_BLOB cache_value;
866 struct file_id key;
867 struct smb_filename *smb_fname_dot = NULL;
868 struct smb_filename *smb_fname_full = NULL;
870 if (!lp_getwd_cache()) {
871 goto nocache;
874 smb_fname_dot = synthetic_smb_fname(ctx, ".", NULL, NULL);
875 if (smb_fname_dot == NULL) {
876 errno = ENOMEM;
877 goto out;
880 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
882 * Known to fail for root: the directory may be NFS-mounted
883 * and exported with root_squash (so has no root access).
885 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
886 "(NFS problem ?)\n", strerror(errno) ));
887 goto nocache;
890 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
892 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
893 data_blob_const(&key, sizeof(key)),
894 &cache_value)) {
895 goto nocache;
898 SMB_ASSERT((cache_value.length > 0)
899 && (cache_value.data[cache_value.length-1] == '\0'));
901 smb_fname_full = synthetic_smb_fname(ctx, (char *)cache_value.data,
902 NULL, NULL);
903 if (smb_fname_full == NULL) {
904 errno = ENOMEM;
905 goto out;
908 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
909 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
910 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
911 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
913 * Ok, we're done
915 result = talloc_strdup(ctx, smb_fname_full->base_name);
916 if (result == NULL) {
917 errno = ENOMEM;
919 goto out;
922 nocache:
925 * We don't have the information to hand so rely on traditional
926 * methods. The very slow getcwd, which spawns a process on some
927 * systems, or the not quite so bad getwd.
930 current_dir = SMB_VFS_GETWD(conn);
931 if (current_dir == NULL) {
932 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
933 strerror(errno)));
934 goto out;
937 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
938 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
940 memcache_add(smbd_memcache(), GETWD_CACHE,
941 data_blob_const(&key, sizeof(key)),
942 data_blob_const(current_dir,
943 strlen(current_dir)+1));
946 result = talloc_strdup(ctx, current_dir);
947 if (result == NULL) {
948 errno = ENOMEM;
951 out:
952 TALLOC_FREE(smb_fname_dot);
953 TALLOC_FREE(smb_fname_full);
954 SAFE_FREE(current_dir);
955 return result;
958 /*******************************************************************
959 Reduce a file name, removing .. elements and checking that
960 it is below dir in the heirachy. This uses realpath.
961 This function must run as root, and will return names
962 and valid stat structs that can be checked on open.
963 ********************************************************************/
965 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
966 const char *fname,
967 struct smb_request *smbreq)
969 NTSTATUS status;
970 TALLOC_CTX *ctx = talloc_tos();
971 const char *conn_rootdir;
972 size_t rootdir_len;
973 char *dir_name = NULL;
974 const char *last_component = NULL;
975 char *resolved_name = NULL;
976 char *saved_dir = NULL;
977 struct smb_filename *smb_fname_cwd = NULL;
978 struct privilege_paths *priv_paths = NULL;
979 int ret;
981 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
982 fname,
983 conn->connectpath));
986 priv_paths = talloc_zero(smbreq, struct privilege_paths);
987 if (!priv_paths) {
988 status = NT_STATUS_NO_MEMORY;
989 goto err;
992 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
993 status = NT_STATUS_NO_MEMORY;
994 goto err;
997 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
998 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
1000 if (priv_paths->parent_name.base_name == NULL ||
1001 priv_paths->file_name.base_name == NULL) {
1002 status = NT_STATUS_NO_MEMORY;
1003 goto err;
1006 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
1007 status = map_nt_error_from_unix(errno);
1008 goto err;
1010 /* Remember where we were. */
1011 saved_dir = vfs_GetWd(ctx, conn);
1012 if (!saved_dir) {
1013 status = map_nt_error_from_unix(errno);
1014 goto err;
1017 /* Go to the parent directory to lock in memory. */
1018 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
1019 status = map_nt_error_from_unix(errno);
1020 goto err;
1023 /* Get the absolute path of the parent directory. */
1024 resolved_name = SMB_VFS_REALPATH(conn,".");
1025 if (!resolved_name) {
1026 status = map_nt_error_from_unix(errno);
1027 goto err;
1030 if (*resolved_name != '/') {
1031 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1032 "doesn't return absolute paths !\n"));
1033 status = NT_STATUS_OBJECT_NAME_INVALID;
1034 goto err;
1037 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1038 priv_paths->parent_name.base_name,
1039 resolved_name));
1041 /* Now check the stat value is the same. */
1042 smb_fname_cwd = synthetic_smb_fname(talloc_tos(), ".", NULL, NULL);
1043 if (smb_fname_cwd == NULL) {
1044 status = NT_STATUS_NO_MEMORY;
1045 goto err;
1048 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1049 status = map_nt_error_from_unix(errno);
1050 goto err;
1053 /* Ensure we're pointing at the same place. */
1054 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1055 DEBUG(0,("check_reduced_name_with_privilege: "
1056 "device/inode/uid/gid on directory %s changed. "
1057 "Denying access !\n",
1058 priv_paths->parent_name.base_name));
1059 status = NT_STATUS_ACCESS_DENIED;
1060 goto err;
1063 /* Ensure we're below the connect path. */
1065 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1066 if (conn_rootdir == NULL) {
1067 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1068 "conn_rootdir\n"));
1069 status = NT_STATUS_ACCESS_DENIED;
1070 goto err;
1073 rootdir_len = strlen(conn_rootdir);
1074 if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1075 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1076 "attempt: %s is a symlink outside the "
1077 "share path\n",
1078 dir_name));
1079 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1080 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1081 status = NT_STATUS_ACCESS_DENIED;
1082 goto err;
1085 /* Now ensure that the last component either doesn't
1086 exist, or is *NOT* a symlink. */
1088 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1089 if (ret == -1) {
1090 /* Errno must be ENOENT for this be ok. */
1091 if (errno != ENOENT) {
1092 status = map_nt_error_from_unix(errno);
1093 DEBUG(2, ("check_reduced_name_with_privilege: "
1094 "LSTAT on %s failed with %s\n",
1095 priv_paths->file_name.base_name,
1096 nt_errstr(status)));
1097 goto err;
1101 if (VALID_STAT(priv_paths->file_name.st) &&
1102 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1103 DEBUG(2, ("check_reduced_name_with_privilege: "
1104 "Last component %s is a symlink. Denying"
1105 "access.\n",
1106 priv_paths->file_name.base_name));
1107 status = NT_STATUS_ACCESS_DENIED;
1108 goto err;
1111 smbreq->priv_paths = priv_paths;
1112 status = NT_STATUS_OK;
1114 err:
1116 if (saved_dir) {
1117 vfs_ChDir(conn, saved_dir);
1119 SAFE_FREE(resolved_name);
1120 if (!NT_STATUS_IS_OK(status)) {
1121 TALLOC_FREE(priv_paths);
1123 TALLOC_FREE(dir_name);
1124 return status;
1127 /*******************************************************************
1128 Reduce a file name, removing .. elements and checking that
1129 it is below dir in the heirachy. This uses realpath.
1130 ********************************************************************/
1132 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1134 char *resolved_name = NULL;
1135 bool allow_symlinks = true;
1136 bool allow_widelinks = false;
1138 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1140 resolved_name = SMB_VFS_REALPATH(conn,fname);
1142 if (!resolved_name) {
1143 switch (errno) {
1144 case ENOTDIR:
1145 DEBUG(3,("check_reduced_name: Component not a "
1146 "directory in getting realpath for "
1147 "%s\n", fname));
1148 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1149 case ENOENT:
1151 TALLOC_CTX *ctx = talloc_tos();
1152 char *dir_name = NULL;
1153 const char *last_component = NULL;
1154 char *new_name = NULL;
1155 int ret;
1157 /* Last component didn't exist.
1158 Remove it and try and canonicalise
1159 the directory name. */
1160 if (!parent_dirname(ctx, fname,
1161 &dir_name,
1162 &last_component)) {
1163 return NT_STATUS_NO_MEMORY;
1166 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1167 if (!resolved_name) {
1168 NTSTATUS status = map_nt_error_from_unix(errno);
1170 if (errno == ENOENT || errno == ENOTDIR) {
1171 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1174 DEBUG(3,("check_reduce_name: "
1175 "couldn't get realpath for "
1176 "%s (%s)\n",
1177 fname,
1178 nt_errstr(status)));
1179 return status;
1181 ret = asprintf(&new_name, "%s/%s",
1182 resolved_name, last_component);
1183 SAFE_FREE(resolved_name);
1184 if (ret == -1) {
1185 return NT_STATUS_NO_MEMORY;
1187 resolved_name = new_name;
1188 break;
1190 default:
1191 DEBUG(3,("check_reduced_name: couldn't get "
1192 "realpath for %s\n", fname));
1193 return map_nt_error_from_unix(errno);
1197 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1198 resolved_name));
1200 if (*resolved_name != '/') {
1201 DEBUG(0,("check_reduced_name: realpath doesn't return "
1202 "absolute paths !\n"));
1203 SAFE_FREE(resolved_name);
1204 return NT_STATUS_OBJECT_NAME_INVALID;
1207 allow_widelinks = lp_widelinks(SNUM(conn));
1208 allow_symlinks = lp_symlinks(SNUM(conn));
1210 /* Common widelinks and symlinks checks. */
1211 if (!allow_widelinks || !allow_symlinks) {
1212 const char *conn_rootdir;
1213 size_t rootdir_len;
1215 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1216 if (conn_rootdir == NULL) {
1217 DEBUG(2, ("check_reduced_name: Could not get "
1218 "conn_rootdir\n"));
1219 SAFE_FREE(resolved_name);
1220 return NT_STATUS_ACCESS_DENIED;
1223 rootdir_len = strlen(conn_rootdir);
1224 if (strncmp(conn_rootdir, resolved_name,
1225 rootdir_len) != 0) {
1226 DEBUG(2, ("check_reduced_name: Bad access "
1227 "attempt: %s is a symlink outside the "
1228 "share path\n", fname));
1229 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1230 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1231 SAFE_FREE(resolved_name);
1232 return NT_STATUS_ACCESS_DENIED;
1235 /* Extra checks if all symlinks are disallowed. */
1236 if (!allow_symlinks) {
1237 /* fname can't have changed in resolved_path. */
1238 const char *p = &resolved_name[rootdir_len];
1240 /* *p can be '\0' if fname was "." */
1241 if (*p == '\0' && ISDOT(fname)) {
1242 goto out;
1245 if (*p != '/') {
1246 DEBUG(2, ("check_reduced_name: logic error (%c) "
1247 "in resolved_name: %s\n",
1249 fname));
1250 SAFE_FREE(resolved_name);
1251 return NT_STATUS_ACCESS_DENIED;
1254 p++;
1255 if (strcmp(fname, p)!=0) {
1256 DEBUG(2, ("check_reduced_name: Bad access "
1257 "attempt: %s is a symlink to %s\n",
1258 fname, p));
1259 SAFE_FREE(resolved_name);
1260 return NT_STATUS_ACCESS_DENIED;
1265 out:
1267 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1268 resolved_name));
1269 SAFE_FREE(resolved_name);
1270 return NT_STATUS_OK;
1274 * XXX: This is temporary and there should be no callers of this once
1275 * smb_filename is plumbed through all path based operations.
1277 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1278 SMB_STRUCT_STAT *psbuf)
1280 struct smb_filename *smb_fname;
1281 int ret;
1283 smb_fname = synthetic_smb_fname_split(talloc_tos(), fname, NULL);
1284 if (smb_fname == NULL) {
1285 errno = ENOMEM;
1286 return -1;
1289 if (lp_posix_pathnames()) {
1290 ret = SMB_VFS_LSTAT(conn, smb_fname);
1291 } else {
1292 ret = SMB_VFS_STAT(conn, smb_fname);
1295 if (ret != -1) {
1296 *psbuf = smb_fname->st;
1299 TALLOC_FREE(smb_fname);
1300 return ret;
1304 * XXX: This is temporary and there should be no callers of this once
1305 * smb_filename is plumbed through all path based operations.
1307 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1308 SMB_STRUCT_STAT *psbuf)
1310 struct smb_filename *smb_fname;
1311 int ret;
1313 smb_fname = synthetic_smb_fname_split(talloc_tos(), fname, NULL);
1314 if (smb_fname == NULL) {
1315 errno = ENOMEM;
1316 return -1;
1319 ret = SMB_VFS_LSTAT(conn, smb_fname);
1320 if (ret != -1) {
1321 *psbuf = smb_fname->st;
1324 TALLOC_FREE(smb_fname);
1325 return ret;
1329 * Ensure LSTAT is called for POSIX paths.
1332 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1334 int ret;
1336 if(fsp->fh->fd == -1) {
1337 if (fsp->posix_open) {
1338 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1339 } else {
1340 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1342 if (ret == -1) {
1343 return map_nt_error_from_unix(errno);
1345 } else {
1346 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1347 return map_nt_error_from_unix(errno);
1350 return NT_STATUS_OK;
1354 * Initialize num_streams and streams, then call VFS op streaminfo
1356 NTSTATUS vfs_streaminfo(connection_struct *conn,
1357 struct files_struct *fsp,
1358 const char *fname,
1359 TALLOC_CTX *mem_ctx,
1360 unsigned int *num_streams,
1361 struct stream_struct **streams)
1363 *num_streams = 0;
1364 *streams = NULL;
1365 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1369 generate a file_id from a stat structure
1371 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1373 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1376 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1377 const char *service, const char *user)
1379 VFS_FIND(connect);
1380 return handle->fns->connect_fn(handle, service, user);
1383 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1385 VFS_FIND(disconnect);
1386 handle->fns->disconnect_fn(handle);
1389 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1390 const char *path, bool small_query,
1391 uint64_t *bsize, uint64_t *dfree,
1392 uint64_t *dsize)
1394 VFS_FIND(disk_free);
1395 return handle->fns->disk_free_fn(handle, path, small_query, bsize,
1396 dfree, dsize);
1399 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1400 enum SMB_QUOTA_TYPE qtype, unid_t id,
1401 SMB_DISK_QUOTA *qt)
1403 VFS_FIND(get_quota);
1404 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1407 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1408 enum SMB_QUOTA_TYPE qtype, unid_t id,
1409 SMB_DISK_QUOTA *qt)
1411 VFS_FIND(set_quota);
1412 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1415 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1416 struct files_struct *fsp,
1417 struct shadow_copy_data *shadow_copy_data,
1418 bool labels)
1420 VFS_FIND(get_shadow_copy_data);
1421 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1422 shadow_copy_data,
1423 labels);
1425 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1426 struct vfs_statvfs_struct *statbuf)
1428 VFS_FIND(statvfs);
1429 return handle->fns->statvfs_fn(handle, path, statbuf);
1432 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1433 enum timestamp_set_resolution *p_ts_res)
1435 VFS_FIND(fs_capabilities);
1436 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1439 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1440 struct dfs_GetDFSReferral *r)
1442 VFS_FIND(get_dfs_referrals);
1443 return handle->fns->get_dfs_referrals_fn(handle, r);
1446 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1447 const char *fname, const char *mask,
1448 uint32 attributes)
1450 VFS_FIND(opendir);
1451 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1454 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1455 struct files_struct *fsp,
1456 const char *mask,
1457 uint32 attributes)
1459 VFS_FIND(fdopendir);
1460 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1463 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1464 DIR *dirp,
1465 SMB_STRUCT_STAT *sbuf)
1467 VFS_FIND(readdir);
1468 return handle->fns->readdir_fn(handle, dirp, sbuf);
1471 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1472 DIR *dirp, long offset)
1474 VFS_FIND(seekdir);
1475 handle->fns->seekdir_fn(handle, dirp, offset);
1478 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1479 DIR *dirp)
1481 VFS_FIND(telldir);
1482 return handle->fns->telldir_fn(handle, dirp);
1485 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1486 DIR *dirp)
1488 VFS_FIND(rewind_dir);
1489 handle->fns->rewind_dir_fn(handle, dirp);
1492 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1493 mode_t mode)
1495 VFS_FIND(mkdir);
1496 return handle->fns->mkdir_fn(handle, path, mode);
1499 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1501 VFS_FIND(rmdir);
1502 return handle->fns->rmdir_fn(handle, path);
1505 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1506 DIR *dir)
1508 VFS_FIND(closedir);
1509 return handle->fns->closedir_fn(handle, dir);
1512 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1513 DIR *dirp)
1515 VFS_FIND(init_search_op);
1516 handle->fns->init_search_op_fn(handle, dirp);
1519 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1520 struct smb_filename *smb_fname, struct files_struct *fsp,
1521 int flags, mode_t mode)
1523 VFS_FIND(open);
1524 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1527 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1528 struct smb_request *req,
1529 uint16_t root_dir_fid,
1530 struct smb_filename *smb_fname,
1531 uint32_t access_mask,
1532 uint32_t share_access,
1533 uint32_t create_disposition,
1534 uint32_t create_options,
1535 uint32_t file_attributes,
1536 uint32_t oplock_request,
1537 uint64_t allocation_size,
1538 uint32_t private_flags,
1539 struct security_descriptor *sd,
1540 struct ea_list *ea_list,
1541 files_struct **result,
1542 int *pinfo)
1544 VFS_FIND(create_file);
1545 return handle->fns->create_file_fn(
1546 handle, req, root_dir_fid, smb_fname, access_mask,
1547 share_access, create_disposition, create_options,
1548 file_attributes, oplock_request, allocation_size,
1549 private_flags, sd, ea_list,
1550 result, pinfo);
1553 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1554 struct files_struct *fsp)
1556 VFS_FIND(close);
1557 return handle->fns->close_fn(handle, fsp);
1560 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1561 struct files_struct *fsp, void *data, size_t n)
1563 VFS_FIND(read);
1564 return handle->fns->read_fn(handle, fsp, data, n);
1567 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1568 struct files_struct *fsp, void *data, size_t n,
1569 off_t offset)
1571 VFS_FIND(pread);
1572 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1575 struct smb_vfs_call_pread_state {
1576 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1577 ssize_t retval;
1580 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1582 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1583 TALLOC_CTX *mem_ctx,
1584 struct tevent_context *ev,
1585 struct files_struct *fsp,
1586 void *data,
1587 size_t n, off_t offset)
1589 struct tevent_req *req, *subreq;
1590 struct smb_vfs_call_pread_state *state;
1592 req = tevent_req_create(mem_ctx, &state,
1593 struct smb_vfs_call_pread_state);
1594 if (req == NULL) {
1595 return NULL;
1597 VFS_FIND(pread_send);
1598 state->recv_fn = handle->fns->pread_recv_fn;
1600 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1601 offset);
1602 if (tevent_req_nomem(subreq, req)) {
1603 return tevent_req_post(req, ev);
1605 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1606 return req;
1609 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1611 struct tevent_req *req = tevent_req_callback_data(
1612 subreq, struct tevent_req);
1613 struct smb_vfs_call_pread_state *state = tevent_req_data(
1614 req, struct smb_vfs_call_pread_state);
1615 int err;
1617 state->retval = state->recv_fn(subreq, &err);
1618 TALLOC_FREE(subreq);
1619 if (state->retval == -1) {
1620 tevent_req_error(req, err);
1621 return;
1623 tevent_req_done(req);
1626 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req, int *perrno)
1628 struct smb_vfs_call_pread_state *state = tevent_req_data(
1629 req, struct smb_vfs_call_pread_state);
1630 int err;
1632 if (tevent_req_is_unix_error(req, &err)) {
1633 *perrno = err;
1634 return -1;
1636 return state->retval;
1639 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1640 struct files_struct *fsp, const void *data,
1641 size_t n)
1643 VFS_FIND(write);
1644 return handle->fns->write_fn(handle, fsp, data, n);
1647 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1648 struct files_struct *fsp, const void *data,
1649 size_t n, off_t offset)
1651 VFS_FIND(pwrite);
1652 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1655 struct smb_vfs_call_pwrite_state {
1656 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1657 ssize_t retval;
1660 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1662 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1663 TALLOC_CTX *mem_ctx,
1664 struct tevent_context *ev,
1665 struct files_struct *fsp,
1666 const void *data,
1667 size_t n, off_t offset)
1669 struct tevent_req *req, *subreq;
1670 struct smb_vfs_call_pwrite_state *state;
1672 req = tevent_req_create(mem_ctx, &state,
1673 struct smb_vfs_call_pwrite_state);
1674 if (req == NULL) {
1675 return NULL;
1677 VFS_FIND(pwrite_send);
1678 state->recv_fn = handle->fns->pwrite_recv_fn;
1680 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1681 offset);
1682 if (tevent_req_nomem(subreq, req)) {
1683 return tevent_req_post(req, ev);
1685 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1686 return req;
1689 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1691 struct tevent_req *req = tevent_req_callback_data(
1692 subreq, struct tevent_req);
1693 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1694 req, struct smb_vfs_call_pwrite_state);
1695 int err;
1697 state->retval = state->recv_fn(subreq, &err);
1698 TALLOC_FREE(subreq);
1699 if (state->retval == -1) {
1700 tevent_req_error(req, err);
1701 return;
1703 tevent_req_done(req);
1706 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req, int *perrno)
1708 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1709 req, struct smb_vfs_call_pwrite_state);
1710 int err;
1712 if (tevent_req_is_unix_error(req, &err)) {
1713 *perrno = err;
1714 return -1;
1716 return state->retval;
1719 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1720 struct files_struct *fsp, off_t offset,
1721 int whence)
1723 VFS_FIND(lseek);
1724 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1727 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1728 files_struct *fromfsp, const DATA_BLOB *header,
1729 off_t offset, size_t count)
1731 VFS_FIND(sendfile);
1732 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1733 count);
1736 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1737 files_struct *tofsp, off_t offset,
1738 size_t count)
1740 VFS_FIND(recvfile);
1741 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1744 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1745 const struct smb_filename *smb_fname_src,
1746 const struct smb_filename *smb_fname_dst)
1748 VFS_FIND(rename);
1749 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1752 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1753 struct files_struct *fsp)
1755 VFS_FIND(fsync);
1756 return handle->fns->fsync_fn(handle, fsp);
1759 struct smb_vfs_call_fsync_state {
1760 int (*recv_fn)(struct tevent_req *req, int *err);
1761 int retval;
1764 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1766 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1767 TALLOC_CTX *mem_ctx,
1768 struct tevent_context *ev,
1769 struct files_struct *fsp)
1771 struct tevent_req *req, *subreq;
1772 struct smb_vfs_call_fsync_state *state;
1774 req = tevent_req_create(mem_ctx, &state,
1775 struct smb_vfs_call_fsync_state);
1776 if (req == NULL) {
1777 return NULL;
1779 VFS_FIND(fsync_send);
1780 state->recv_fn = handle->fns->fsync_recv_fn;
1782 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1783 if (tevent_req_nomem(subreq, req)) {
1784 return tevent_req_post(req, ev);
1786 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1787 return req;
1790 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1792 struct tevent_req *req = tevent_req_callback_data(
1793 subreq, struct tevent_req);
1794 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1795 req, struct smb_vfs_call_fsync_state);
1796 int err;
1798 state->retval = state->recv_fn(subreq, &err);
1799 TALLOC_FREE(subreq);
1800 if (state->retval == -1) {
1801 tevent_req_error(req, err);
1802 return;
1804 tevent_req_done(req);
1807 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, int *perrno)
1809 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1810 req, struct smb_vfs_call_fsync_state);
1811 int err;
1813 if (tevent_req_is_unix_error(req, &err)) {
1814 *perrno = err;
1815 return -1;
1817 return state->retval;
1821 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1822 struct smb_filename *smb_fname)
1824 VFS_FIND(stat);
1825 return handle->fns->stat_fn(handle, smb_fname);
1828 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1829 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1831 VFS_FIND(fstat);
1832 return handle->fns->fstat_fn(handle, fsp, sbuf);
1835 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1836 struct smb_filename *smb_filename)
1838 VFS_FIND(lstat);
1839 return handle->fns->lstat_fn(handle, smb_filename);
1842 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1843 struct files_struct *fsp,
1844 const SMB_STRUCT_STAT *sbuf)
1846 VFS_FIND(get_alloc_size);
1847 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1850 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1851 const struct smb_filename *smb_fname)
1853 VFS_FIND(unlink);
1854 return handle->fns->unlink_fn(handle, smb_fname);
1857 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1858 mode_t mode)
1860 VFS_FIND(chmod);
1861 return handle->fns->chmod_fn(handle, path, mode);
1864 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1865 struct files_struct *fsp, mode_t mode)
1867 VFS_FIND(fchmod);
1868 return handle->fns->fchmod_fn(handle, fsp, mode);
1871 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1872 uid_t uid, gid_t gid)
1874 VFS_FIND(chown);
1875 return handle->fns->chown_fn(handle, path, uid, gid);
1878 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1879 struct files_struct *fsp, uid_t uid, gid_t gid)
1881 VFS_FIND(fchown);
1882 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1885 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1886 uid_t uid, gid_t gid)
1888 VFS_FIND(lchown);
1889 return handle->fns->lchown_fn(handle, path, uid, gid);
1892 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1894 int ret;
1895 bool as_root = false;
1896 const char *path;
1897 char *saved_dir = NULL;
1898 char *parent_dir = NULL;
1899 NTSTATUS status;
1901 if (fsp->fh->fd != -1) {
1902 /* Try fchown. */
1903 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1904 if (ret == 0) {
1905 return NT_STATUS_OK;
1907 if (ret == -1 && errno != ENOSYS) {
1908 return map_nt_error_from_unix(errno);
1912 as_root = (geteuid() == 0);
1914 if (as_root) {
1916 * We are being asked to chown as root. Make
1917 * sure we chdir() into the path to pin it,
1918 * and always act using lchown to ensure we
1919 * don't deref any symbolic links.
1921 const char *final_component = NULL;
1922 struct smb_filename local_fname;
1924 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1925 if (!saved_dir) {
1926 status = map_nt_error_from_unix(errno);
1927 DEBUG(0,("vfs_chown_fsp: failed to get "
1928 "current working directory. Error was %s\n",
1929 strerror(errno)));
1930 return status;
1933 if (!parent_dirname(talloc_tos(),
1934 fsp->fsp_name->base_name,
1935 &parent_dir,
1936 &final_component)) {
1937 return NT_STATUS_NO_MEMORY;
1940 /* cd into the parent dir to pin it. */
1941 ret = vfs_ChDir(fsp->conn, parent_dir);
1942 if (ret == -1) {
1943 return map_nt_error_from_unix(errno);
1946 ZERO_STRUCT(local_fname);
1947 local_fname.base_name = discard_const_p(char, final_component);
1949 /* Must use lstat here. */
1950 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1951 if (ret == -1) {
1952 status = map_nt_error_from_unix(errno);
1953 goto out;
1956 /* Ensure it matches the fsp stat. */
1957 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1958 status = NT_STATUS_ACCESS_DENIED;
1959 goto out;
1961 path = final_component;
1962 } else {
1963 path = fsp->fsp_name->base_name;
1966 if (fsp->posix_open || as_root) {
1967 ret = SMB_VFS_LCHOWN(fsp->conn,
1968 path,
1969 uid, gid);
1970 } else {
1971 ret = SMB_VFS_CHOWN(fsp->conn,
1972 path,
1973 uid, gid);
1976 if (ret == 0) {
1977 status = NT_STATUS_OK;
1978 } else {
1979 status = map_nt_error_from_unix(errno);
1982 out:
1984 if (as_root) {
1985 vfs_ChDir(fsp->conn,saved_dir);
1986 TALLOC_FREE(saved_dir);
1987 TALLOC_FREE(parent_dir);
1989 return status;
1992 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1994 VFS_FIND(chdir);
1995 return handle->fns->chdir_fn(handle, path);
1998 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
2000 VFS_FIND(getwd);
2001 return handle->fns->getwd_fn(handle);
2004 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
2005 const struct smb_filename *smb_fname,
2006 struct smb_file_time *ft)
2008 VFS_FIND(ntimes);
2009 return handle->fns->ntimes_fn(handle, smb_fname, ft);
2012 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2013 struct files_struct *fsp, off_t offset)
2015 VFS_FIND(ftruncate);
2016 return handle->fns->ftruncate_fn(handle, fsp, offset);
2019 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2020 struct files_struct *fsp,
2021 enum vfs_fallocate_mode mode,
2022 off_t offset,
2023 off_t len)
2025 VFS_FIND(fallocate);
2026 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2029 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2030 struct files_struct *fsp, uint32 share_mode,
2031 uint32_t access_mask)
2033 VFS_FIND(kernel_flock);
2034 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2035 access_mask);
2038 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2039 struct files_struct *fsp, int leasetype)
2041 VFS_FIND(linux_setlease);
2042 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2045 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
2046 const char *newpath)
2048 VFS_FIND(symlink);
2049 return handle->fns->symlink_fn(handle, oldpath, newpath);
2052 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2053 const char *path, char *buf, size_t bufsiz)
2055 VFS_FIND(readlink);
2056 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
2059 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
2060 const char *newpath)
2062 VFS_FIND(link);
2063 return handle->fns->link_fn(handle, oldpath, newpath);
2066 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
2067 mode_t mode, SMB_DEV_T dev)
2069 VFS_FIND(mknod);
2070 return handle->fns->mknod_fn(handle, path, mode, dev);
2073 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
2075 VFS_FIND(realpath);
2076 return handle->fns->realpath_fn(handle, path);
2079 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
2080 struct sys_notify_context *ctx,
2081 const char *path,
2082 uint32_t *filter,
2083 uint32_t *subdir_filter,
2084 void (*callback)(struct sys_notify_context *ctx,
2085 void *private_data,
2086 struct notify_event *ev),
2087 void *private_data, void *handle_p)
2089 VFS_FIND(notify_watch);
2090 return handle->fns->notify_watch_fn(handle, ctx, path,
2091 filter, subdir_filter, callback,
2092 private_data, handle_p);
2095 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
2096 unsigned int flags)
2098 VFS_FIND(chflags);
2099 return handle->fns->chflags_fn(handle, path, flags);
2102 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2103 const SMB_STRUCT_STAT *sbuf)
2105 VFS_FIND(file_id_create);
2106 return handle->fns->file_id_create_fn(handle, sbuf);
2109 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2110 struct files_struct *fsp,
2111 const char *fname,
2112 TALLOC_CTX *mem_ctx,
2113 unsigned int *num_streams,
2114 struct stream_struct **streams)
2116 VFS_FIND(streaminfo);
2117 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
2118 num_streams, streams);
2121 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2122 const char *path, const char *name,
2123 TALLOC_CTX *mem_ctx, char **found_name)
2125 VFS_FIND(get_real_filename);
2126 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2127 found_name);
2130 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2131 const char *filename)
2133 VFS_FIND(connectpath);
2134 return handle->fns->connectpath_fn(handle, filename);
2137 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2138 struct files_struct *fsp,
2139 struct lock_struct *plock)
2141 VFS_FIND(strict_lock);
2142 return handle->fns->strict_lock_fn(handle, fsp, plock);
2145 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2146 struct files_struct *fsp,
2147 struct lock_struct *plock)
2149 VFS_FIND(strict_unlock);
2150 handle->fns->strict_unlock_fn(handle, fsp, plock);
2153 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2154 const char *name,
2155 enum vfs_translate_direction direction,
2156 TALLOC_CTX *mem_ctx,
2157 char **mapped_name)
2159 VFS_FIND(translate_name);
2160 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2161 mapped_name);
2164 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2165 struct files_struct *fsp,
2166 TALLOC_CTX *ctx,
2167 uint32_t function,
2168 uint16_t req_flags,
2169 const uint8_t *in_data,
2170 uint32_t in_len,
2171 uint8_t **out_data,
2172 uint32_t max_out_len,
2173 uint32_t *out_len)
2175 VFS_FIND(fsctl);
2176 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2177 in_data, in_len, out_data, max_out_len,
2178 out_len);
2181 struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle,
2182 TALLOC_CTX *mem_ctx,
2183 struct tevent_context *ev,
2184 struct files_struct *src_fsp,
2185 off_t src_off,
2186 struct files_struct *dest_fsp,
2187 off_t dest_off,
2188 off_t num)
2190 VFS_FIND(copy_chunk_send);
2191 return handle->fns->copy_chunk_send_fn(handle, mem_ctx, ev, src_fsp,
2192 src_off, dest_fsp, dest_off, num);
2195 NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,
2196 struct tevent_req *req,
2197 off_t *copied)
2199 VFS_FIND(copy_chunk_recv);
2200 return handle->fns->copy_chunk_recv_fn(handle, req, copied);
2203 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2204 struct files_struct *fsp,
2205 uint32 security_info,
2206 TALLOC_CTX *mem_ctx,
2207 struct security_descriptor **ppdesc)
2209 VFS_FIND(fget_nt_acl);
2210 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2211 mem_ctx, ppdesc);
2214 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2215 const char *name,
2216 uint32 security_info,
2217 TALLOC_CTX *mem_ctx,
2218 struct security_descriptor **ppdesc)
2220 VFS_FIND(get_nt_acl);
2221 return handle->fns->get_nt_acl_fn(handle, name, security_info, mem_ctx, ppdesc);
2224 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2225 struct files_struct *fsp,
2226 uint32 security_info_sent,
2227 const struct security_descriptor *psd)
2229 VFS_FIND(fset_nt_acl);
2230 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2231 psd);
2234 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2235 struct smb_filename *file,
2236 struct security_acl *sacl,
2237 uint32_t access_requested,
2238 uint32_t access_denied)
2240 VFS_FIND(audit_file);
2241 return handle->fns->audit_file_fn(handle,
2242 file,
2243 sacl,
2244 access_requested,
2245 access_denied);
2248 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2249 mode_t mode)
2251 VFS_FIND(chmod_acl);
2252 return handle->fns->chmod_acl_fn(handle, name, mode);
2255 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2256 struct files_struct *fsp, mode_t mode)
2258 VFS_FIND(fchmod_acl);
2259 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2262 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2263 const char *path_p,
2264 SMB_ACL_TYPE_T type,
2265 TALLOC_CTX *mem_ctx)
2267 VFS_FIND(sys_acl_get_file);
2268 return handle->fns->sys_acl_get_file_fn(handle, path_p, type, mem_ctx);
2271 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2272 struct files_struct *fsp,
2273 TALLOC_CTX *mem_ctx)
2275 VFS_FIND(sys_acl_get_fd);
2276 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2279 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2280 const char *path_p,
2281 TALLOC_CTX *mem_ctx,
2282 char **blob_description,
2283 DATA_BLOB *blob)
2285 VFS_FIND(sys_acl_blob_get_file);
2286 return handle->fns->sys_acl_blob_get_file_fn(handle, path_p, mem_ctx, blob_description, blob);
2289 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2290 struct files_struct *fsp,
2291 TALLOC_CTX *mem_ctx,
2292 char **blob_description,
2293 DATA_BLOB *blob)
2295 VFS_FIND(sys_acl_blob_get_fd);
2296 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2299 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2300 const char *name, SMB_ACL_TYPE_T acltype,
2301 SMB_ACL_T theacl)
2303 VFS_FIND(sys_acl_set_file);
2304 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2307 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2308 struct files_struct *fsp, SMB_ACL_T theacl)
2310 VFS_FIND(sys_acl_set_fd);
2311 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2314 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2315 const char *path)
2317 VFS_FIND(sys_acl_delete_def_file);
2318 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2321 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2322 const char *path, const char *name, void *value,
2323 size_t size)
2325 VFS_FIND(getxattr);
2326 return handle->fns->getxattr_fn(handle, path, name, value, size);
2329 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2330 struct files_struct *fsp, const char *name,
2331 void *value, size_t size)
2333 VFS_FIND(fgetxattr);
2334 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2337 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2338 const char *path, char *list, size_t size)
2340 VFS_FIND(listxattr);
2341 return handle->fns->listxattr_fn(handle, path, list, size);
2344 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2345 struct files_struct *fsp, char *list,
2346 size_t size)
2348 VFS_FIND(flistxattr);
2349 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2352 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2353 const char *path, const char *name)
2355 VFS_FIND(removexattr);
2356 return handle->fns->removexattr_fn(handle, path, name);
2359 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2360 struct files_struct *fsp, const char *name)
2362 VFS_FIND(fremovexattr);
2363 return handle->fns->fremovexattr_fn(handle, fsp, name);
2366 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2367 const char *name, const void *value, size_t size,
2368 int flags)
2370 VFS_FIND(setxattr);
2371 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2374 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2375 struct files_struct *fsp, const char *name,
2376 const void *value, size_t size, int flags)
2378 VFS_FIND(fsetxattr);
2379 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2382 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2383 struct files_struct *fsp)
2385 VFS_FIND(aio_force);
2386 return handle->fns->aio_force_fn(handle, fsp);
2389 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2390 const struct smb_filename *fname,
2391 SMB_STRUCT_STAT *sbuf)
2393 VFS_FIND(is_offline);
2394 return handle->fns->is_offline_fn(handle, fname, sbuf);
2397 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2398 const struct smb_filename *fname)
2400 VFS_FIND(set_offline);
2401 return handle->fns->set_offline_fn(handle, fname);
2404 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2405 struct files_struct *fsp,
2406 TALLOC_CTX *mem_ctx,
2407 DATA_BLOB *cookie)
2409 VFS_FIND(durable_cookie);
2410 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2413 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2414 struct files_struct *fsp,
2415 const DATA_BLOB old_cookie,
2416 TALLOC_CTX *mem_ctx,
2417 DATA_BLOB *new_cookie)
2419 VFS_FIND(durable_disconnect);
2420 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2421 mem_ctx, new_cookie);
2424 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2425 struct smb_request *smb1req,
2426 struct smbXsrv_open *op,
2427 const DATA_BLOB old_cookie,
2428 TALLOC_CTX *mem_ctx,
2429 struct files_struct **fsp,
2430 DATA_BLOB *new_cookie)
2432 VFS_FIND(durable_reconnect);
2433 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2434 old_cookie, mem_ctx, fsp,
2435 new_cookie);