s3: smbd: VFS: Add vfs_stat_smb_basename() - to be called when we *know* stream name...
[Samba.git] / source3 / smbd / vfs.c
blobb8525501742e8491d60ceff7205ca3fb97aa7a35
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 *)(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_read_fn(void *file, void *buf, size_t len)
761 struct files_struct *fsp = (struct files_struct *)file;
763 return SMB_VFS_READ(fsp, buf, len);
766 static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
768 struct files_struct *fsp = (struct files_struct *)file;
770 return SMB_VFS_WRITE(fsp, buf, len);
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_read_fn, vfs_write_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 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1283 SMB_STRUCT_STAT *psbuf)
1285 struct smb_filename *smb_fname;
1286 int ret;
1288 smb_fname = synthetic_smb_fname_split(talloc_tos(), fname, NULL);
1289 if (smb_fname == NULL) {
1290 errno = ENOMEM;
1291 return -1;
1294 if (lp_posix_pathnames()) {
1295 ret = SMB_VFS_LSTAT(conn, smb_fname);
1296 } else {
1297 ret = SMB_VFS_STAT(conn, smb_fname);
1300 if (ret != -1) {
1301 *psbuf = smb_fname->st;
1304 TALLOC_FREE(smb_fname);
1305 return ret;
1309 * XXX: This is temporary and there should be no callers of this once
1310 * smb_filename is plumbed through all path based operations.
1312 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1313 SMB_STRUCT_STAT *psbuf)
1315 struct smb_filename *smb_fname;
1316 int ret;
1318 smb_fname = synthetic_smb_fname_split(talloc_tos(), fname, NULL);
1319 if (smb_fname == NULL) {
1320 errno = ENOMEM;
1321 return -1;
1324 ret = SMB_VFS_LSTAT(conn, smb_fname);
1325 if (ret != -1) {
1326 *psbuf = smb_fname->st;
1329 TALLOC_FREE(smb_fname);
1330 return ret;
1334 * XXX: This is temporary and there should be no callers of this once
1335 * smb_filename is plumbed through all path based operations.
1337 * Called when we know stream name parsing has already been done.
1339 int vfs_stat_smb_basename(struct connection_struct *conn, const char *fname,
1340 SMB_STRUCT_STAT *psbuf)
1342 struct smb_filename smb_fname = {
1343 .base_name = discard_const_p(char, fname)
1345 int ret;
1347 if (lp_posix_pathnames()) {
1348 ret = SMB_VFS_LSTAT(conn, &smb_fname);
1349 } else {
1350 ret = SMB_VFS_STAT(conn, &smb_fname);
1353 if (ret != -1) {
1354 *psbuf = smb_fname.st;
1356 return ret;
1360 * Ensure LSTAT is called for POSIX paths.
1363 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1365 int ret;
1367 if(fsp->fh->fd == -1) {
1368 if (fsp->posix_open) {
1369 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1370 } else {
1371 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1373 if (ret == -1) {
1374 return map_nt_error_from_unix(errno);
1376 } else {
1377 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1378 return map_nt_error_from_unix(errno);
1381 return NT_STATUS_OK;
1385 * Initialize num_streams and streams, then call VFS op streaminfo
1387 NTSTATUS vfs_streaminfo(connection_struct *conn,
1388 struct files_struct *fsp,
1389 const char *fname,
1390 TALLOC_CTX *mem_ctx,
1391 unsigned int *num_streams,
1392 struct stream_struct **streams)
1394 *num_streams = 0;
1395 *streams = NULL;
1396 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1400 generate a file_id from a stat structure
1402 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1404 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1407 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1408 const char *service, const char *user)
1410 VFS_FIND(connect);
1411 return handle->fns->connect_fn(handle, service, user);
1414 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1416 VFS_FIND(disconnect);
1417 handle->fns->disconnect_fn(handle);
1420 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1421 const char *path, uint64_t *bsize,
1422 uint64_t *dfree, uint64_t *dsize)
1424 VFS_FIND(disk_free);
1425 return handle->fns->disk_free_fn(handle, path, bsize, dfree, dsize);
1428 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1429 enum SMB_QUOTA_TYPE qtype, unid_t id,
1430 SMB_DISK_QUOTA *qt)
1432 VFS_FIND(get_quota);
1433 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1436 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1437 enum SMB_QUOTA_TYPE qtype, unid_t id,
1438 SMB_DISK_QUOTA *qt)
1440 VFS_FIND(set_quota);
1441 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1444 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1445 struct files_struct *fsp,
1446 struct shadow_copy_data *shadow_copy_data,
1447 bool labels)
1449 VFS_FIND(get_shadow_copy_data);
1450 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1451 shadow_copy_data,
1452 labels);
1454 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1455 struct vfs_statvfs_struct *statbuf)
1457 VFS_FIND(statvfs);
1458 return handle->fns->statvfs_fn(handle, path, statbuf);
1461 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1462 enum timestamp_set_resolution *p_ts_res)
1464 VFS_FIND(fs_capabilities);
1465 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1468 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1469 struct dfs_GetDFSReferral *r)
1471 VFS_FIND(get_dfs_referrals);
1472 return handle->fns->get_dfs_referrals_fn(handle, r);
1475 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1476 const char *fname, const char *mask,
1477 uint32 attributes)
1479 VFS_FIND(opendir);
1480 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1483 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1484 struct files_struct *fsp,
1485 const char *mask,
1486 uint32 attributes)
1488 VFS_FIND(fdopendir);
1489 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1492 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1493 DIR *dirp,
1494 SMB_STRUCT_STAT *sbuf)
1496 VFS_FIND(readdir);
1497 return handle->fns->readdir_fn(handle, dirp, sbuf);
1500 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1501 DIR *dirp, long offset)
1503 VFS_FIND(seekdir);
1504 handle->fns->seekdir_fn(handle, dirp, offset);
1507 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1508 DIR *dirp)
1510 VFS_FIND(telldir);
1511 return handle->fns->telldir_fn(handle, dirp);
1514 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1515 DIR *dirp)
1517 VFS_FIND(rewind_dir);
1518 handle->fns->rewind_dir_fn(handle, dirp);
1521 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1522 mode_t mode)
1524 VFS_FIND(mkdir);
1525 return handle->fns->mkdir_fn(handle, path, mode);
1528 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1530 VFS_FIND(rmdir);
1531 return handle->fns->rmdir_fn(handle, path);
1534 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1535 DIR *dir)
1537 VFS_FIND(closedir);
1538 return handle->fns->closedir_fn(handle, dir);
1541 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1542 DIR *dirp)
1544 VFS_FIND(init_search_op);
1545 handle->fns->init_search_op_fn(handle, dirp);
1548 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1549 struct smb_filename *smb_fname, struct files_struct *fsp,
1550 int flags, mode_t mode)
1552 VFS_FIND(open);
1553 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1556 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1557 struct smb_request *req,
1558 uint16_t root_dir_fid,
1559 struct smb_filename *smb_fname,
1560 uint32_t access_mask,
1561 uint32_t share_access,
1562 uint32_t create_disposition,
1563 uint32_t create_options,
1564 uint32_t file_attributes,
1565 uint32_t oplock_request,
1566 struct smb2_lease *lease,
1567 uint64_t allocation_size,
1568 uint32_t private_flags,
1569 struct security_descriptor *sd,
1570 struct ea_list *ea_list,
1571 files_struct **result,
1572 int *pinfo,
1573 const struct smb2_create_blobs *in_context_blobs,
1574 struct smb2_create_blobs *out_context_blobs)
1576 VFS_FIND(create_file);
1577 return handle->fns->create_file_fn(
1578 handle, req, root_dir_fid, smb_fname, access_mask,
1579 share_access, create_disposition, create_options,
1580 file_attributes, oplock_request, lease, allocation_size,
1581 private_flags, sd, ea_list,
1582 result, pinfo, in_context_blobs, out_context_blobs);
1585 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1586 struct files_struct *fsp)
1588 VFS_FIND(close);
1589 return handle->fns->close_fn(handle, fsp);
1592 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1593 struct files_struct *fsp, void *data, size_t n)
1595 VFS_FIND(read);
1596 return handle->fns->read_fn(handle, fsp, data, n);
1599 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1600 struct files_struct *fsp, void *data, size_t n,
1601 off_t offset)
1603 VFS_FIND(pread);
1604 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1607 struct smb_vfs_call_pread_state {
1608 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1609 ssize_t retval;
1612 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1614 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1615 TALLOC_CTX *mem_ctx,
1616 struct tevent_context *ev,
1617 struct files_struct *fsp,
1618 void *data,
1619 size_t n, off_t offset)
1621 struct tevent_req *req, *subreq;
1622 struct smb_vfs_call_pread_state *state;
1624 req = tevent_req_create(mem_ctx, &state,
1625 struct smb_vfs_call_pread_state);
1626 if (req == NULL) {
1627 return NULL;
1629 VFS_FIND(pread_send);
1630 state->recv_fn = handle->fns->pread_recv_fn;
1632 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1633 offset);
1634 if (tevent_req_nomem(subreq, req)) {
1635 return tevent_req_post(req, ev);
1637 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1638 return req;
1641 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1643 struct tevent_req *req = tevent_req_callback_data(
1644 subreq, struct tevent_req);
1645 struct smb_vfs_call_pread_state *state = tevent_req_data(
1646 req, struct smb_vfs_call_pread_state);
1647 int err;
1649 state->retval = state->recv_fn(subreq, &err);
1650 TALLOC_FREE(subreq);
1651 if (state->retval == -1) {
1652 tevent_req_error(req, err);
1653 return;
1655 tevent_req_done(req);
1658 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req, int *perrno)
1660 struct smb_vfs_call_pread_state *state = tevent_req_data(
1661 req, struct smb_vfs_call_pread_state);
1662 int err;
1664 if (tevent_req_is_unix_error(req, &err)) {
1665 *perrno = err;
1666 return -1;
1668 return state->retval;
1671 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1672 struct files_struct *fsp, const void *data,
1673 size_t n)
1675 VFS_FIND(write);
1676 return handle->fns->write_fn(handle, fsp, data, n);
1679 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1680 struct files_struct *fsp, const void *data,
1681 size_t n, off_t offset)
1683 VFS_FIND(pwrite);
1684 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1687 struct smb_vfs_call_pwrite_state {
1688 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1689 ssize_t retval;
1692 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1694 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1695 TALLOC_CTX *mem_ctx,
1696 struct tevent_context *ev,
1697 struct files_struct *fsp,
1698 const void *data,
1699 size_t n, off_t offset)
1701 struct tevent_req *req, *subreq;
1702 struct smb_vfs_call_pwrite_state *state;
1704 req = tevent_req_create(mem_ctx, &state,
1705 struct smb_vfs_call_pwrite_state);
1706 if (req == NULL) {
1707 return NULL;
1709 VFS_FIND(pwrite_send);
1710 state->recv_fn = handle->fns->pwrite_recv_fn;
1712 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1713 offset);
1714 if (tevent_req_nomem(subreq, req)) {
1715 return tevent_req_post(req, ev);
1717 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1718 return req;
1721 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1723 struct tevent_req *req = tevent_req_callback_data(
1724 subreq, struct tevent_req);
1725 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1726 req, struct smb_vfs_call_pwrite_state);
1727 int err;
1729 state->retval = state->recv_fn(subreq, &err);
1730 TALLOC_FREE(subreq);
1731 if (state->retval == -1) {
1732 tevent_req_error(req, err);
1733 return;
1735 tevent_req_done(req);
1738 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req, int *perrno)
1740 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1741 req, struct smb_vfs_call_pwrite_state);
1742 int err;
1744 if (tevent_req_is_unix_error(req, &err)) {
1745 *perrno = err;
1746 return -1;
1748 return state->retval;
1751 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1752 struct files_struct *fsp, off_t offset,
1753 int whence)
1755 VFS_FIND(lseek);
1756 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1759 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1760 files_struct *fromfsp, const DATA_BLOB *header,
1761 off_t offset, size_t count)
1763 VFS_FIND(sendfile);
1764 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1765 count);
1768 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1769 files_struct *tofsp, off_t offset,
1770 size_t count)
1772 VFS_FIND(recvfile);
1773 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1776 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1777 const struct smb_filename *smb_fname_src,
1778 const struct smb_filename *smb_fname_dst)
1780 VFS_FIND(rename);
1781 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1784 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1785 struct files_struct *fsp)
1787 VFS_FIND(fsync);
1788 return handle->fns->fsync_fn(handle, fsp);
1791 struct smb_vfs_call_fsync_state {
1792 int (*recv_fn)(struct tevent_req *req, int *err);
1793 int retval;
1796 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1798 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1799 TALLOC_CTX *mem_ctx,
1800 struct tevent_context *ev,
1801 struct files_struct *fsp)
1803 struct tevent_req *req, *subreq;
1804 struct smb_vfs_call_fsync_state *state;
1806 req = tevent_req_create(mem_ctx, &state,
1807 struct smb_vfs_call_fsync_state);
1808 if (req == NULL) {
1809 return NULL;
1811 VFS_FIND(fsync_send);
1812 state->recv_fn = handle->fns->fsync_recv_fn;
1814 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1815 if (tevent_req_nomem(subreq, req)) {
1816 return tevent_req_post(req, ev);
1818 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1819 return req;
1822 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1824 struct tevent_req *req = tevent_req_callback_data(
1825 subreq, struct tevent_req);
1826 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1827 req, struct smb_vfs_call_fsync_state);
1828 int err;
1830 state->retval = state->recv_fn(subreq, &err);
1831 TALLOC_FREE(subreq);
1832 if (state->retval == -1) {
1833 tevent_req_error(req, err);
1834 return;
1836 tevent_req_done(req);
1839 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, int *perrno)
1841 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1842 req, struct smb_vfs_call_fsync_state);
1843 int err;
1845 if (tevent_req_is_unix_error(req, &err)) {
1846 *perrno = err;
1847 return -1;
1849 return state->retval;
1853 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1854 struct smb_filename *smb_fname)
1856 VFS_FIND(stat);
1857 return handle->fns->stat_fn(handle, smb_fname);
1860 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1861 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1863 VFS_FIND(fstat);
1864 return handle->fns->fstat_fn(handle, fsp, sbuf);
1867 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1868 struct smb_filename *smb_filename)
1870 VFS_FIND(lstat);
1871 return handle->fns->lstat_fn(handle, smb_filename);
1874 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1875 struct files_struct *fsp,
1876 const SMB_STRUCT_STAT *sbuf)
1878 VFS_FIND(get_alloc_size);
1879 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1882 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1883 const struct smb_filename *smb_fname)
1885 VFS_FIND(unlink);
1886 return handle->fns->unlink_fn(handle, smb_fname);
1889 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1890 mode_t mode)
1892 VFS_FIND(chmod);
1893 return handle->fns->chmod_fn(handle, path, mode);
1896 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1897 struct files_struct *fsp, mode_t mode)
1899 VFS_FIND(fchmod);
1900 return handle->fns->fchmod_fn(handle, fsp, mode);
1903 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1904 uid_t uid, gid_t gid)
1906 VFS_FIND(chown);
1907 return handle->fns->chown_fn(handle, path, uid, gid);
1910 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1911 struct files_struct *fsp, uid_t uid, gid_t gid)
1913 VFS_FIND(fchown);
1914 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1917 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1918 uid_t uid, gid_t gid)
1920 VFS_FIND(lchown);
1921 return handle->fns->lchown_fn(handle, path, uid, gid);
1924 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1926 int ret;
1927 bool as_root = false;
1928 const char *path;
1929 char *saved_dir = NULL;
1930 char *parent_dir = NULL;
1931 NTSTATUS status;
1933 if (fsp->fh->fd != -1) {
1934 /* Try fchown. */
1935 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1936 if (ret == 0) {
1937 return NT_STATUS_OK;
1939 if (ret == -1 && errno != ENOSYS) {
1940 return map_nt_error_from_unix(errno);
1944 as_root = (geteuid() == 0);
1946 if (as_root) {
1948 * We are being asked to chown as root. Make
1949 * sure we chdir() into the path to pin it,
1950 * and always act using lchown to ensure we
1951 * don't deref any symbolic links.
1953 const char *final_component = NULL;
1954 struct smb_filename local_fname;
1956 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1957 if (!saved_dir) {
1958 status = map_nt_error_from_unix(errno);
1959 DEBUG(0,("vfs_chown_fsp: failed to get "
1960 "current working directory. Error was %s\n",
1961 strerror(errno)));
1962 return status;
1965 if (!parent_dirname(talloc_tos(),
1966 fsp->fsp_name->base_name,
1967 &parent_dir,
1968 &final_component)) {
1969 return NT_STATUS_NO_MEMORY;
1972 /* cd into the parent dir to pin it. */
1973 ret = vfs_ChDir(fsp->conn, parent_dir);
1974 if (ret == -1) {
1975 return map_nt_error_from_unix(errno);
1978 ZERO_STRUCT(local_fname);
1979 local_fname.base_name = discard_const_p(char, final_component);
1981 /* Must use lstat here. */
1982 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1983 if (ret == -1) {
1984 status = map_nt_error_from_unix(errno);
1985 goto out;
1988 /* Ensure it matches the fsp stat. */
1989 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1990 status = NT_STATUS_ACCESS_DENIED;
1991 goto out;
1993 path = final_component;
1994 } else {
1995 path = fsp->fsp_name->base_name;
1998 if (fsp->posix_open || as_root) {
1999 ret = SMB_VFS_LCHOWN(fsp->conn,
2000 path,
2001 uid, gid);
2002 } else {
2003 ret = SMB_VFS_CHOWN(fsp->conn,
2004 path,
2005 uid, gid);
2008 if (ret == 0) {
2009 status = NT_STATUS_OK;
2010 } else {
2011 status = map_nt_error_from_unix(errno);
2014 out:
2016 if (as_root) {
2017 vfs_ChDir(fsp->conn,saved_dir);
2018 TALLOC_FREE(saved_dir);
2019 TALLOC_FREE(parent_dir);
2021 return status;
2024 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
2026 VFS_FIND(chdir);
2027 return handle->fns->chdir_fn(handle, path);
2030 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
2032 VFS_FIND(getwd);
2033 return handle->fns->getwd_fn(handle);
2036 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
2037 const struct smb_filename *smb_fname,
2038 struct smb_file_time *ft)
2040 VFS_FIND(ntimes);
2041 return handle->fns->ntimes_fn(handle, smb_fname, ft);
2044 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2045 struct files_struct *fsp, off_t offset)
2047 VFS_FIND(ftruncate);
2048 return handle->fns->ftruncate_fn(handle, fsp, offset);
2051 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2052 struct files_struct *fsp,
2053 uint32_t mode,
2054 off_t offset,
2055 off_t len)
2057 VFS_FIND(fallocate);
2058 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2061 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2062 struct files_struct *fsp, uint32 share_mode,
2063 uint32_t access_mask)
2065 VFS_FIND(kernel_flock);
2066 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2067 access_mask);
2070 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2071 struct files_struct *fsp, int leasetype)
2073 VFS_FIND(linux_setlease);
2074 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2077 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
2078 const char *newpath)
2080 VFS_FIND(symlink);
2081 return handle->fns->symlink_fn(handle, oldpath, newpath);
2084 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2085 const char *path, char *buf, size_t bufsiz)
2087 VFS_FIND(readlink);
2088 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
2091 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
2092 const char *newpath)
2094 VFS_FIND(link);
2095 return handle->fns->link_fn(handle, oldpath, newpath);
2098 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
2099 mode_t mode, SMB_DEV_T dev)
2101 VFS_FIND(mknod);
2102 return handle->fns->mknod_fn(handle, path, mode, dev);
2105 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
2107 VFS_FIND(realpath);
2108 return handle->fns->realpath_fn(handle, path);
2111 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
2112 struct sys_notify_context *ctx,
2113 const char *path,
2114 uint32_t *filter,
2115 uint32_t *subdir_filter,
2116 void (*callback)(struct sys_notify_context *ctx,
2117 void *private_data,
2118 struct notify_event *ev),
2119 void *private_data, void *handle_p)
2121 VFS_FIND(notify_watch);
2122 return handle->fns->notify_watch_fn(handle, ctx, path,
2123 filter, subdir_filter, callback,
2124 private_data, handle_p);
2127 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
2128 unsigned int flags)
2130 VFS_FIND(chflags);
2131 return handle->fns->chflags_fn(handle, path, flags);
2134 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2135 const SMB_STRUCT_STAT *sbuf)
2137 VFS_FIND(file_id_create);
2138 return handle->fns->file_id_create_fn(handle, sbuf);
2141 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2142 struct files_struct *fsp,
2143 const char *fname,
2144 TALLOC_CTX *mem_ctx,
2145 unsigned int *num_streams,
2146 struct stream_struct **streams)
2148 VFS_FIND(streaminfo);
2149 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
2150 num_streams, streams);
2153 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2154 const char *path, const char *name,
2155 TALLOC_CTX *mem_ctx, char **found_name)
2157 VFS_FIND(get_real_filename);
2158 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2159 found_name);
2162 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2163 const char *filename)
2165 VFS_FIND(connectpath);
2166 return handle->fns->connectpath_fn(handle, filename);
2169 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2170 struct files_struct *fsp,
2171 struct lock_struct *plock)
2173 VFS_FIND(strict_lock);
2174 return handle->fns->strict_lock_fn(handle, fsp, plock);
2177 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2178 struct files_struct *fsp,
2179 struct lock_struct *plock)
2181 VFS_FIND(strict_unlock);
2182 handle->fns->strict_unlock_fn(handle, fsp, plock);
2185 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2186 const char *name,
2187 enum vfs_translate_direction direction,
2188 TALLOC_CTX *mem_ctx,
2189 char **mapped_name)
2191 VFS_FIND(translate_name);
2192 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2193 mapped_name);
2196 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2197 struct files_struct *fsp,
2198 TALLOC_CTX *ctx,
2199 uint32_t function,
2200 uint16_t req_flags,
2201 const uint8_t *in_data,
2202 uint32_t in_len,
2203 uint8_t **out_data,
2204 uint32_t max_out_len,
2205 uint32_t *out_len)
2207 VFS_FIND(fsctl);
2208 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2209 in_data, in_len, out_data, max_out_len,
2210 out_len);
2213 struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle,
2214 TALLOC_CTX *mem_ctx,
2215 struct tevent_context *ev,
2216 struct files_struct *src_fsp,
2217 off_t src_off,
2218 struct files_struct *dest_fsp,
2219 off_t dest_off,
2220 off_t num)
2222 VFS_FIND(copy_chunk_send);
2223 return handle->fns->copy_chunk_send_fn(handle, mem_ctx, ev, src_fsp,
2224 src_off, dest_fsp, dest_off, num);
2227 NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,
2228 struct tevent_req *req,
2229 off_t *copied)
2231 VFS_FIND(copy_chunk_recv);
2232 return handle->fns->copy_chunk_recv_fn(handle, req, copied);
2235 NTSTATUS smb_vfs_call_get_compression(vfs_handle_struct *handle,
2236 TALLOC_CTX *mem_ctx,
2237 struct files_struct *fsp,
2238 struct smb_filename *smb_fname,
2239 uint16_t *_compression_fmt)
2241 VFS_FIND(get_compression);
2242 return handle->fns->get_compression_fn(handle, mem_ctx, fsp, smb_fname,
2243 _compression_fmt);
2246 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2247 TALLOC_CTX *mem_ctx,
2248 struct files_struct *fsp,
2249 uint16_t compression_fmt)
2251 VFS_FIND(set_compression);
2252 return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2253 compression_fmt);
2256 NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
2257 TALLOC_CTX *mem_ctx,
2258 const char *service_path,
2259 char **base_volume)
2261 VFS_FIND(snap_check_path);
2262 return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path,
2263 base_volume);
2266 NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle,
2267 TALLOC_CTX *mem_ctx,
2268 const char *base_volume,
2269 time_t *tstamp,
2270 bool rw,
2271 char **base_path,
2272 char **snap_path)
2274 VFS_FIND(snap_create);
2275 return handle->fns->snap_create_fn(handle, mem_ctx, base_volume, tstamp,
2276 rw, base_path, snap_path);
2279 NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle,
2280 TALLOC_CTX *mem_ctx,
2281 char *base_path,
2282 char *snap_path)
2284 VFS_FIND(snap_delete);
2285 return handle->fns->snap_delete_fn(handle, mem_ctx, base_path,
2286 snap_path);
2289 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2290 struct files_struct *fsp,
2291 uint32 security_info,
2292 TALLOC_CTX *mem_ctx,
2293 struct security_descriptor **ppdesc)
2295 VFS_FIND(fget_nt_acl);
2296 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2297 mem_ctx, ppdesc);
2300 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2301 const char *name,
2302 uint32 security_info,
2303 TALLOC_CTX *mem_ctx,
2304 struct security_descriptor **ppdesc)
2306 VFS_FIND(get_nt_acl);
2307 return handle->fns->get_nt_acl_fn(handle, name, security_info, mem_ctx, ppdesc);
2310 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2311 struct files_struct *fsp,
2312 uint32 security_info_sent,
2313 const struct security_descriptor *psd)
2315 VFS_FIND(fset_nt_acl);
2316 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2317 psd);
2320 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2321 struct smb_filename *file,
2322 struct security_acl *sacl,
2323 uint32_t access_requested,
2324 uint32_t access_denied)
2326 VFS_FIND(audit_file);
2327 return handle->fns->audit_file_fn(handle,
2328 file,
2329 sacl,
2330 access_requested,
2331 access_denied);
2334 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2335 mode_t mode)
2337 VFS_FIND(chmod_acl);
2338 return handle->fns->chmod_acl_fn(handle, name, mode);
2341 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2342 struct files_struct *fsp, mode_t mode)
2344 VFS_FIND(fchmod_acl);
2345 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2348 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2349 const char *path_p,
2350 SMB_ACL_TYPE_T type,
2351 TALLOC_CTX *mem_ctx)
2353 VFS_FIND(sys_acl_get_file);
2354 return handle->fns->sys_acl_get_file_fn(handle, path_p, type, mem_ctx);
2357 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2358 struct files_struct *fsp,
2359 TALLOC_CTX *mem_ctx)
2361 VFS_FIND(sys_acl_get_fd);
2362 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2365 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2366 const char *path_p,
2367 TALLOC_CTX *mem_ctx,
2368 char **blob_description,
2369 DATA_BLOB *blob)
2371 VFS_FIND(sys_acl_blob_get_file);
2372 return handle->fns->sys_acl_blob_get_file_fn(handle, path_p, mem_ctx, blob_description, blob);
2375 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2376 struct files_struct *fsp,
2377 TALLOC_CTX *mem_ctx,
2378 char **blob_description,
2379 DATA_BLOB *blob)
2381 VFS_FIND(sys_acl_blob_get_fd);
2382 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2385 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2386 const char *name, SMB_ACL_TYPE_T acltype,
2387 SMB_ACL_T theacl)
2389 VFS_FIND(sys_acl_set_file);
2390 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2393 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2394 struct files_struct *fsp, SMB_ACL_T theacl)
2396 VFS_FIND(sys_acl_set_fd);
2397 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2400 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2401 const char *path)
2403 VFS_FIND(sys_acl_delete_def_file);
2404 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2407 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2408 const char *path, const char *name, void *value,
2409 size_t size)
2411 VFS_FIND(getxattr);
2412 return handle->fns->getxattr_fn(handle, path, name, value, size);
2415 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2416 struct files_struct *fsp, const char *name,
2417 void *value, size_t size)
2419 VFS_FIND(fgetxattr);
2420 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2423 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2424 const char *path, char *list, size_t size)
2426 VFS_FIND(listxattr);
2427 return handle->fns->listxattr_fn(handle, path, list, size);
2430 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2431 struct files_struct *fsp, char *list,
2432 size_t size)
2434 VFS_FIND(flistxattr);
2435 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2438 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2439 const char *path, const char *name)
2441 VFS_FIND(removexattr);
2442 return handle->fns->removexattr_fn(handle, path, name);
2445 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2446 struct files_struct *fsp, const char *name)
2448 VFS_FIND(fremovexattr);
2449 return handle->fns->fremovexattr_fn(handle, fsp, name);
2452 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2453 const char *name, const void *value, size_t size,
2454 int flags)
2456 VFS_FIND(setxattr);
2457 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2460 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2461 struct files_struct *fsp, const char *name,
2462 const void *value, size_t size, int flags)
2464 VFS_FIND(fsetxattr);
2465 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2468 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2469 struct files_struct *fsp)
2471 VFS_FIND(aio_force);
2472 return handle->fns->aio_force_fn(handle, fsp);
2475 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2476 const struct smb_filename *fname,
2477 SMB_STRUCT_STAT *sbuf)
2479 VFS_FIND(is_offline);
2480 return handle->fns->is_offline_fn(handle, fname, sbuf);
2483 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2484 const struct smb_filename *fname)
2486 VFS_FIND(set_offline);
2487 return handle->fns->set_offline_fn(handle, fname);
2490 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2491 struct files_struct *fsp,
2492 TALLOC_CTX *mem_ctx,
2493 DATA_BLOB *cookie)
2495 VFS_FIND(durable_cookie);
2496 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2499 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2500 struct files_struct *fsp,
2501 const DATA_BLOB old_cookie,
2502 TALLOC_CTX *mem_ctx,
2503 DATA_BLOB *new_cookie)
2505 VFS_FIND(durable_disconnect);
2506 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2507 mem_ctx, new_cookie);
2510 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2511 struct smb_request *smb1req,
2512 struct smbXsrv_open *op,
2513 const DATA_BLOB old_cookie,
2514 TALLOC_CTX *mem_ctx,
2515 struct files_struct **fsp,
2516 DATA_BLOB *new_cookie)
2518 VFS_FIND(durable_reconnect);
2519 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2520 old_cookie, mem_ctx, fsp,
2521 new_cookie);
2524 NTSTATUS smb_vfs_call_readdir_attr(struct vfs_handle_struct *handle,
2525 const struct smb_filename *fname,
2526 TALLOC_CTX *mem_ctx,
2527 struct readdir_attr_data **attr_data)
2529 VFS_FIND(readdir_attr);
2530 return handle->fns->readdir_attr_fn(handle, fname, mem_ctx, attr_data);