smbd: Add direct notify_fam support
[Samba.git] / source3 / smbd / vfs.c
blobb2673879f5a4aa64f8b2607df45f064e2815d794
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 "../lib/util/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_t *)(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 /****************************************************************************
397 Write data to a fd on the vfs.
398 ****************************************************************************/
400 ssize_t vfs_write_data(struct smb_request *req,
401 files_struct *fsp,
402 const char *buffer,
403 size_t N)
405 size_t total=0;
406 ssize_t ret;
408 if (req && req->unread_bytes) {
409 int sockfd = req->xconn->transport.sock;
410 int old_flags;
411 SMB_ASSERT(req->unread_bytes == N);
412 /* VFS_RECVFILE must drain the socket
413 * before returning. */
414 req->unread_bytes = 0;
415 /* Ensure the socket is blocking. */
416 old_flags = fcntl(sockfd, F_GETFL, 0);
417 if (set_blocking(sockfd, true) == -1) {
418 return (ssize_t)-1;
420 ret = SMB_VFS_RECVFILE(sockfd,
421 fsp,
422 (off_t)-1,
424 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
425 return (ssize_t)-1;
427 return ret;
430 while (total < N) {
431 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
433 if (ret == -1)
434 return -1;
435 if (ret == 0)
436 return total;
438 total += ret;
440 return (ssize_t)total;
443 ssize_t vfs_pwrite_data(struct smb_request *req,
444 files_struct *fsp,
445 const char *buffer,
446 size_t N,
447 off_t offset)
449 size_t total=0;
450 ssize_t ret;
452 if (req && req->unread_bytes) {
453 int sockfd = req->xconn->transport.sock;
454 SMB_ASSERT(req->unread_bytes == N);
455 /* VFS_RECVFILE must drain the socket
456 * before returning. */
457 req->unread_bytes = 0;
459 * Leave the socket non-blocking and
460 * use SMB_VFS_RECVFILE. If it returns
461 * EAGAIN || EWOULDBLOCK temporarily set
462 * the socket blocking and retry
463 * the RECVFILE.
465 while (total < N) {
466 ret = SMB_VFS_RECVFILE(sockfd,
467 fsp,
468 offset + total,
469 N - total);
470 if (ret == 0 || (ret == -1 &&
471 (errno == EAGAIN ||
472 errno == EWOULDBLOCK))) {
473 int old_flags;
474 /* Ensure the socket is blocking. */
475 old_flags = fcntl(sockfd, F_GETFL, 0);
476 if (set_blocking(sockfd, true) == -1) {
477 return (ssize_t)-1;
479 ret = SMB_VFS_RECVFILE(sockfd,
480 fsp,
481 offset + total,
482 N - total);
483 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
484 return (ssize_t)-1;
486 if (ret == -1) {
487 return (ssize_t)-1;
489 total += ret;
490 return (ssize_t)total;
492 /* Any other error case. */
493 if (ret == -1) {
494 return ret;
496 total += ret;
498 return (ssize_t)total;
501 while (total < N) {
502 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
503 offset + total);
505 if (ret == -1)
506 return -1;
507 if (ret == 0)
508 return total;
510 total += ret;
512 return (ssize_t)total;
514 /****************************************************************************
515 An allocate file space call using the vfs interface.
516 Allocates space for a file from a filedescriptor.
517 Returns 0 on success, -1 on failure.
518 ****************************************************************************/
520 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
522 int ret;
523 connection_struct *conn = fsp->conn;
524 uint64_t space_avail;
525 uint64_t bsize,dfree,dsize;
526 NTSTATUS status;
529 * Actually try and commit the space on disk....
532 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
533 fsp_str_dbg(fsp), (double)len));
535 if (((off_t)len) < 0) {
536 DEBUG(0,("vfs_allocate_file_space: %s negative len "
537 "requested.\n", fsp_str_dbg(fsp)));
538 errno = EINVAL;
539 return -1;
542 status = vfs_stat_fsp(fsp);
543 if (!NT_STATUS_IS_OK(status)) {
544 return -1;
547 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
548 return 0;
550 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
551 /* Shrink - use ftruncate. */
553 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
554 "size %.0f\n", fsp_str_dbg(fsp),
555 (double)fsp->fsp_name->st.st_ex_size));
557 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
559 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
560 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
561 set_filelen_write_cache(fsp, len);
564 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
566 return ret;
569 /* Grow - we need to test if we have enough space. */
571 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
573 if (lp_strict_allocate(SNUM(fsp->conn))) {
574 /* See if we have a syscall that will allocate beyond
575 end-of-file without changing EOF. */
576 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_FL_KEEP_SIZE,
577 0, len);
578 } else {
579 ret = 0;
582 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
584 if (ret == 0) {
585 /* We changed the allocation size on disk, but not
586 EOF - exactly as required. We're done ! */
587 return 0;
590 if (ret == -1 && errno == ENOSPC) {
591 return -1;
594 len -= fsp->fsp_name->st.st_ex_size;
595 len /= 1024; /* Len is now number of 1k blocks needed. */
596 space_avail = get_dfree_info(conn, fsp->fsp_name->base_name,
597 &bsize, &dfree, &dsize);
598 if (space_avail == (uint64_t)-1) {
599 return -1;
602 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
603 "needed blocks = %.0f, space avail = %.0f\n",
604 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
605 (double)space_avail));
607 if (len > space_avail) {
608 errno = ENOSPC;
609 return -1;
612 return 0;
615 /****************************************************************************
616 A vfs set_filelen call.
617 set the length of a file from a filedescriptor.
618 Returns 0 on success, -1 on failure.
619 ****************************************************************************/
621 int vfs_set_filelen(files_struct *fsp, off_t len)
623 int ret;
625 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
627 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
628 fsp_str_dbg(fsp), (double)len));
629 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
630 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
631 set_filelen_write_cache(fsp, len);
632 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
633 FILE_NOTIFY_CHANGE_SIZE
634 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
635 fsp->fsp_name->base_name);
638 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
640 return ret;
643 /****************************************************************************
644 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
645 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
646 as this is also called from the default SMB_VFS_FTRUNCATE code.
647 Always extends the file size.
648 Returns 0 on success, -1 on failure.
649 ****************************************************************************/
651 #define SPARSE_BUF_WRITE_SIZE (32*1024)
653 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
655 ssize_t pwrite_ret;
656 size_t total = 0;
658 if (!sparse_buf) {
659 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
660 if (!sparse_buf) {
661 errno = ENOMEM;
662 return -1;
666 while (total < len) {
667 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
669 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
670 if (pwrite_ret == -1) {
671 int saved_errno = errno;
672 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
673 "%s failed with error %s\n",
674 fsp_str_dbg(fsp), strerror(saved_errno)));
675 errno = saved_errno;
676 return -1;
678 total += pwrite_ret;
681 return 0;
684 /****************************************************************************
685 A vfs fill sparse call.
686 Writes zeros from the end of file to len, if len is greater than EOF.
687 Used only by strict_sync.
688 Returns 0 on success, -1 on failure.
689 ****************************************************************************/
691 int vfs_fill_sparse(files_struct *fsp, off_t len)
693 int ret;
694 NTSTATUS status;
695 off_t offset;
696 size_t num_to_write;
698 status = vfs_stat_fsp(fsp);
699 if (!NT_STATUS_IS_OK(status)) {
700 return -1;
703 if (len <= fsp->fsp_name->st.st_ex_size) {
704 return 0;
707 #ifdef S_ISFIFO
708 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
709 return 0;
711 #endif
713 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
714 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
715 (double)fsp->fsp_name->st.st_ex_size, (double)len,
716 (double)(len - fsp->fsp_name->st.st_ex_size)));
718 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
720 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
722 offset = fsp->fsp_name->st.st_ex_size;
723 num_to_write = len - fsp->fsp_name->st.st_ex_size;
725 /* Only do this on non-stream file handles. */
726 if (fsp->base_fsp == NULL) {
727 /* for allocation try fallocate first. This can fail on some
728 * platforms e.g. when the filesystem doesn't support it and no
729 * emulation is being done by the libc (like on AIX with JFS1). In that
730 * case we do our own emulation. fallocate implementations can
731 * return ENOTSUP or EINVAL in cases like that. */
732 ret = SMB_VFS_FALLOCATE(fsp, 0, offset, num_to_write);
733 if (ret == -1 && errno == ENOSPC) {
734 goto out;
736 if (ret == 0) {
737 goto out;
739 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
740 "error %d. Falling back to slow manual allocation\n", ret));
743 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
745 out:
747 if (ret == 0) {
748 set_filelen_write_cache(fsp, len);
751 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
752 return ret;
755 /****************************************************************************
756 Transfer some data (n bytes) between two file_struct's.
757 ****************************************************************************/
759 static ssize_t vfs_pread_fn(void *file, void *buf, size_t len, off_t offset)
761 struct files_struct *fsp = (struct files_struct *)file;
763 return SMB_VFS_PREAD(fsp, buf, len, offset);
766 static ssize_t vfs_pwrite_fn(void *file, const void *buf, size_t len, off_t offset)
768 struct files_struct *fsp = (struct files_struct *)file;
770 return SMB_VFS_PWRITE(fsp, buf, len, offset);
773 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
775 return transfer_file_internal((void *)in, (void *)out, n,
776 vfs_pread_fn, vfs_pwrite_fn);
779 /*******************************************************************
780 A vfs_readdir wrapper which just returns the file name.
781 ********************************************************************/
783 const char *vfs_readdirname(connection_struct *conn, void *p,
784 SMB_STRUCT_STAT *sbuf, char **talloced)
786 struct dirent *ptr= NULL;
787 const char *dname;
788 char *translated;
789 NTSTATUS status;
791 if (!p)
792 return(NULL);
794 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
795 if (!ptr)
796 return(NULL);
798 dname = ptr->d_name;
801 #ifdef NEXT2
802 if (telldir(p) < 0)
803 return(NULL);
804 #endif
806 #ifdef HAVE_BROKEN_READDIR_NAME
807 /* using /usr/ucb/cc is BAD */
808 dname = dname - 2;
809 #endif
811 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
812 talloc_tos(), &translated);
813 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
814 *talloced = NULL;
815 return dname;
817 *talloced = translated;
818 if (!NT_STATUS_IS_OK(status)) {
819 return NULL;
821 return translated;
824 /*******************************************************************
825 A wrapper for vfs_chdir().
826 ********************************************************************/
828 int vfs_ChDir(connection_struct *conn, const char *path)
830 int ret;
832 if (!LastDir) {
833 LastDir = SMB_STRDUP("");
836 if (ISDOT(path)) {
837 return 0;
840 if (*path == '/' && strcsequal(LastDir,path)) {
841 return 0;
844 DEBUG(4,("vfs_ChDir to %s\n",path));
846 ret = SMB_VFS_CHDIR(conn,path);
847 if (ret == 0) {
848 /* Global cache. */
849 SAFE_FREE(LastDir);
850 LastDir = SMB_STRDUP(path);
852 /* conn cache. */
853 TALLOC_FREE(conn->cwd);
854 conn->cwd = vfs_GetWd(conn, conn);
855 DEBUG(4,("vfs_ChDir got %s\n",conn->cwd));
857 return ret;
860 /*******************************************************************
861 Return the absolute current directory path - given a UNIX pathname.
862 Note that this path is returned in DOS format, not UNIX
863 format. Note this can be called with conn == NULL.
864 ********************************************************************/
866 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
868 char *current_dir = NULL;
869 char *result = NULL;
870 DATA_BLOB cache_value;
871 struct file_id key;
872 struct smb_filename *smb_fname_dot = NULL;
873 struct smb_filename *smb_fname_full = NULL;
875 if (!lp_getwd_cache()) {
876 goto nocache;
879 smb_fname_dot = synthetic_smb_fname(ctx, ".", NULL, NULL);
880 if (smb_fname_dot == NULL) {
881 errno = ENOMEM;
882 goto out;
885 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
887 * Known to fail for root: the directory may be NFS-mounted
888 * and exported with root_squash (so has no root access).
890 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
891 "(NFS problem ?)\n", strerror(errno) ));
892 goto nocache;
895 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
897 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
898 data_blob_const(&key, sizeof(key)),
899 &cache_value)) {
900 goto nocache;
903 SMB_ASSERT((cache_value.length > 0)
904 && (cache_value.data[cache_value.length-1] == '\0'));
906 smb_fname_full = synthetic_smb_fname(ctx, (char *)cache_value.data,
907 NULL, NULL);
908 if (smb_fname_full == NULL) {
909 errno = ENOMEM;
910 goto out;
913 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
914 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
915 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
916 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
918 * Ok, we're done
920 result = talloc_strdup(ctx, smb_fname_full->base_name);
921 if (result == NULL) {
922 errno = ENOMEM;
924 goto out;
927 nocache:
930 * We don't have the information to hand so rely on traditional
931 * methods. The very slow getcwd, which spawns a process on some
932 * systems, or the not quite so bad getwd.
935 current_dir = SMB_VFS_GETWD(conn);
936 if (current_dir == NULL) {
937 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
938 strerror(errno)));
939 goto out;
942 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
943 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
945 memcache_add(smbd_memcache(), GETWD_CACHE,
946 data_blob_const(&key, sizeof(key)),
947 data_blob_const(current_dir,
948 strlen(current_dir)+1));
951 result = talloc_strdup(ctx, current_dir);
952 if (result == NULL) {
953 errno = ENOMEM;
956 out:
957 TALLOC_FREE(smb_fname_dot);
958 TALLOC_FREE(smb_fname_full);
959 SAFE_FREE(current_dir);
960 return result;
963 /*******************************************************************
964 Reduce a file name, removing .. elements and checking that
965 it is below dir in the heirachy. This uses realpath.
966 This function must run as root, and will return names
967 and valid stat structs that can be checked on open.
968 ********************************************************************/
970 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
971 const char *fname,
972 struct smb_request *smbreq)
974 NTSTATUS status;
975 TALLOC_CTX *ctx = talloc_tos();
976 const char *conn_rootdir;
977 size_t rootdir_len;
978 char *dir_name = NULL;
979 const char *last_component = NULL;
980 char *resolved_name = NULL;
981 char *saved_dir = NULL;
982 struct smb_filename *smb_fname_cwd = NULL;
983 struct privilege_paths *priv_paths = NULL;
984 int ret;
986 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
987 fname,
988 conn->connectpath));
991 priv_paths = talloc_zero(smbreq, struct privilege_paths);
992 if (!priv_paths) {
993 status = NT_STATUS_NO_MEMORY;
994 goto err;
997 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
998 status = NT_STATUS_NO_MEMORY;
999 goto err;
1002 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
1003 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
1005 if (priv_paths->parent_name.base_name == NULL ||
1006 priv_paths->file_name.base_name == NULL) {
1007 status = NT_STATUS_NO_MEMORY;
1008 goto err;
1011 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
1012 status = map_nt_error_from_unix(errno);
1013 goto err;
1015 /* Remember where we were. */
1016 saved_dir = vfs_GetWd(ctx, conn);
1017 if (!saved_dir) {
1018 status = map_nt_error_from_unix(errno);
1019 goto err;
1022 /* Go to the parent directory to lock in memory. */
1023 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
1024 status = map_nt_error_from_unix(errno);
1025 goto err;
1028 /* Get the absolute path of the parent directory. */
1029 resolved_name = SMB_VFS_REALPATH(conn,".");
1030 if (!resolved_name) {
1031 status = map_nt_error_from_unix(errno);
1032 goto err;
1035 if (*resolved_name != '/') {
1036 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1037 "doesn't return absolute paths !\n"));
1038 status = NT_STATUS_OBJECT_NAME_INVALID;
1039 goto err;
1042 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1043 priv_paths->parent_name.base_name,
1044 resolved_name));
1046 /* Now check the stat value is the same. */
1047 smb_fname_cwd = synthetic_smb_fname(talloc_tos(), ".", NULL, NULL);
1048 if (smb_fname_cwd == NULL) {
1049 status = NT_STATUS_NO_MEMORY;
1050 goto err;
1053 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1054 status = map_nt_error_from_unix(errno);
1055 goto err;
1058 /* Ensure we're pointing at the same place. */
1059 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1060 DEBUG(0,("check_reduced_name_with_privilege: "
1061 "device/inode/uid/gid on directory %s changed. "
1062 "Denying access !\n",
1063 priv_paths->parent_name.base_name));
1064 status = NT_STATUS_ACCESS_DENIED;
1065 goto err;
1068 /* Ensure we're below the connect path. */
1070 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1071 if (conn_rootdir == NULL) {
1072 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1073 "conn_rootdir\n"));
1074 status = NT_STATUS_ACCESS_DENIED;
1075 goto err;
1078 rootdir_len = strlen(conn_rootdir);
1079 if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1080 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1081 "attempt: %s is a symlink outside the "
1082 "share path\n",
1083 dir_name));
1084 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1085 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1086 status = NT_STATUS_ACCESS_DENIED;
1087 goto err;
1090 /* Now ensure that the last component either doesn't
1091 exist, or is *NOT* a symlink. */
1093 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1094 if (ret == -1) {
1095 /* Errno must be ENOENT for this be ok. */
1096 if (errno != ENOENT) {
1097 status = map_nt_error_from_unix(errno);
1098 DEBUG(2, ("check_reduced_name_with_privilege: "
1099 "LSTAT on %s failed with %s\n",
1100 priv_paths->file_name.base_name,
1101 nt_errstr(status)));
1102 goto err;
1106 if (VALID_STAT(priv_paths->file_name.st) &&
1107 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1108 DEBUG(2, ("check_reduced_name_with_privilege: "
1109 "Last component %s is a symlink. Denying"
1110 "access.\n",
1111 priv_paths->file_name.base_name));
1112 status = NT_STATUS_ACCESS_DENIED;
1113 goto err;
1116 smbreq->priv_paths = priv_paths;
1117 status = NT_STATUS_OK;
1119 err:
1121 if (saved_dir) {
1122 vfs_ChDir(conn, saved_dir);
1124 SAFE_FREE(resolved_name);
1125 if (!NT_STATUS_IS_OK(status)) {
1126 TALLOC_FREE(priv_paths);
1128 TALLOC_FREE(dir_name);
1129 return status;
1132 /*******************************************************************
1133 Reduce a file name, removing .. elements and checking that
1134 it is below dir in the heirachy. This uses realpath.
1135 ********************************************************************/
1137 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1139 char *resolved_name = NULL;
1140 bool allow_symlinks = true;
1141 bool allow_widelinks = false;
1143 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1145 resolved_name = SMB_VFS_REALPATH(conn,fname);
1147 if (!resolved_name) {
1148 switch (errno) {
1149 case ENOTDIR:
1150 DEBUG(3,("check_reduced_name: Component not a "
1151 "directory in getting realpath for "
1152 "%s\n", fname));
1153 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1154 case ENOENT:
1156 TALLOC_CTX *ctx = talloc_tos();
1157 char *dir_name = NULL;
1158 const char *last_component = NULL;
1159 char *new_name = NULL;
1160 int ret;
1162 /* Last component didn't exist.
1163 Remove it and try and canonicalise
1164 the directory name. */
1165 if (!parent_dirname(ctx, fname,
1166 &dir_name,
1167 &last_component)) {
1168 return NT_STATUS_NO_MEMORY;
1171 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1172 if (!resolved_name) {
1173 NTSTATUS status = map_nt_error_from_unix(errno);
1175 if (errno == ENOENT || errno == ENOTDIR) {
1176 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1179 DEBUG(3,("check_reduce_name: "
1180 "couldn't get realpath for "
1181 "%s (%s)\n",
1182 fname,
1183 nt_errstr(status)));
1184 return status;
1186 ret = asprintf(&new_name, "%s/%s",
1187 resolved_name, last_component);
1188 SAFE_FREE(resolved_name);
1189 if (ret == -1) {
1190 return NT_STATUS_NO_MEMORY;
1192 resolved_name = new_name;
1193 break;
1195 default:
1196 DEBUG(3,("check_reduced_name: couldn't get "
1197 "realpath for %s\n", fname));
1198 return map_nt_error_from_unix(errno);
1202 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1203 resolved_name));
1205 if (*resolved_name != '/') {
1206 DEBUG(0,("check_reduced_name: realpath doesn't return "
1207 "absolute paths !\n"));
1208 SAFE_FREE(resolved_name);
1209 return NT_STATUS_OBJECT_NAME_INVALID;
1212 allow_widelinks = lp_widelinks(SNUM(conn));
1213 allow_symlinks = lp_follow_symlinks(SNUM(conn));
1215 /* Common widelinks and symlinks checks. */
1216 if (!allow_widelinks || !allow_symlinks) {
1217 const char *conn_rootdir;
1218 size_t rootdir_len;
1220 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1221 if (conn_rootdir == NULL) {
1222 DEBUG(2, ("check_reduced_name: Could not get "
1223 "conn_rootdir\n"));
1224 SAFE_FREE(resolved_name);
1225 return NT_STATUS_ACCESS_DENIED;
1228 rootdir_len = strlen(conn_rootdir);
1229 if (strncmp(conn_rootdir, resolved_name,
1230 rootdir_len) != 0) {
1231 DEBUG(2, ("check_reduced_name: Bad access "
1232 "attempt: %s is a symlink outside the "
1233 "share path\n", fname));
1234 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1235 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1236 SAFE_FREE(resolved_name);
1237 return NT_STATUS_ACCESS_DENIED;
1240 /* Extra checks if all symlinks are disallowed. */
1241 if (!allow_symlinks) {
1242 /* fname can't have changed in resolved_path. */
1243 const char *p = &resolved_name[rootdir_len];
1245 /* *p can be '\0' if fname was "." */
1246 if (*p == '\0' && ISDOT(fname)) {
1247 goto out;
1250 if (*p != '/') {
1251 DEBUG(2, ("check_reduced_name: logic error (%c) "
1252 "in resolved_name: %s\n",
1254 fname));
1255 SAFE_FREE(resolved_name);
1256 return NT_STATUS_ACCESS_DENIED;
1259 p++;
1260 if (strcmp(fname, p)!=0) {
1261 DEBUG(2, ("check_reduced_name: Bad access "
1262 "attempt: %s is a symlink to %s\n",
1263 fname, p));
1264 SAFE_FREE(resolved_name);
1265 return NT_STATUS_ACCESS_DENIED;
1270 out:
1272 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1273 resolved_name));
1274 SAFE_FREE(resolved_name);
1275 return NT_STATUS_OK;
1279 * XXX: This is temporary and there should be no callers of this once
1280 * smb_filename is plumbed through all path based operations.
1282 * Called when we know stream name parsing has already been done.
1284 int vfs_stat_smb_basename(struct connection_struct *conn, const char *fname,
1285 SMB_STRUCT_STAT *psbuf)
1287 struct smb_filename smb_fname = {
1288 .base_name = discard_const_p(char, fname)
1290 int ret;
1292 if (lp_posix_pathnames()) {
1293 ret = SMB_VFS_LSTAT(conn, &smb_fname);
1294 } else {
1295 ret = SMB_VFS_STAT(conn, &smb_fname);
1298 if (ret != -1) {
1299 *psbuf = smb_fname.st;
1301 return ret;
1305 * Ensure LSTAT is called for POSIX paths.
1308 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1310 int ret;
1312 if(fsp->fh->fd == -1) {
1313 if (fsp->posix_open) {
1314 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1315 } else {
1316 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1318 if (ret == -1) {
1319 return map_nt_error_from_unix(errno);
1321 } else {
1322 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1323 return map_nt_error_from_unix(errno);
1326 return NT_STATUS_OK;
1330 * Initialize num_streams and streams, then call VFS op streaminfo
1332 NTSTATUS vfs_streaminfo(connection_struct *conn,
1333 struct files_struct *fsp,
1334 const char *fname,
1335 TALLOC_CTX *mem_ctx,
1336 unsigned int *num_streams,
1337 struct stream_struct **streams)
1339 *num_streams = 0;
1340 *streams = NULL;
1341 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1345 generate a file_id from a stat structure
1347 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1349 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1352 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1353 const char *service, const char *user)
1355 VFS_FIND(connect);
1356 return handle->fns->connect_fn(handle, service, user);
1359 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1361 VFS_FIND(disconnect);
1362 handle->fns->disconnect_fn(handle);
1365 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1366 const char *path, uint64_t *bsize,
1367 uint64_t *dfree, uint64_t *dsize)
1369 VFS_FIND(disk_free);
1370 return handle->fns->disk_free_fn(handle, path, bsize, dfree, dsize);
1373 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1374 enum SMB_QUOTA_TYPE qtype, unid_t id,
1375 SMB_DISK_QUOTA *qt)
1377 VFS_FIND(get_quota);
1378 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1381 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1382 enum SMB_QUOTA_TYPE qtype, unid_t id,
1383 SMB_DISK_QUOTA *qt)
1385 VFS_FIND(set_quota);
1386 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1389 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1390 struct files_struct *fsp,
1391 struct shadow_copy_data *shadow_copy_data,
1392 bool labels)
1394 VFS_FIND(get_shadow_copy_data);
1395 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1396 shadow_copy_data,
1397 labels);
1399 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1400 struct vfs_statvfs_struct *statbuf)
1402 VFS_FIND(statvfs);
1403 return handle->fns->statvfs_fn(handle, path, statbuf);
1406 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1407 enum timestamp_set_resolution *p_ts_res)
1409 VFS_FIND(fs_capabilities);
1410 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1413 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1414 struct dfs_GetDFSReferral *r)
1416 VFS_FIND(get_dfs_referrals);
1417 return handle->fns->get_dfs_referrals_fn(handle, r);
1420 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1421 const char *fname, const char *mask,
1422 uint32_t attributes)
1424 VFS_FIND(opendir);
1425 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1428 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1429 struct files_struct *fsp,
1430 const char *mask,
1431 uint32_t attributes)
1433 VFS_FIND(fdopendir);
1434 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1437 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1438 DIR *dirp,
1439 SMB_STRUCT_STAT *sbuf)
1441 VFS_FIND(readdir);
1442 return handle->fns->readdir_fn(handle, dirp, sbuf);
1445 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1446 DIR *dirp, long offset)
1448 VFS_FIND(seekdir);
1449 handle->fns->seekdir_fn(handle, dirp, offset);
1452 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1453 DIR *dirp)
1455 VFS_FIND(telldir);
1456 return handle->fns->telldir_fn(handle, dirp);
1459 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1460 DIR *dirp)
1462 VFS_FIND(rewind_dir);
1463 handle->fns->rewind_dir_fn(handle, dirp);
1466 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1467 mode_t mode)
1469 VFS_FIND(mkdir);
1470 return handle->fns->mkdir_fn(handle, path, mode);
1473 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1475 VFS_FIND(rmdir);
1476 return handle->fns->rmdir_fn(handle, path);
1479 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1480 DIR *dir)
1482 VFS_FIND(closedir);
1483 return handle->fns->closedir_fn(handle, dir);
1486 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1487 DIR *dirp)
1489 VFS_FIND(init_search_op);
1490 handle->fns->init_search_op_fn(handle, dirp);
1493 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1494 struct smb_filename *smb_fname, struct files_struct *fsp,
1495 int flags, mode_t mode)
1497 VFS_FIND(open);
1498 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1501 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1502 struct smb_request *req,
1503 uint16_t root_dir_fid,
1504 struct smb_filename *smb_fname,
1505 uint32_t access_mask,
1506 uint32_t share_access,
1507 uint32_t create_disposition,
1508 uint32_t create_options,
1509 uint32_t file_attributes,
1510 uint32_t oplock_request,
1511 struct smb2_lease *lease,
1512 uint64_t allocation_size,
1513 uint32_t private_flags,
1514 struct security_descriptor *sd,
1515 struct ea_list *ea_list,
1516 files_struct **result,
1517 int *pinfo,
1518 const struct smb2_create_blobs *in_context_blobs,
1519 struct smb2_create_blobs *out_context_blobs)
1521 VFS_FIND(create_file);
1522 return handle->fns->create_file_fn(
1523 handle, req, root_dir_fid, smb_fname, access_mask,
1524 share_access, create_disposition, create_options,
1525 file_attributes, oplock_request, lease, allocation_size,
1526 private_flags, sd, ea_list,
1527 result, pinfo, in_context_blobs, out_context_blobs);
1530 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1531 struct files_struct *fsp)
1533 VFS_FIND(close);
1534 return handle->fns->close_fn(handle, fsp);
1537 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1538 struct files_struct *fsp, void *data, size_t n)
1540 VFS_FIND(read);
1541 return handle->fns->read_fn(handle, fsp, data, n);
1544 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1545 struct files_struct *fsp, void *data, size_t n,
1546 off_t offset)
1548 VFS_FIND(pread);
1549 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1552 struct smb_vfs_call_pread_state {
1553 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1554 ssize_t retval;
1557 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1559 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1560 TALLOC_CTX *mem_ctx,
1561 struct tevent_context *ev,
1562 struct files_struct *fsp,
1563 void *data,
1564 size_t n, off_t offset)
1566 struct tevent_req *req, *subreq;
1567 struct smb_vfs_call_pread_state *state;
1569 req = tevent_req_create(mem_ctx, &state,
1570 struct smb_vfs_call_pread_state);
1571 if (req == NULL) {
1572 return NULL;
1574 VFS_FIND(pread_send);
1575 state->recv_fn = handle->fns->pread_recv_fn;
1577 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1578 offset);
1579 if (tevent_req_nomem(subreq, req)) {
1580 return tevent_req_post(req, ev);
1582 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1583 return req;
1586 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1588 struct tevent_req *req = tevent_req_callback_data(
1589 subreq, struct tevent_req);
1590 struct smb_vfs_call_pread_state *state = tevent_req_data(
1591 req, struct smb_vfs_call_pread_state);
1592 int err;
1594 state->retval = state->recv_fn(subreq, &err);
1595 TALLOC_FREE(subreq);
1596 if (state->retval == -1) {
1597 tevent_req_error(req, err);
1598 return;
1600 tevent_req_done(req);
1603 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req, int *perrno)
1605 struct smb_vfs_call_pread_state *state = tevent_req_data(
1606 req, struct smb_vfs_call_pread_state);
1607 int err;
1609 if (tevent_req_is_unix_error(req, &err)) {
1610 *perrno = err;
1611 return -1;
1613 return state->retval;
1616 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1617 struct files_struct *fsp, const void *data,
1618 size_t n)
1620 VFS_FIND(write);
1621 return handle->fns->write_fn(handle, fsp, data, n);
1624 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1625 struct files_struct *fsp, const void *data,
1626 size_t n, off_t offset)
1628 VFS_FIND(pwrite);
1629 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1632 struct smb_vfs_call_pwrite_state {
1633 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1634 ssize_t retval;
1637 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1639 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1640 TALLOC_CTX *mem_ctx,
1641 struct tevent_context *ev,
1642 struct files_struct *fsp,
1643 const void *data,
1644 size_t n, off_t offset)
1646 struct tevent_req *req, *subreq;
1647 struct smb_vfs_call_pwrite_state *state;
1649 req = tevent_req_create(mem_ctx, &state,
1650 struct smb_vfs_call_pwrite_state);
1651 if (req == NULL) {
1652 return NULL;
1654 VFS_FIND(pwrite_send);
1655 state->recv_fn = handle->fns->pwrite_recv_fn;
1657 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1658 offset);
1659 if (tevent_req_nomem(subreq, req)) {
1660 return tevent_req_post(req, ev);
1662 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1663 return req;
1666 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1668 struct tevent_req *req = tevent_req_callback_data(
1669 subreq, struct tevent_req);
1670 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1671 req, struct smb_vfs_call_pwrite_state);
1672 int err;
1674 state->retval = state->recv_fn(subreq, &err);
1675 TALLOC_FREE(subreq);
1676 if (state->retval == -1) {
1677 tevent_req_error(req, err);
1678 return;
1680 tevent_req_done(req);
1683 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req, int *perrno)
1685 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1686 req, struct smb_vfs_call_pwrite_state);
1687 int err;
1689 if (tevent_req_is_unix_error(req, &err)) {
1690 *perrno = err;
1691 return -1;
1693 return state->retval;
1696 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1697 struct files_struct *fsp, off_t offset,
1698 int whence)
1700 VFS_FIND(lseek);
1701 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1704 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1705 files_struct *fromfsp, const DATA_BLOB *header,
1706 off_t offset, size_t count)
1708 VFS_FIND(sendfile);
1709 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1710 count);
1713 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1714 files_struct *tofsp, off_t offset,
1715 size_t count)
1717 VFS_FIND(recvfile);
1718 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1721 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1722 const struct smb_filename *smb_fname_src,
1723 const struct smb_filename *smb_fname_dst)
1725 VFS_FIND(rename);
1726 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1729 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1730 struct files_struct *fsp)
1732 VFS_FIND(fsync);
1733 return handle->fns->fsync_fn(handle, fsp);
1736 struct smb_vfs_call_fsync_state {
1737 int (*recv_fn)(struct tevent_req *req, int *err);
1738 int retval;
1741 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1743 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1744 TALLOC_CTX *mem_ctx,
1745 struct tevent_context *ev,
1746 struct files_struct *fsp)
1748 struct tevent_req *req, *subreq;
1749 struct smb_vfs_call_fsync_state *state;
1751 req = tevent_req_create(mem_ctx, &state,
1752 struct smb_vfs_call_fsync_state);
1753 if (req == NULL) {
1754 return NULL;
1756 VFS_FIND(fsync_send);
1757 state->recv_fn = handle->fns->fsync_recv_fn;
1759 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1760 if (tevent_req_nomem(subreq, req)) {
1761 return tevent_req_post(req, ev);
1763 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1764 return req;
1767 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1769 struct tevent_req *req = tevent_req_callback_data(
1770 subreq, struct tevent_req);
1771 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1772 req, struct smb_vfs_call_fsync_state);
1773 int err;
1775 state->retval = state->recv_fn(subreq, &err);
1776 TALLOC_FREE(subreq);
1777 if (state->retval == -1) {
1778 tevent_req_error(req, err);
1779 return;
1781 tevent_req_done(req);
1784 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, int *perrno)
1786 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1787 req, struct smb_vfs_call_fsync_state);
1788 int err;
1790 if (tevent_req_is_unix_error(req, &err)) {
1791 *perrno = err;
1792 return -1;
1794 return state->retval;
1798 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1799 struct smb_filename *smb_fname)
1801 VFS_FIND(stat);
1802 return handle->fns->stat_fn(handle, smb_fname);
1805 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1806 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1808 VFS_FIND(fstat);
1809 return handle->fns->fstat_fn(handle, fsp, sbuf);
1812 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1813 struct smb_filename *smb_filename)
1815 VFS_FIND(lstat);
1816 return handle->fns->lstat_fn(handle, smb_filename);
1819 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1820 struct files_struct *fsp,
1821 const SMB_STRUCT_STAT *sbuf)
1823 VFS_FIND(get_alloc_size);
1824 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1827 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1828 const struct smb_filename *smb_fname)
1830 VFS_FIND(unlink);
1831 return handle->fns->unlink_fn(handle, smb_fname);
1834 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1835 mode_t mode)
1837 VFS_FIND(chmod);
1838 return handle->fns->chmod_fn(handle, path, mode);
1841 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1842 struct files_struct *fsp, mode_t mode)
1844 VFS_FIND(fchmod);
1845 return handle->fns->fchmod_fn(handle, fsp, mode);
1848 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1849 uid_t uid, gid_t gid)
1851 VFS_FIND(chown);
1852 return handle->fns->chown_fn(handle, path, uid, gid);
1855 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1856 struct files_struct *fsp, uid_t uid, gid_t gid)
1858 VFS_FIND(fchown);
1859 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1862 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1863 uid_t uid, gid_t gid)
1865 VFS_FIND(lchown);
1866 return handle->fns->lchown_fn(handle, path, uid, gid);
1869 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1871 int ret;
1872 bool as_root = false;
1873 const char *path;
1874 char *saved_dir = NULL;
1875 char *parent_dir = NULL;
1876 NTSTATUS status;
1878 if (fsp->fh->fd != -1) {
1879 /* Try fchown. */
1880 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1881 if (ret == 0) {
1882 return NT_STATUS_OK;
1884 if (ret == -1 && errno != ENOSYS) {
1885 return map_nt_error_from_unix(errno);
1889 as_root = (geteuid() == 0);
1891 if (as_root) {
1893 * We are being asked to chown as root. Make
1894 * sure we chdir() into the path to pin it,
1895 * and always act using lchown to ensure we
1896 * don't deref any symbolic links.
1898 const char *final_component = NULL;
1899 struct smb_filename local_fname;
1901 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1902 if (!saved_dir) {
1903 status = map_nt_error_from_unix(errno);
1904 DEBUG(0,("vfs_chown_fsp: failed to get "
1905 "current working directory. Error was %s\n",
1906 strerror(errno)));
1907 return status;
1910 if (!parent_dirname(talloc_tos(),
1911 fsp->fsp_name->base_name,
1912 &parent_dir,
1913 &final_component)) {
1914 return NT_STATUS_NO_MEMORY;
1917 /* cd into the parent dir to pin it. */
1918 ret = vfs_ChDir(fsp->conn, parent_dir);
1919 if (ret == -1) {
1920 return map_nt_error_from_unix(errno);
1923 ZERO_STRUCT(local_fname);
1924 local_fname.base_name = discard_const_p(char, final_component);
1926 /* Must use lstat here. */
1927 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1928 if (ret == -1) {
1929 status = map_nt_error_from_unix(errno);
1930 goto out;
1933 /* Ensure it matches the fsp stat. */
1934 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1935 status = NT_STATUS_ACCESS_DENIED;
1936 goto out;
1938 path = final_component;
1939 } else {
1940 path = fsp->fsp_name->base_name;
1943 if (fsp->posix_open || as_root) {
1944 ret = SMB_VFS_LCHOWN(fsp->conn,
1945 path,
1946 uid, gid);
1947 } else {
1948 ret = SMB_VFS_CHOWN(fsp->conn,
1949 path,
1950 uid, gid);
1953 if (ret == 0) {
1954 status = NT_STATUS_OK;
1955 } else {
1956 status = map_nt_error_from_unix(errno);
1959 out:
1961 if (as_root) {
1962 vfs_ChDir(fsp->conn,saved_dir);
1963 TALLOC_FREE(saved_dir);
1964 TALLOC_FREE(parent_dir);
1966 return status;
1969 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1971 VFS_FIND(chdir);
1972 return handle->fns->chdir_fn(handle, path);
1975 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
1977 VFS_FIND(getwd);
1978 return handle->fns->getwd_fn(handle);
1981 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
1982 const struct smb_filename *smb_fname,
1983 struct smb_file_time *ft)
1985 VFS_FIND(ntimes);
1986 return handle->fns->ntimes_fn(handle, smb_fname, ft);
1989 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
1990 struct files_struct *fsp, off_t offset)
1992 VFS_FIND(ftruncate);
1993 return handle->fns->ftruncate_fn(handle, fsp, offset);
1996 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
1997 struct files_struct *fsp,
1998 uint32_t mode,
1999 off_t offset,
2000 off_t len)
2002 VFS_FIND(fallocate);
2003 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2006 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2007 struct files_struct *fsp, uint32_t share_mode,
2008 uint32_t access_mask)
2010 VFS_FIND(kernel_flock);
2011 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2012 access_mask);
2015 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2016 struct files_struct *fsp, int leasetype)
2018 VFS_FIND(linux_setlease);
2019 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2022 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
2023 const char *newpath)
2025 VFS_FIND(symlink);
2026 return handle->fns->symlink_fn(handle, oldpath, newpath);
2029 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2030 const char *path, char *buf, size_t bufsiz)
2032 VFS_FIND(readlink);
2033 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
2036 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
2037 const char *newpath)
2039 VFS_FIND(link);
2040 return handle->fns->link_fn(handle, oldpath, newpath);
2043 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
2044 mode_t mode, SMB_DEV_T dev)
2046 VFS_FIND(mknod);
2047 return handle->fns->mknod_fn(handle, path, mode, dev);
2050 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
2052 VFS_FIND(realpath);
2053 return handle->fns->realpath_fn(handle, path);
2056 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
2057 struct sys_notify_context *ctx,
2058 const char *path,
2059 uint32_t *filter,
2060 uint32_t *subdir_filter,
2061 void (*callback)(struct sys_notify_context *ctx,
2062 void *private_data,
2063 struct notify_event *ev),
2064 void *private_data, void *handle_p)
2066 VFS_FIND(notify_watch);
2067 return handle->fns->notify_watch_fn(handle, ctx, path,
2068 filter, subdir_filter, callback,
2069 private_data, handle_p);
2072 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
2073 unsigned int flags)
2075 VFS_FIND(chflags);
2076 return handle->fns->chflags_fn(handle, path, flags);
2079 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2080 const SMB_STRUCT_STAT *sbuf)
2082 VFS_FIND(file_id_create);
2083 return handle->fns->file_id_create_fn(handle, sbuf);
2086 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2087 struct files_struct *fsp,
2088 const char *fname,
2089 TALLOC_CTX *mem_ctx,
2090 unsigned int *num_streams,
2091 struct stream_struct **streams)
2093 VFS_FIND(streaminfo);
2094 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
2095 num_streams, streams);
2098 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2099 const char *path, const char *name,
2100 TALLOC_CTX *mem_ctx, char **found_name)
2102 VFS_FIND(get_real_filename);
2103 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2104 found_name);
2107 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2108 const char *filename)
2110 VFS_FIND(connectpath);
2111 return handle->fns->connectpath_fn(handle, filename);
2114 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2115 struct files_struct *fsp,
2116 struct lock_struct *plock)
2118 VFS_FIND(strict_lock);
2119 return handle->fns->strict_lock_fn(handle, fsp, plock);
2122 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2123 struct files_struct *fsp,
2124 struct lock_struct *plock)
2126 VFS_FIND(strict_unlock);
2127 handle->fns->strict_unlock_fn(handle, fsp, plock);
2130 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2131 const char *name,
2132 enum vfs_translate_direction direction,
2133 TALLOC_CTX *mem_ctx,
2134 char **mapped_name)
2136 VFS_FIND(translate_name);
2137 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2138 mapped_name);
2141 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2142 struct files_struct *fsp,
2143 TALLOC_CTX *ctx,
2144 uint32_t function,
2145 uint16_t req_flags,
2146 const uint8_t *in_data,
2147 uint32_t in_len,
2148 uint8_t **out_data,
2149 uint32_t max_out_len,
2150 uint32_t *out_len)
2152 VFS_FIND(fsctl);
2153 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2154 in_data, in_len, out_data, max_out_len,
2155 out_len);
2158 struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle,
2159 TALLOC_CTX *mem_ctx,
2160 struct tevent_context *ev,
2161 struct files_struct *src_fsp,
2162 off_t src_off,
2163 struct files_struct *dest_fsp,
2164 off_t dest_off,
2165 off_t num)
2167 VFS_FIND(copy_chunk_send);
2168 return handle->fns->copy_chunk_send_fn(handle, mem_ctx, ev, src_fsp,
2169 src_off, dest_fsp, dest_off, num);
2172 NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,
2173 struct tevent_req *req,
2174 off_t *copied)
2176 VFS_FIND(copy_chunk_recv);
2177 return handle->fns->copy_chunk_recv_fn(handle, req, copied);
2180 NTSTATUS smb_vfs_call_get_compression(vfs_handle_struct *handle,
2181 TALLOC_CTX *mem_ctx,
2182 struct files_struct *fsp,
2183 struct smb_filename *smb_fname,
2184 uint16_t *_compression_fmt)
2186 VFS_FIND(get_compression);
2187 return handle->fns->get_compression_fn(handle, mem_ctx, fsp, smb_fname,
2188 _compression_fmt);
2191 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2192 TALLOC_CTX *mem_ctx,
2193 struct files_struct *fsp,
2194 uint16_t compression_fmt)
2196 VFS_FIND(set_compression);
2197 return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2198 compression_fmt);
2201 NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
2202 TALLOC_CTX *mem_ctx,
2203 const char *service_path,
2204 char **base_volume)
2206 VFS_FIND(snap_check_path);
2207 return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path,
2208 base_volume);
2211 NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle,
2212 TALLOC_CTX *mem_ctx,
2213 const char *base_volume,
2214 time_t *tstamp,
2215 bool rw,
2216 char **base_path,
2217 char **snap_path)
2219 VFS_FIND(snap_create);
2220 return handle->fns->snap_create_fn(handle, mem_ctx, base_volume, tstamp,
2221 rw, base_path, snap_path);
2224 NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle,
2225 TALLOC_CTX *mem_ctx,
2226 char *base_path,
2227 char *snap_path)
2229 VFS_FIND(snap_delete);
2230 return handle->fns->snap_delete_fn(handle, mem_ctx, base_path,
2231 snap_path);
2234 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2235 struct files_struct *fsp,
2236 uint32_t security_info,
2237 TALLOC_CTX *mem_ctx,
2238 struct security_descriptor **ppdesc)
2240 VFS_FIND(fget_nt_acl);
2241 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2242 mem_ctx, ppdesc);
2245 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2246 const char *name,
2247 uint32_t security_info,
2248 TALLOC_CTX *mem_ctx,
2249 struct security_descriptor **ppdesc)
2251 VFS_FIND(get_nt_acl);
2252 return handle->fns->get_nt_acl_fn(handle, name, security_info, mem_ctx, ppdesc);
2255 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2256 struct files_struct *fsp,
2257 uint32_t security_info_sent,
2258 const struct security_descriptor *psd)
2260 VFS_FIND(fset_nt_acl);
2261 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2262 psd);
2265 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2266 struct smb_filename *file,
2267 struct security_acl *sacl,
2268 uint32_t access_requested,
2269 uint32_t access_denied)
2271 VFS_FIND(audit_file);
2272 return handle->fns->audit_file_fn(handle,
2273 file,
2274 sacl,
2275 access_requested,
2276 access_denied);
2279 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2280 mode_t mode)
2282 VFS_FIND(chmod_acl);
2283 return handle->fns->chmod_acl_fn(handle, name, mode);
2286 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2287 struct files_struct *fsp, mode_t mode)
2289 VFS_FIND(fchmod_acl);
2290 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2293 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2294 const char *path_p,
2295 SMB_ACL_TYPE_T type,
2296 TALLOC_CTX *mem_ctx)
2298 VFS_FIND(sys_acl_get_file);
2299 return handle->fns->sys_acl_get_file_fn(handle, path_p, type, mem_ctx);
2302 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2303 struct files_struct *fsp,
2304 TALLOC_CTX *mem_ctx)
2306 VFS_FIND(sys_acl_get_fd);
2307 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2310 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2311 const char *path_p,
2312 TALLOC_CTX *mem_ctx,
2313 char **blob_description,
2314 DATA_BLOB *blob)
2316 VFS_FIND(sys_acl_blob_get_file);
2317 return handle->fns->sys_acl_blob_get_file_fn(handle, path_p, mem_ctx, blob_description, blob);
2320 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2321 struct files_struct *fsp,
2322 TALLOC_CTX *mem_ctx,
2323 char **blob_description,
2324 DATA_BLOB *blob)
2326 VFS_FIND(sys_acl_blob_get_fd);
2327 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2330 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2331 const char *name, SMB_ACL_TYPE_T acltype,
2332 SMB_ACL_T theacl)
2334 VFS_FIND(sys_acl_set_file);
2335 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2338 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2339 struct files_struct *fsp, SMB_ACL_T theacl)
2341 VFS_FIND(sys_acl_set_fd);
2342 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2345 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2346 const char *path)
2348 VFS_FIND(sys_acl_delete_def_file);
2349 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2352 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2353 const char *path, const char *name, void *value,
2354 size_t size)
2356 VFS_FIND(getxattr);
2357 return handle->fns->getxattr_fn(handle, path, name, value, size);
2360 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2361 struct files_struct *fsp, const char *name,
2362 void *value, size_t size)
2364 VFS_FIND(fgetxattr);
2365 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2368 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2369 const char *path, char *list, size_t size)
2371 VFS_FIND(listxattr);
2372 return handle->fns->listxattr_fn(handle, path, list, size);
2375 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2376 struct files_struct *fsp, char *list,
2377 size_t size)
2379 VFS_FIND(flistxattr);
2380 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2383 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2384 const char *path, const char *name)
2386 VFS_FIND(removexattr);
2387 return handle->fns->removexattr_fn(handle, path, name);
2390 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2391 struct files_struct *fsp, const char *name)
2393 VFS_FIND(fremovexattr);
2394 return handle->fns->fremovexattr_fn(handle, fsp, name);
2397 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2398 const char *name, const void *value, size_t size,
2399 int flags)
2401 VFS_FIND(setxattr);
2402 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2405 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2406 struct files_struct *fsp, const char *name,
2407 const void *value, size_t size, int flags)
2409 VFS_FIND(fsetxattr);
2410 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2413 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2414 struct files_struct *fsp)
2416 VFS_FIND(aio_force);
2417 return handle->fns->aio_force_fn(handle, fsp);
2420 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2421 const struct smb_filename *fname,
2422 SMB_STRUCT_STAT *sbuf)
2424 VFS_FIND(is_offline);
2425 return handle->fns->is_offline_fn(handle, fname, sbuf);
2428 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2429 const struct smb_filename *fname)
2431 VFS_FIND(set_offline);
2432 return handle->fns->set_offline_fn(handle, fname);
2435 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2436 struct files_struct *fsp,
2437 TALLOC_CTX *mem_ctx,
2438 DATA_BLOB *cookie)
2440 VFS_FIND(durable_cookie);
2441 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2444 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2445 struct files_struct *fsp,
2446 const DATA_BLOB old_cookie,
2447 TALLOC_CTX *mem_ctx,
2448 DATA_BLOB *new_cookie)
2450 VFS_FIND(durable_disconnect);
2451 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2452 mem_ctx, new_cookie);
2455 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2456 struct smb_request *smb1req,
2457 struct smbXsrv_open *op,
2458 const DATA_BLOB old_cookie,
2459 TALLOC_CTX *mem_ctx,
2460 struct files_struct **fsp,
2461 DATA_BLOB *new_cookie)
2463 VFS_FIND(durable_reconnect);
2464 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2465 old_cookie, mem_ctx, fsp,
2466 new_cookie);
2469 NTSTATUS smb_vfs_call_readdir_attr(struct vfs_handle_struct *handle,
2470 const struct smb_filename *fname,
2471 TALLOC_CTX *mem_ctx,
2472 struct readdir_attr_data **attr_data)
2474 VFS_FIND(readdir_attr);
2475 return handle->fns->readdir_attr_fn(handle, fname, mem_ctx, attr_data);