librpc: Shorten dcerpc_binding_handle_call a bit
[Samba/gebeck_regimport.git] / source3 / smbd / vfs.c
blob49609d0179412196b7f447749acb10dd690bd9f9
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 VFS initialisation and support functions
5 Copyright (C) Tim Potter 1999
6 Copyright (C) Alexander Bokovoy 2002
7 Copyright (C) James Peach 2006
8 Copyright (C) Volker Lendecke 2009
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 This work was sponsored by Optifacio Software Services, Inc.
26 #include "includes.h"
27 #include "system/filesys.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "memcache.h"
31 #include "transfer_file.h"
32 #include "ntioctl.h"
33 #include "lib/util/tevent_unix.h"
35 #undef DBGC_CLASS
36 #define DBGC_CLASS DBGC_VFS
38 static_decl_vfs;
40 struct vfs_fsp_data {
41 struct vfs_fsp_data *next;
42 struct vfs_handle_struct *owner;
43 void (*destroy)(void *p_data);
44 void *_dummy_;
45 /* NOTE: This structure contains four pointers so that we can guarantee
46 * that the end of the structure is always both 4-byte and 8-byte aligned.
50 struct vfs_init_function_entry {
51 char *name;
52 struct vfs_init_function_entry *prev, *next;
53 const struct vfs_fn_pointers *fns;
56 /****************************************************************************
57 maintain the list of available backends
58 ****************************************************************************/
60 static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
62 struct vfs_init_function_entry *entry = backends;
64 DEBUG(10, ("vfs_find_backend_entry called for %s\n", name));
66 while(entry) {
67 if (strcmp(entry->name, name)==0) return entry;
68 entry = entry->next;
71 return NULL;
74 NTSTATUS smb_register_vfs(int version, const char *name,
75 const struct vfs_fn_pointers *fns)
77 struct vfs_init_function_entry *entry = backends;
79 if ((version != SMB_VFS_INTERFACE_VERSION)) {
80 DEBUG(0, ("Failed to register vfs module.\n"
81 "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
82 "current SMB_VFS_INTERFACE_VERSION is %d.\n"
83 "Please recompile against the current Samba Version!\n",
84 version, SMB_VFS_INTERFACE_VERSION));
85 return NT_STATUS_OBJECT_TYPE_MISMATCH;
88 if (!name || !name[0]) {
89 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
90 return NT_STATUS_INVALID_PARAMETER;
93 if (vfs_find_backend_entry(name)) {
94 DEBUG(0,("VFS module %s already loaded!\n", name));
95 return NT_STATUS_OBJECT_NAME_COLLISION;
98 entry = SMB_XMALLOC_P(struct vfs_init_function_entry);
99 entry->name = smb_xstrdup(name);
100 entry->fns = fns;
102 DLIST_ADD(backends, entry);
103 DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
104 return NT_STATUS_OK;
107 /****************************************************************************
108 initialise default vfs hooks
109 ****************************************************************************/
111 static void vfs_init_default(connection_struct *conn)
113 DEBUG(3, ("Initialising default vfs hooks\n"));
114 vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME);
117 /****************************************************************************
118 initialise custom vfs hooks
119 ****************************************************************************/
121 bool vfs_init_custom(connection_struct *conn, const char *vfs_object)
123 char *module_path = NULL;
124 char *module_name = NULL;
125 char *module_param = NULL, *p;
126 vfs_handle_struct *handle;
127 const struct vfs_init_function_entry *entry;
129 if (!conn||!vfs_object||!vfs_object[0]) {
130 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
131 "empty vfs_object!\n"));
132 return False;
135 if(!backends) {
136 static_init_vfs;
139 DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
141 module_path = smb_xstrdup(vfs_object);
143 p = strchr_m(module_path, ':');
145 if (p) {
146 *p = 0;
147 module_param = p+1;
148 trim_char(module_param, ' ', ' ');
151 trim_char(module_path, ' ', ' ');
153 module_name = smb_xstrdup(module_path);
155 if ((module_name[0] == '/') &&
156 (strcmp(module_path, DEFAULT_VFS_MODULE_NAME) != 0)) {
159 * Extract the module name from the path. Just use the base
160 * name of the last path component.
163 SAFE_FREE(module_name);
164 module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
166 p = strchr_m(module_name, '.');
168 if (p != NULL) {
169 *p = '\0';
173 /* First, try to load the module with the new module system */
174 entry = vfs_find_backend_entry(module_name);
175 if (!entry) {
176 NTSTATUS status;
178 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
179 vfs_object));
181 status = smb_load_module("vfs", module_path);
182 if (!NT_STATUS_IS_OK(status)) {
183 DEBUG(0, ("error probing vfs module '%s': %s\n",
184 module_path, nt_errstr(status)));
185 goto fail;
188 entry = vfs_find_backend_entry(module_name);
189 if (!entry) {
190 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
191 goto fail;
195 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
197 handle = talloc_zero(conn, vfs_handle_struct);
198 if (!handle) {
199 DEBUG(0,("TALLOC_ZERO() failed!\n"));
200 goto fail;
202 handle->conn = conn;
203 handle->fns = entry->fns;
204 if (module_param) {
205 handle->param = talloc_strdup(conn, module_param);
207 DLIST_ADD(conn->vfs_handles, handle);
209 SAFE_FREE(module_path);
210 SAFE_FREE(module_name);
211 return True;
213 fail:
214 SAFE_FREE(module_path);
215 SAFE_FREE(module_name);
216 return False;
219 /*****************************************************************
220 Allow VFS modules to extend files_struct with VFS-specific state.
221 This will be ok for small numbers of extensions, but might need to
222 be refactored if it becomes more widely used.
223 ******************************************************************/
225 #define EXT_DATA_AREA(e) ((uint8 *)(e) + sizeof(struct vfs_fsp_data))
227 void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle,
228 files_struct *fsp, size_t ext_size,
229 void (*destroy_fn)(void *p_data))
231 struct vfs_fsp_data *ext;
232 void * ext_data;
234 /* Prevent VFS modules adding multiple extensions. */
235 if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
236 return ext_data;
239 ext = (struct vfs_fsp_data *)TALLOC_ZERO(
240 handle->conn, sizeof(struct vfs_fsp_data) + ext_size);
241 if (ext == NULL) {
242 return NULL;
245 ext->owner = handle;
246 ext->next = fsp->vfs_extension;
247 ext->destroy = destroy_fn;
248 fsp->vfs_extension = ext;
249 return EXT_DATA_AREA(ext);
252 void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
254 struct vfs_fsp_data *curr;
255 struct vfs_fsp_data *prev;
257 for (curr = fsp->vfs_extension, prev = NULL;
258 curr;
259 prev = curr, curr = curr->next) {
260 if (curr->owner == handle) {
261 if (prev) {
262 prev->next = curr->next;
263 } else {
264 fsp->vfs_extension = curr->next;
266 if (curr->destroy) {
267 curr->destroy(EXT_DATA_AREA(curr));
269 TALLOC_FREE(curr);
270 return;
275 void vfs_remove_all_fsp_extensions(files_struct *fsp)
277 struct vfs_fsp_data *curr;
278 struct vfs_fsp_data *next;
280 for (curr = fsp->vfs_extension; curr; curr = next) {
282 next = curr->next;
283 fsp->vfs_extension = next;
285 if (curr->destroy) {
286 curr->destroy(EXT_DATA_AREA(curr));
288 TALLOC_FREE(curr);
292 void *vfs_memctx_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
294 struct vfs_fsp_data *head;
296 for (head = fsp->vfs_extension; head; head = head->next) {
297 if (head->owner == handle) {
298 return head;
302 return NULL;
305 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
307 struct vfs_fsp_data *head;
309 head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
310 if (head != NULL) {
311 return EXT_DATA_AREA(head);
314 return NULL;
317 #undef EXT_DATA_AREA
319 /*****************************************************************
320 Generic VFS init.
321 ******************************************************************/
323 bool smbd_vfs_init(connection_struct *conn)
325 const char **vfs_objects;
326 unsigned int i = 0;
327 int j = 0;
329 /* Normal share - initialise with disk access functions */
330 vfs_init_default(conn);
332 /* No need to load vfs modules for printer connections */
333 if (conn->printer) {
334 return True;
337 vfs_objects = lp_vfs_objects(SNUM(conn));
339 /* Override VFS functions if 'vfs object' was not specified*/
340 if (!vfs_objects || !vfs_objects[0])
341 return True;
343 for (i=0; vfs_objects[i] ;) {
344 i++;
347 for (j=i-1; j >= 0; j--) {
348 if (!vfs_init_custom(conn, vfs_objects[j])) {
349 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
350 return False;
353 return True;
356 /*******************************************************************
357 Check if a file exists in the vfs.
358 ********************************************************************/
360 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
362 /* Only return OK if stat was successful and S_ISREG */
363 if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
364 S_ISREG(smb_fname->st.st_ex_mode)) {
365 return NT_STATUS_OK;
368 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
371 /****************************************************************************
372 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
373 ****************************************************************************/
375 ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
377 size_t total=0;
379 while (total < byte_count)
381 ssize_t ret = SMB_VFS_READ(fsp, buf + total,
382 byte_count - total);
384 if (ret == 0) return total;
385 if (ret == -1) {
386 if (errno == EINTR)
387 continue;
388 else
389 return -1;
391 total += ret;
393 return (ssize_t)total;
396 ssize_t vfs_pread_data(files_struct *fsp, char *buf,
397 size_t byte_count, off_t offset)
399 size_t total=0;
401 while (total < byte_count)
403 ssize_t ret = SMB_VFS_PREAD(fsp, buf + total,
404 byte_count - total, offset + total);
406 if (ret == 0) return total;
407 if (ret == -1) {
408 if (errno == EINTR)
409 continue;
410 else
411 return -1;
413 total += ret;
415 return (ssize_t)total;
418 /****************************************************************************
419 Write data to a fd on the vfs.
420 ****************************************************************************/
422 ssize_t vfs_write_data(struct smb_request *req,
423 files_struct *fsp,
424 const char *buffer,
425 size_t N)
427 size_t total=0;
428 ssize_t ret;
430 if (req && req->unread_bytes) {
431 int sockfd = req->sconn->sock;
432 int old_flags;
433 SMB_ASSERT(req->unread_bytes == N);
434 /* VFS_RECVFILE must drain the socket
435 * before returning. */
436 req->unread_bytes = 0;
437 /* Ensure the socket is blocking. */
438 old_flags = fcntl(sockfd, F_GETFL, 0);
439 if (set_blocking(sockfd, true) == -1) {
440 return (ssize_t)-1;
442 ret = SMB_VFS_RECVFILE(sockfd,
443 fsp,
444 (off_t)-1,
446 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
447 return (ssize_t)-1;
449 return ret;
452 while (total < N) {
453 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
455 if (ret == -1)
456 return -1;
457 if (ret == 0)
458 return total;
460 total += ret;
462 return (ssize_t)total;
465 ssize_t vfs_pwrite_data(struct smb_request *req,
466 files_struct *fsp,
467 const char *buffer,
468 size_t N,
469 off_t offset)
471 size_t total=0;
472 ssize_t ret;
474 if (req && req->unread_bytes) {
475 int sockfd = req->sconn->sock;
476 int old_flags;
477 SMB_ASSERT(req->unread_bytes == N);
478 /* VFS_RECVFILE must drain the socket
479 * before returning. */
480 req->unread_bytes = 0;
481 /* Ensure the socket is blocking. */
482 old_flags = fcntl(sockfd, F_GETFL, 0);
483 if (set_blocking(sockfd, true) == -1) {
484 return (ssize_t)-1;
486 ret = SMB_VFS_RECVFILE(sockfd,
487 fsp,
488 offset,
490 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
491 return (ssize_t)-1;
493 return ret;
496 while (total < N) {
497 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
498 offset + total);
500 if (ret == -1)
501 return -1;
502 if (ret == 0)
503 return total;
505 total += ret;
507 return (ssize_t)total;
509 /****************************************************************************
510 An allocate file space call using the vfs interface.
511 Allocates space for a file from a filedescriptor.
512 Returns 0 on success, -1 on failure.
513 ****************************************************************************/
515 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
517 int ret;
518 connection_struct *conn = fsp->conn;
519 uint64_t space_avail;
520 uint64_t bsize,dfree,dsize;
521 NTSTATUS status;
524 * Actually try and commit the space on disk....
527 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
528 fsp_str_dbg(fsp), (double)len));
530 if (((off_t)len) < 0) {
531 DEBUG(0,("vfs_allocate_file_space: %s negative len "
532 "requested.\n", fsp_str_dbg(fsp)));
533 errno = EINVAL;
534 return -1;
537 status = vfs_stat_fsp(fsp);
538 if (!NT_STATUS_IS_OK(status)) {
539 return -1;
542 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
543 return 0;
545 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
546 /* Shrink - use ftruncate. */
548 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
549 "size %.0f\n", fsp_str_dbg(fsp),
550 (double)fsp->fsp_name->st.st_ex_size));
552 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
554 flush_write_cache(fsp, SIZECHANGE_FLUSH);
555 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
556 set_filelen_write_cache(fsp, len);
559 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
561 return ret;
564 if (!lp_strict_allocate(SNUM(fsp->conn)))
565 return 0;
567 /* Grow - we need to test if we have enough space. */
569 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
571 /* See if we have a syscall that will allocate beyond end-of-file
572 without changing EOF. */
573 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
575 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
577 if (ret == 0) {
578 /* We changed the allocation size on disk, but not
579 EOF - exactly as required. We're done ! */
580 return 0;
583 len -= fsp->fsp_name->st.st_ex_size;
584 len /= 1024; /* Len is now number of 1k blocks needed. */
585 space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
586 &bsize, &dfree, &dsize);
587 if (space_avail == (uint64_t)-1) {
588 return -1;
591 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
592 "needed blocks = %.0f, space avail = %.0f\n",
593 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
594 (double)space_avail));
596 if (len > space_avail) {
597 errno = ENOSPC;
598 return -1;
601 return 0;
604 /****************************************************************************
605 A vfs set_filelen call.
606 set the length of a file from a filedescriptor.
607 Returns 0 on success, -1 on failure.
608 ****************************************************************************/
610 int vfs_set_filelen(files_struct *fsp, off_t len)
612 int ret;
614 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
616 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
617 fsp_str_dbg(fsp), (double)len));
618 flush_write_cache(fsp, SIZECHANGE_FLUSH);
619 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
620 set_filelen_write_cache(fsp, len);
621 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
622 FILE_NOTIFY_CHANGE_SIZE
623 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
624 fsp->fsp_name->base_name);
627 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
629 return ret;
632 /****************************************************************************
633 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
634 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
635 as this is also called from the default SMB_VFS_FTRUNCATE code.
636 Always extends the file size.
637 Returns 0 on success, errno on failure.
638 ****************************************************************************/
640 #define SPARSE_BUF_WRITE_SIZE (32*1024)
642 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
644 ssize_t pwrite_ret;
645 size_t total = 0;
647 if (!sparse_buf) {
648 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
649 if (!sparse_buf) {
650 errno = ENOMEM;
651 return ENOMEM;
655 while (total < len) {
656 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
658 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
659 if (pwrite_ret == -1) {
660 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
661 "%s failed with error %s\n",
662 fsp_str_dbg(fsp), strerror(errno)));
663 return errno;
665 total += pwrite_ret;
668 return 0;
671 /****************************************************************************
672 A vfs fill sparse call.
673 Writes zeros from the end of file to len, if len is greater than EOF.
674 Used only by strict_sync.
675 Returns 0 on success, -1 on failure.
676 ****************************************************************************/
678 int vfs_fill_sparse(files_struct *fsp, off_t len)
680 int ret;
681 NTSTATUS status;
682 off_t offset;
683 size_t num_to_write;
685 status = vfs_stat_fsp(fsp);
686 if (!NT_STATUS_IS_OK(status)) {
687 return -1;
690 if (len <= fsp->fsp_name->st.st_ex_size) {
691 return 0;
694 #ifdef S_ISFIFO
695 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
696 return 0;
698 #endif
700 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
701 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
702 (double)fsp->fsp_name->st.st_ex_size, (double)len,
703 (double)(len - fsp->fsp_name->st.st_ex_size)));
705 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
707 flush_write_cache(fsp, SIZECHANGE_FLUSH);
709 offset = fsp->fsp_name->st.st_ex_size;
710 num_to_write = len - fsp->fsp_name->st.st_ex_size;
712 /* Only do this on non-stream file handles. */
713 if (fsp->base_fsp == NULL) {
714 /* for allocation try fallocate first. This can fail on some
715 * platforms e.g. when the filesystem doesn't support it and no
716 * emulation is being done by the libc (like on AIX with JFS1). In that
717 * case we do our own emulation. fallocate implementations can
718 * return ENOTSUP or EINVAL in cases like that. */
719 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
720 offset, num_to_write);
721 if (ret == ENOSPC) {
722 errno = ENOSPC;
723 ret = -1;
724 goto out;
726 if (ret == 0) {
727 goto out;
729 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
730 "error %d. Falling back to slow manual allocation\n", ret));
733 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
734 if (ret != 0) {
735 errno = ret;
736 ret = -1;
739 out:
741 if (ret == 0) {
742 set_filelen_write_cache(fsp, len);
745 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
746 return ret;
749 /****************************************************************************
750 Transfer some data (n bytes) between two file_struct's.
751 ****************************************************************************/
753 static ssize_t vfs_read_fn(void *file, void *buf, size_t len)
755 struct files_struct *fsp = (struct files_struct *)file;
757 return SMB_VFS_READ(fsp, buf, len);
760 static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
762 struct files_struct *fsp = (struct files_struct *)file;
764 return SMB_VFS_WRITE(fsp, buf, len);
767 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
769 return transfer_file_internal((void *)in, (void *)out, n,
770 vfs_read_fn, vfs_write_fn);
773 /*******************************************************************
774 A vfs_readdir wrapper which just returns the file name.
775 ********************************************************************/
777 const char *vfs_readdirname(connection_struct *conn, void *p,
778 SMB_STRUCT_STAT *sbuf, char **talloced)
780 struct dirent *ptr= NULL;
781 const char *dname;
782 char *translated;
783 NTSTATUS status;
785 if (!p)
786 return(NULL);
788 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
789 if (!ptr)
790 return(NULL);
792 dname = ptr->d_name;
795 #ifdef NEXT2
796 if (telldir(p) < 0)
797 return(NULL);
798 #endif
800 #ifdef HAVE_BROKEN_READDIR_NAME
801 /* using /usr/ucb/cc is BAD */
802 dname = dname - 2;
803 #endif
805 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
806 talloc_tos(), &translated);
807 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
808 *talloced = NULL;
809 return dname;
811 *talloced = translated;
812 if (!NT_STATUS_IS_OK(status)) {
813 return NULL;
815 return translated;
818 /*******************************************************************
819 A wrapper for vfs_chdir().
820 ********************************************************************/
822 int vfs_ChDir(connection_struct *conn, const char *path)
824 int ret;
826 if (!LastDir) {
827 LastDir = SMB_STRDUP("");
830 if (strcsequal(path,".")) {
831 return 0;
834 if (*path == '/' && strcsequal(LastDir,path)) {
835 return 0;
838 DEBUG(4,("vfs_ChDir to %s\n",path));
840 ret = SMB_VFS_CHDIR(conn,path);
841 if (ret == 0) {
842 /* Global cache. */
843 SAFE_FREE(LastDir);
844 LastDir = SMB_STRDUP(path);
846 /* conn cache. */
847 TALLOC_FREE(conn->cwd);
848 conn->cwd = vfs_GetWd(conn, conn);
849 DEBUG(4,("vfs_ChDir got %s\n",conn->cwd));
851 return ret;
854 /*******************************************************************
855 Return the absolute current directory path - given a UNIX pathname.
856 Note that this path is returned in DOS format, not UNIX
857 format. Note this can be called with conn == NULL.
858 ********************************************************************/
860 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
862 char *current_dir = NULL;
863 char *result = NULL;
864 DATA_BLOB cache_value;
865 struct file_id key;
866 struct smb_filename *smb_fname_dot = NULL;
867 struct smb_filename *smb_fname_full = NULL;
869 if (!lp_getwd_cache()) {
870 goto nocache;
873 smb_fname_dot = synthetic_smb_fname(ctx, ".", NULL, NULL);
874 if (smb_fname_dot == NULL) {
875 errno = ENOMEM;
876 goto out;
879 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
881 * Known to fail for root: the directory may be NFS-mounted
882 * and exported with root_squash (so has no root access).
884 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
885 "(NFS problem ?)\n", strerror(errno) ));
886 goto nocache;
889 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
891 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
892 data_blob_const(&key, sizeof(key)),
893 &cache_value)) {
894 goto nocache;
897 SMB_ASSERT((cache_value.length > 0)
898 && (cache_value.data[cache_value.length-1] == '\0'));
900 smb_fname_full = synthetic_smb_fname(ctx, (char *)cache_value.data,
901 NULL, NULL);
902 if (smb_fname_full == NULL) {
903 errno = ENOMEM;
904 goto out;
907 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
908 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
909 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
910 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
912 * Ok, we're done
914 result = talloc_strdup(ctx, smb_fname_full->base_name);
915 if (result == NULL) {
916 errno = ENOMEM;
918 goto out;
921 nocache:
924 * We don't have the information to hand so rely on traditional
925 * methods. The very slow getcwd, which spawns a process on some
926 * systems, or the not quite so bad getwd.
929 current_dir = SMB_VFS_GETWD(conn);
930 if (current_dir == NULL) {
931 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
932 strerror(errno)));
933 goto out;
936 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
937 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
939 memcache_add(smbd_memcache(), GETWD_CACHE,
940 data_blob_const(&key, sizeof(key)),
941 data_blob_const(current_dir,
942 strlen(current_dir)+1));
945 result = talloc_strdup(ctx, current_dir);
946 if (result == NULL) {
947 errno = ENOMEM;
950 out:
951 TALLOC_FREE(smb_fname_dot);
952 TALLOC_FREE(smb_fname_full);
953 SAFE_FREE(current_dir);
954 return result;
957 /*******************************************************************
958 Reduce a file name, removing .. elements and checking that
959 it is below dir in the heirachy. This uses realpath.
960 This function must run as root, and will return names
961 and valid stat structs that can be checked on open.
962 ********************************************************************/
964 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
965 const char *fname,
966 struct smb_request *smbreq)
968 NTSTATUS status;
969 TALLOC_CTX *ctx = talloc_tos();
970 const char *conn_rootdir;
971 size_t rootdir_len;
972 char *dir_name = NULL;
973 const char *last_component = NULL;
974 char *resolved_name = NULL;
975 char *saved_dir = NULL;
976 struct smb_filename *smb_fname_cwd = NULL;
977 struct privilege_paths *priv_paths = NULL;
978 int ret;
980 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
981 fname,
982 conn->connectpath));
985 priv_paths = talloc_zero(smbreq, struct privilege_paths);
986 if (!priv_paths) {
987 status = NT_STATUS_NO_MEMORY;
988 goto err;
991 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
992 status = NT_STATUS_NO_MEMORY;
993 goto err;
996 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
997 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
999 if (priv_paths->parent_name.base_name == NULL ||
1000 priv_paths->file_name.base_name == NULL) {
1001 status = NT_STATUS_NO_MEMORY;
1002 goto err;
1005 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
1006 status = map_nt_error_from_unix(errno);
1007 goto err;
1009 /* Remember where we were. */
1010 saved_dir = vfs_GetWd(ctx, conn);
1011 if (!saved_dir) {
1012 status = map_nt_error_from_unix(errno);
1013 goto err;
1016 /* Go to the parent directory to lock in memory. */
1017 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
1018 status = map_nt_error_from_unix(errno);
1019 goto err;
1022 /* Get the absolute path of the parent directory. */
1023 resolved_name = SMB_VFS_REALPATH(conn,".");
1024 if (!resolved_name) {
1025 status = map_nt_error_from_unix(errno);
1026 goto err;
1029 if (*resolved_name != '/') {
1030 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1031 "doesn't return absolute paths !\n"));
1032 status = NT_STATUS_OBJECT_NAME_INVALID;
1033 goto err;
1036 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1037 priv_paths->parent_name.base_name,
1038 resolved_name));
1040 /* Now check the stat value is the same. */
1041 smb_fname_cwd = synthetic_smb_fname(talloc_tos(), ".", NULL, NULL);
1042 if (smb_fname_cwd == NULL) {
1043 status = NT_STATUS_NO_MEMORY;
1044 goto err;
1047 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1048 status = map_nt_error_from_unix(errno);
1049 goto err;
1052 /* Ensure we're pointing at the same place. */
1053 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1054 DEBUG(0,("check_reduced_name_with_privilege: "
1055 "device/inode/uid/gid on directory %s changed. "
1056 "Denying access !\n",
1057 priv_paths->parent_name.base_name));
1058 status = NT_STATUS_ACCESS_DENIED;
1059 goto err;
1062 /* Ensure we're below the connect path. */
1064 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1065 if (conn_rootdir == NULL) {
1066 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1067 "conn_rootdir\n"));
1068 status = NT_STATUS_ACCESS_DENIED;
1069 goto err;
1072 rootdir_len = strlen(conn_rootdir);
1073 if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1074 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1075 "attempt: %s is a symlink outside the "
1076 "share path\n",
1077 dir_name));
1078 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1079 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1080 status = NT_STATUS_ACCESS_DENIED;
1081 goto err;
1084 /* Now ensure that the last component either doesn't
1085 exist, or is *NOT* a symlink. */
1087 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1088 if (ret == -1) {
1089 /* Errno must be ENOENT for this be ok. */
1090 if (errno != ENOENT) {
1091 status = map_nt_error_from_unix(errno);
1092 DEBUG(2, ("check_reduced_name_with_privilege: "
1093 "LSTAT on %s failed with %s\n",
1094 priv_paths->file_name.base_name,
1095 nt_errstr(status)));
1096 goto err;
1100 if (VALID_STAT(priv_paths->file_name.st) &&
1101 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1102 DEBUG(2, ("check_reduced_name_with_privilege: "
1103 "Last component %s is a symlink. Denying"
1104 "access.\n",
1105 priv_paths->file_name.base_name));
1106 status = NT_STATUS_ACCESS_DENIED;
1107 goto err;
1110 smbreq->priv_paths = priv_paths;
1111 status = NT_STATUS_OK;
1113 err:
1115 if (saved_dir) {
1116 vfs_ChDir(conn, saved_dir);
1118 SAFE_FREE(resolved_name);
1119 if (!NT_STATUS_IS_OK(status)) {
1120 TALLOC_FREE(priv_paths);
1122 TALLOC_FREE(dir_name);
1123 return status;
1126 /*******************************************************************
1127 Reduce a file name, removing .. elements and checking that
1128 it is below dir in the heirachy. This uses realpath.
1129 ********************************************************************/
1131 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1133 char *resolved_name = NULL;
1134 bool allow_symlinks = true;
1135 bool allow_widelinks = false;
1137 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1139 resolved_name = SMB_VFS_REALPATH(conn,fname);
1141 if (!resolved_name) {
1142 switch (errno) {
1143 case ENOTDIR:
1144 DEBUG(3,("check_reduced_name: Component not a "
1145 "directory in getting realpath for "
1146 "%s\n", fname));
1147 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1148 case ENOENT:
1150 TALLOC_CTX *ctx = talloc_tos();
1151 char *dir_name = NULL;
1152 const char *last_component = NULL;
1153 char *new_name = NULL;
1154 int ret;
1156 /* Last component didn't exist.
1157 Remove it and try and canonicalise
1158 the directory name. */
1159 if (!parent_dirname(ctx, fname,
1160 &dir_name,
1161 &last_component)) {
1162 return NT_STATUS_NO_MEMORY;
1165 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1166 if (!resolved_name) {
1167 NTSTATUS status = map_nt_error_from_unix(errno);
1169 if (errno == ENOENT || errno == ENOTDIR) {
1170 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1173 DEBUG(3,("check_reduce_name: "
1174 "couldn't get realpath for "
1175 "%s (%s)\n",
1176 fname,
1177 nt_errstr(status)));
1178 return status;
1180 ret = asprintf(&new_name, "%s/%s",
1181 resolved_name, last_component);
1182 SAFE_FREE(resolved_name);
1183 if (ret == -1) {
1184 return NT_STATUS_NO_MEMORY;
1186 resolved_name = new_name;
1187 break;
1189 default:
1190 DEBUG(3,("check_reduced_name: couldn't get "
1191 "realpath for %s\n", fname));
1192 return map_nt_error_from_unix(errno);
1196 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1197 resolved_name));
1199 if (*resolved_name != '/') {
1200 DEBUG(0,("check_reduced_name: realpath doesn't return "
1201 "absolute paths !\n"));
1202 SAFE_FREE(resolved_name);
1203 return NT_STATUS_OBJECT_NAME_INVALID;
1206 allow_widelinks = lp_widelinks(SNUM(conn));
1207 allow_symlinks = lp_symlinks(SNUM(conn));
1209 /* Common widelinks and symlinks checks. */
1210 if (!allow_widelinks || !allow_symlinks) {
1211 const char *conn_rootdir;
1212 size_t rootdir_len;
1214 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1215 if (conn_rootdir == NULL) {
1216 DEBUG(2, ("check_reduced_name: Could not get "
1217 "conn_rootdir\n"));
1218 SAFE_FREE(resolved_name);
1219 return NT_STATUS_ACCESS_DENIED;
1222 rootdir_len = strlen(conn_rootdir);
1223 if (strncmp(conn_rootdir, resolved_name,
1224 rootdir_len) != 0) {
1225 DEBUG(2, ("check_reduced_name: Bad access "
1226 "attempt: %s is a symlink outside the "
1227 "share path\n", fname));
1228 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1229 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1230 SAFE_FREE(resolved_name);
1231 return NT_STATUS_ACCESS_DENIED;
1234 /* Extra checks if all symlinks are disallowed. */
1235 if (!allow_symlinks) {
1236 /* fname can't have changed in resolved_path. */
1237 const char *p = &resolved_name[rootdir_len];
1239 /* *p can be '\0' if fname was "." */
1240 if (*p == '\0' && ISDOT(fname)) {
1241 goto out;
1244 if (*p != '/') {
1245 DEBUG(2, ("check_reduced_name: logic error (%c) "
1246 "in resolved_name: %s\n",
1248 fname));
1249 SAFE_FREE(resolved_name);
1250 return NT_STATUS_ACCESS_DENIED;
1253 p++;
1254 if (strcmp(fname, p)!=0) {
1255 DEBUG(2, ("check_reduced_name: Bad access "
1256 "attempt: %s is a symlink to %s\n",
1257 fname, p));
1258 SAFE_FREE(resolved_name);
1259 return NT_STATUS_ACCESS_DENIED;
1264 out:
1266 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1267 resolved_name));
1268 SAFE_FREE(resolved_name);
1269 return NT_STATUS_OK;
1273 * XXX: This is temporary and there should be no callers of this once
1274 * smb_filename is plumbed through all path based operations.
1276 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1277 SMB_STRUCT_STAT *psbuf)
1279 struct smb_filename *smb_fname;
1280 int ret;
1282 smb_fname = synthetic_smb_fname_split(talloc_tos(), fname, NULL);
1283 if (smb_fname == NULL) {
1284 errno = ENOMEM;
1285 return -1;
1288 if (lp_posix_pathnames()) {
1289 ret = SMB_VFS_LSTAT(conn, smb_fname);
1290 } else {
1291 ret = SMB_VFS_STAT(conn, smb_fname);
1294 if (ret != -1) {
1295 *psbuf = smb_fname->st;
1298 TALLOC_FREE(smb_fname);
1299 return ret;
1303 * XXX: This is temporary and there should be no callers of this once
1304 * smb_filename is plumbed through all path based operations.
1306 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1307 SMB_STRUCT_STAT *psbuf)
1309 struct smb_filename *smb_fname;
1310 int ret;
1312 smb_fname = synthetic_smb_fname_split(talloc_tos(), fname, NULL);
1313 if (smb_fname == NULL) {
1314 errno = ENOMEM;
1315 return -1;
1318 ret = SMB_VFS_LSTAT(conn, smb_fname);
1319 if (ret != -1) {
1320 *psbuf = smb_fname->st;
1323 TALLOC_FREE(smb_fname);
1324 return ret;
1328 * Ensure LSTAT is called for POSIX paths.
1331 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1333 int ret;
1335 if(fsp->fh->fd == -1) {
1336 if (fsp->posix_open) {
1337 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1338 } else {
1339 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1341 if (ret == -1) {
1342 return map_nt_error_from_unix(errno);
1344 } else {
1345 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1346 return map_nt_error_from_unix(errno);
1349 return NT_STATUS_OK;
1353 * Initialize num_streams and streams, then call VFS op streaminfo
1355 NTSTATUS vfs_streaminfo(connection_struct *conn,
1356 struct files_struct *fsp,
1357 const char *fname,
1358 TALLOC_CTX *mem_ctx,
1359 unsigned int *num_streams,
1360 struct stream_struct **streams)
1362 *num_streams = 0;
1363 *streams = NULL;
1364 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1368 generate a file_id from a stat structure
1370 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1372 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1375 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1376 const char *service, const char *user)
1378 VFS_FIND(connect);
1379 return handle->fns->connect_fn(handle, service, user);
1382 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1384 VFS_FIND(disconnect);
1385 handle->fns->disconnect_fn(handle);
1388 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1389 const char *path, bool small_query,
1390 uint64_t *bsize, uint64_t *dfree,
1391 uint64_t *dsize)
1393 VFS_FIND(disk_free);
1394 return handle->fns->disk_free_fn(handle, path, small_query, bsize,
1395 dfree, dsize);
1398 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1399 enum SMB_QUOTA_TYPE qtype, unid_t id,
1400 SMB_DISK_QUOTA *qt)
1402 VFS_FIND(get_quota);
1403 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1406 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1407 enum SMB_QUOTA_TYPE qtype, unid_t id,
1408 SMB_DISK_QUOTA *qt)
1410 VFS_FIND(set_quota);
1411 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1414 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1415 struct files_struct *fsp,
1416 struct shadow_copy_data *shadow_copy_data,
1417 bool labels)
1419 VFS_FIND(get_shadow_copy_data);
1420 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1421 shadow_copy_data,
1422 labels);
1424 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1425 struct vfs_statvfs_struct *statbuf)
1427 VFS_FIND(statvfs);
1428 return handle->fns->statvfs_fn(handle, path, statbuf);
1431 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1432 enum timestamp_set_resolution *p_ts_res)
1434 VFS_FIND(fs_capabilities);
1435 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1438 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1439 struct dfs_GetDFSReferral *r)
1441 VFS_FIND(get_dfs_referrals);
1442 return handle->fns->get_dfs_referrals_fn(handle, r);
1445 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1446 const char *fname, const char *mask,
1447 uint32 attributes)
1449 VFS_FIND(opendir);
1450 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1453 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1454 struct files_struct *fsp,
1455 const char *mask,
1456 uint32 attributes)
1458 VFS_FIND(fdopendir);
1459 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1462 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1463 DIR *dirp,
1464 SMB_STRUCT_STAT *sbuf)
1466 VFS_FIND(readdir);
1467 return handle->fns->readdir_fn(handle, dirp, sbuf);
1470 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1471 DIR *dirp, long offset)
1473 VFS_FIND(seekdir);
1474 handle->fns->seekdir_fn(handle, dirp, offset);
1477 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1478 DIR *dirp)
1480 VFS_FIND(telldir);
1481 return handle->fns->telldir_fn(handle, dirp);
1484 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1485 DIR *dirp)
1487 VFS_FIND(rewind_dir);
1488 handle->fns->rewind_dir_fn(handle, dirp);
1491 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1492 mode_t mode)
1494 VFS_FIND(mkdir);
1495 return handle->fns->mkdir_fn(handle, path, mode);
1498 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1500 VFS_FIND(rmdir);
1501 return handle->fns->rmdir_fn(handle, path);
1504 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1505 DIR *dir)
1507 VFS_FIND(closedir);
1508 return handle->fns->closedir_fn(handle, dir);
1511 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1512 DIR *dirp)
1514 VFS_FIND(init_search_op);
1515 handle->fns->init_search_op_fn(handle, dirp);
1518 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1519 struct smb_filename *smb_fname, struct files_struct *fsp,
1520 int flags, mode_t mode)
1522 VFS_FIND(open);
1523 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1526 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1527 struct smb_request *req,
1528 uint16_t root_dir_fid,
1529 struct smb_filename *smb_fname,
1530 uint32_t access_mask,
1531 uint32_t share_access,
1532 uint32_t create_disposition,
1533 uint32_t create_options,
1534 uint32_t file_attributes,
1535 uint32_t oplock_request,
1536 uint64_t allocation_size,
1537 uint32_t private_flags,
1538 struct security_descriptor *sd,
1539 struct ea_list *ea_list,
1540 files_struct **result,
1541 int *pinfo)
1543 VFS_FIND(create_file);
1544 return handle->fns->create_file_fn(
1545 handle, req, root_dir_fid, smb_fname, access_mask,
1546 share_access, create_disposition, create_options,
1547 file_attributes, oplock_request, allocation_size,
1548 private_flags, sd, ea_list,
1549 result, pinfo);
1552 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1553 struct files_struct *fsp)
1555 VFS_FIND(close);
1556 return handle->fns->close_fn(handle, fsp);
1559 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1560 struct files_struct *fsp, void *data, size_t n)
1562 VFS_FIND(read);
1563 return handle->fns->read_fn(handle, fsp, data, n);
1566 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1567 struct files_struct *fsp, void *data, size_t n,
1568 off_t offset)
1570 VFS_FIND(pread);
1571 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1574 struct smb_vfs_call_pread_state {
1575 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1576 ssize_t retval;
1579 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1581 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1582 TALLOC_CTX *mem_ctx,
1583 struct tevent_context *ev,
1584 struct files_struct *fsp,
1585 void *data,
1586 size_t n, off_t offset)
1588 struct tevent_req *req, *subreq;
1589 struct smb_vfs_call_pread_state *state;
1591 req = tevent_req_create(mem_ctx, &state,
1592 struct smb_vfs_call_pread_state);
1593 if (req == NULL) {
1594 return NULL;
1596 VFS_FIND(pread_send);
1597 state->recv_fn = handle->fns->pread_recv_fn;
1599 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1600 offset);
1601 if (tevent_req_nomem(subreq, req)) {
1602 return tevent_req_post(req, ev);
1604 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1605 return req;
1608 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1610 struct tevent_req *req = tevent_req_callback_data(
1611 subreq, struct tevent_req);
1612 struct smb_vfs_call_pread_state *state = tevent_req_data(
1613 req, struct smb_vfs_call_pread_state);
1614 int err;
1616 state->retval = state->recv_fn(subreq, &err);
1617 TALLOC_FREE(subreq);
1618 if (state->retval == -1) {
1619 tevent_req_error(req, err);
1620 return;
1622 tevent_req_done(req);
1625 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req, int *perrno)
1627 struct smb_vfs_call_pread_state *state = tevent_req_data(
1628 req, struct smb_vfs_call_pread_state);
1629 int err;
1631 if (tevent_req_is_unix_error(req, &err)) {
1632 *perrno = err;
1633 return -1;
1635 return state->retval;
1638 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1639 struct files_struct *fsp, const void *data,
1640 size_t n)
1642 VFS_FIND(write);
1643 return handle->fns->write_fn(handle, fsp, data, n);
1646 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1647 struct files_struct *fsp, const void *data,
1648 size_t n, off_t offset)
1650 VFS_FIND(pwrite);
1651 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1654 struct smb_vfs_call_pwrite_state {
1655 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1656 ssize_t retval;
1659 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1661 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1662 TALLOC_CTX *mem_ctx,
1663 struct tevent_context *ev,
1664 struct files_struct *fsp,
1665 const void *data,
1666 size_t n, off_t offset)
1668 struct tevent_req *req, *subreq;
1669 struct smb_vfs_call_pwrite_state *state;
1671 req = tevent_req_create(mem_ctx, &state,
1672 struct smb_vfs_call_pwrite_state);
1673 if (req == NULL) {
1674 return NULL;
1676 VFS_FIND(pwrite_send);
1677 state->recv_fn = handle->fns->pwrite_recv_fn;
1679 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1680 offset);
1681 if (tevent_req_nomem(subreq, req)) {
1682 return tevent_req_post(req, ev);
1684 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1685 return req;
1688 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1690 struct tevent_req *req = tevent_req_callback_data(
1691 subreq, struct tevent_req);
1692 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1693 req, struct smb_vfs_call_pwrite_state);
1694 int err;
1696 state->retval = state->recv_fn(subreq, &err);
1697 TALLOC_FREE(subreq);
1698 if (state->retval == -1) {
1699 tevent_req_error(req, err);
1700 return;
1702 tevent_req_done(req);
1705 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req, int *perrno)
1707 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1708 req, struct smb_vfs_call_pwrite_state);
1709 int err;
1711 if (tevent_req_is_unix_error(req, &err)) {
1712 *perrno = err;
1713 return -1;
1715 return state->retval;
1718 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1719 struct files_struct *fsp, off_t offset,
1720 int whence)
1722 VFS_FIND(lseek);
1723 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1726 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1727 files_struct *fromfsp, const DATA_BLOB *header,
1728 off_t offset, size_t count)
1730 VFS_FIND(sendfile);
1731 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1732 count);
1735 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1736 files_struct *tofsp, off_t offset,
1737 size_t count)
1739 VFS_FIND(recvfile);
1740 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1743 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1744 const struct smb_filename *smb_fname_src,
1745 const struct smb_filename *smb_fname_dst)
1747 VFS_FIND(rename);
1748 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1751 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1752 struct files_struct *fsp)
1754 VFS_FIND(fsync);
1755 return handle->fns->fsync_fn(handle, fsp);
1758 struct smb_vfs_call_fsync_state {
1759 int (*recv_fn)(struct tevent_req *req, int *err);
1760 int retval;
1763 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1765 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1766 TALLOC_CTX *mem_ctx,
1767 struct tevent_context *ev,
1768 struct files_struct *fsp)
1770 struct tevent_req *req, *subreq;
1771 struct smb_vfs_call_fsync_state *state;
1773 req = tevent_req_create(mem_ctx, &state,
1774 struct smb_vfs_call_fsync_state);
1775 if (req == NULL) {
1776 return NULL;
1778 VFS_FIND(fsync_send);
1779 state->recv_fn = handle->fns->fsync_recv_fn;
1781 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1782 if (tevent_req_nomem(subreq, req)) {
1783 return tevent_req_post(req, ev);
1785 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1786 return req;
1789 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1791 struct tevent_req *req = tevent_req_callback_data(
1792 subreq, struct tevent_req);
1793 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1794 req, struct smb_vfs_call_fsync_state);
1795 int err;
1797 state->retval = state->recv_fn(subreq, &err);
1798 TALLOC_FREE(subreq);
1799 if (state->retval == -1) {
1800 tevent_req_error(req, err);
1801 return;
1803 tevent_req_done(req);
1806 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, int *perrno)
1808 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1809 req, struct smb_vfs_call_fsync_state);
1810 int err;
1812 if (tevent_req_is_unix_error(req, &err)) {
1813 *perrno = err;
1814 return -1;
1816 return state->retval;
1820 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1821 struct smb_filename *smb_fname)
1823 VFS_FIND(stat);
1824 return handle->fns->stat_fn(handle, smb_fname);
1827 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1828 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1830 VFS_FIND(fstat);
1831 return handle->fns->fstat_fn(handle, fsp, sbuf);
1834 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1835 struct smb_filename *smb_filename)
1837 VFS_FIND(lstat);
1838 return handle->fns->lstat_fn(handle, smb_filename);
1841 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1842 struct files_struct *fsp,
1843 const SMB_STRUCT_STAT *sbuf)
1845 VFS_FIND(get_alloc_size);
1846 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1849 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1850 const struct smb_filename *smb_fname)
1852 VFS_FIND(unlink);
1853 return handle->fns->unlink_fn(handle, smb_fname);
1856 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1857 mode_t mode)
1859 VFS_FIND(chmod);
1860 return handle->fns->chmod_fn(handle, path, mode);
1863 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1864 struct files_struct *fsp, mode_t mode)
1866 VFS_FIND(fchmod);
1867 return handle->fns->fchmod_fn(handle, fsp, mode);
1870 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1871 uid_t uid, gid_t gid)
1873 VFS_FIND(chown);
1874 return handle->fns->chown_fn(handle, path, uid, gid);
1877 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1878 struct files_struct *fsp, uid_t uid, gid_t gid)
1880 VFS_FIND(fchown);
1881 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1884 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1885 uid_t uid, gid_t gid)
1887 VFS_FIND(lchown);
1888 return handle->fns->lchown_fn(handle, path, uid, gid);
1891 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1893 int ret;
1894 bool as_root = false;
1895 const char *path;
1896 char *saved_dir = NULL;
1897 char *parent_dir = NULL;
1898 NTSTATUS status;
1900 if (fsp->fh->fd != -1) {
1901 /* Try fchown. */
1902 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1903 if (ret == 0) {
1904 return NT_STATUS_OK;
1906 if (ret == -1 && errno != ENOSYS) {
1907 return map_nt_error_from_unix(errno);
1911 as_root = (geteuid() == 0);
1913 if (as_root) {
1915 * We are being asked to chown as root. Make
1916 * sure we chdir() into the path to pin it,
1917 * and always act using lchown to ensure we
1918 * don't deref any symbolic links.
1920 const char *final_component = NULL;
1921 struct smb_filename local_fname;
1923 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1924 if (!saved_dir) {
1925 status = map_nt_error_from_unix(errno);
1926 DEBUG(0,("vfs_chown_fsp: failed to get "
1927 "current working directory. Error was %s\n",
1928 strerror(errno)));
1929 return status;
1932 if (!parent_dirname(talloc_tos(),
1933 fsp->fsp_name->base_name,
1934 &parent_dir,
1935 &final_component)) {
1936 return NT_STATUS_NO_MEMORY;
1939 /* cd into the parent dir to pin it. */
1940 ret = vfs_ChDir(fsp->conn, parent_dir);
1941 if (ret == -1) {
1942 return map_nt_error_from_unix(errno);
1945 ZERO_STRUCT(local_fname);
1946 local_fname.base_name = discard_const_p(char, final_component);
1948 /* Must use lstat here. */
1949 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1950 if (ret == -1) {
1951 status = map_nt_error_from_unix(errno);
1952 goto out;
1955 /* Ensure it matches the fsp stat. */
1956 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1957 status = NT_STATUS_ACCESS_DENIED;
1958 goto out;
1960 path = final_component;
1961 } else {
1962 path = fsp->fsp_name->base_name;
1965 if (fsp->posix_open || as_root) {
1966 ret = SMB_VFS_LCHOWN(fsp->conn,
1967 path,
1968 uid, gid);
1969 } else {
1970 ret = SMB_VFS_CHOWN(fsp->conn,
1971 path,
1972 uid, gid);
1975 if (ret == 0) {
1976 status = NT_STATUS_OK;
1977 } else {
1978 status = map_nt_error_from_unix(errno);
1981 out:
1983 if (as_root) {
1984 vfs_ChDir(fsp->conn,saved_dir);
1985 TALLOC_FREE(saved_dir);
1986 TALLOC_FREE(parent_dir);
1988 return status;
1991 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1993 VFS_FIND(chdir);
1994 return handle->fns->chdir_fn(handle, path);
1997 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
1999 VFS_FIND(getwd);
2000 return handle->fns->getwd_fn(handle);
2003 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
2004 const struct smb_filename *smb_fname,
2005 struct smb_file_time *ft)
2007 VFS_FIND(ntimes);
2008 return handle->fns->ntimes_fn(handle, smb_fname, ft);
2011 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2012 struct files_struct *fsp, off_t offset)
2014 VFS_FIND(ftruncate);
2015 return handle->fns->ftruncate_fn(handle, fsp, offset);
2018 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2019 struct files_struct *fsp,
2020 enum vfs_fallocate_mode mode,
2021 off_t offset,
2022 off_t len)
2024 VFS_FIND(fallocate);
2025 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2028 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2029 struct files_struct *fsp, uint32 share_mode,
2030 uint32_t access_mask)
2032 VFS_FIND(kernel_flock);
2033 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2034 access_mask);
2037 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2038 struct files_struct *fsp, int leasetype)
2040 VFS_FIND(linux_setlease);
2041 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2044 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
2045 const char *newpath)
2047 VFS_FIND(symlink);
2048 return handle->fns->symlink_fn(handle, oldpath, newpath);
2051 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2052 const char *path, char *buf, size_t bufsiz)
2054 VFS_FIND(readlink);
2055 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
2058 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
2059 const char *newpath)
2061 VFS_FIND(link);
2062 return handle->fns->link_fn(handle, oldpath, newpath);
2065 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
2066 mode_t mode, SMB_DEV_T dev)
2068 VFS_FIND(mknod);
2069 return handle->fns->mknod_fn(handle, path, mode, dev);
2072 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
2074 VFS_FIND(realpath);
2075 return handle->fns->realpath_fn(handle, path);
2078 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
2079 struct sys_notify_context *ctx,
2080 const char *path,
2081 uint32_t *filter,
2082 uint32_t *subdir_filter,
2083 void (*callback)(struct sys_notify_context *ctx,
2084 void *private_data,
2085 struct notify_event *ev),
2086 void *private_data, void *handle_p)
2088 VFS_FIND(notify_watch);
2089 return handle->fns->notify_watch_fn(handle, ctx, path,
2090 filter, subdir_filter, callback,
2091 private_data, handle_p);
2094 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
2095 unsigned int flags)
2097 VFS_FIND(chflags);
2098 return handle->fns->chflags_fn(handle, path, flags);
2101 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2102 const SMB_STRUCT_STAT *sbuf)
2104 VFS_FIND(file_id_create);
2105 return handle->fns->file_id_create_fn(handle, sbuf);
2108 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2109 struct files_struct *fsp,
2110 const char *fname,
2111 TALLOC_CTX *mem_ctx,
2112 unsigned int *num_streams,
2113 struct stream_struct **streams)
2115 VFS_FIND(streaminfo);
2116 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
2117 num_streams, streams);
2120 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2121 const char *path, const char *name,
2122 TALLOC_CTX *mem_ctx, char **found_name)
2124 VFS_FIND(get_real_filename);
2125 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2126 found_name);
2129 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2130 const char *filename)
2132 VFS_FIND(connectpath);
2133 return handle->fns->connectpath_fn(handle, filename);
2136 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2137 struct files_struct *fsp,
2138 struct lock_struct *plock)
2140 VFS_FIND(strict_lock);
2141 return handle->fns->strict_lock_fn(handle, fsp, plock);
2144 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2145 struct files_struct *fsp,
2146 struct lock_struct *plock)
2148 VFS_FIND(strict_unlock);
2149 handle->fns->strict_unlock_fn(handle, fsp, plock);
2152 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2153 const char *name,
2154 enum vfs_translate_direction direction,
2155 TALLOC_CTX *mem_ctx,
2156 char **mapped_name)
2158 VFS_FIND(translate_name);
2159 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2160 mapped_name);
2163 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2164 struct files_struct *fsp,
2165 TALLOC_CTX *ctx,
2166 uint32_t function,
2167 uint16_t req_flags,
2168 const uint8_t *in_data,
2169 uint32_t in_len,
2170 uint8_t **out_data,
2171 uint32_t max_out_len,
2172 uint32_t *out_len)
2174 VFS_FIND(fsctl);
2175 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2176 in_data, in_len, out_data, max_out_len,
2177 out_len);
2180 struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle,
2181 TALLOC_CTX *mem_ctx,
2182 struct tevent_context *ev,
2183 struct files_struct *src_fsp,
2184 off_t src_off,
2185 struct files_struct *dest_fsp,
2186 off_t dest_off,
2187 off_t num)
2189 VFS_FIND(copy_chunk_send);
2190 return handle->fns->copy_chunk_send_fn(handle, mem_ctx, ev, src_fsp,
2191 src_off, dest_fsp, dest_off, num);
2194 NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,
2195 struct tevent_req *req,
2196 off_t *copied)
2198 VFS_FIND(copy_chunk_recv);
2199 return handle->fns->copy_chunk_recv_fn(handle, req, copied);
2202 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2203 struct files_struct *fsp,
2204 uint32 security_info,
2205 TALLOC_CTX *mem_ctx,
2206 struct security_descriptor **ppdesc)
2208 VFS_FIND(fget_nt_acl);
2209 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2210 mem_ctx, ppdesc);
2213 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2214 const char *name,
2215 uint32 security_info,
2216 TALLOC_CTX *mem_ctx,
2217 struct security_descriptor **ppdesc)
2219 VFS_FIND(get_nt_acl);
2220 return handle->fns->get_nt_acl_fn(handle, name, security_info, mem_ctx, ppdesc);
2223 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2224 struct files_struct *fsp,
2225 uint32 security_info_sent,
2226 const struct security_descriptor *psd)
2228 VFS_FIND(fset_nt_acl);
2229 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2230 psd);
2233 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2234 struct smb_filename *file,
2235 struct security_acl *sacl,
2236 uint32_t access_requested,
2237 uint32_t access_denied)
2239 VFS_FIND(audit_file);
2240 return handle->fns->audit_file_fn(handle,
2241 file,
2242 sacl,
2243 access_requested,
2244 access_denied);
2247 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2248 mode_t mode)
2250 VFS_FIND(chmod_acl);
2251 return handle->fns->chmod_acl_fn(handle, name, mode);
2254 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2255 struct files_struct *fsp, mode_t mode)
2257 VFS_FIND(fchmod_acl);
2258 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2261 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2262 const char *path_p,
2263 SMB_ACL_TYPE_T type,
2264 TALLOC_CTX *mem_ctx)
2266 VFS_FIND(sys_acl_get_file);
2267 return handle->fns->sys_acl_get_file_fn(handle, path_p, type, mem_ctx);
2270 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2271 struct files_struct *fsp,
2272 TALLOC_CTX *mem_ctx)
2274 VFS_FIND(sys_acl_get_fd);
2275 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2278 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2279 const char *path_p,
2280 TALLOC_CTX *mem_ctx,
2281 char **blob_description,
2282 DATA_BLOB *blob)
2284 VFS_FIND(sys_acl_blob_get_file);
2285 return handle->fns->sys_acl_blob_get_file_fn(handle, path_p, mem_ctx, blob_description, blob);
2288 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2289 struct files_struct *fsp,
2290 TALLOC_CTX *mem_ctx,
2291 char **blob_description,
2292 DATA_BLOB *blob)
2294 VFS_FIND(sys_acl_blob_get_fd);
2295 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2298 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2299 const char *name, SMB_ACL_TYPE_T acltype,
2300 SMB_ACL_T theacl)
2302 VFS_FIND(sys_acl_set_file);
2303 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2306 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2307 struct files_struct *fsp, SMB_ACL_T theacl)
2309 VFS_FIND(sys_acl_set_fd);
2310 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2313 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2314 const char *path)
2316 VFS_FIND(sys_acl_delete_def_file);
2317 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2320 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2321 const char *path, const char *name, void *value,
2322 size_t size)
2324 VFS_FIND(getxattr);
2325 return handle->fns->getxattr_fn(handle, path, name, value, size);
2328 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2329 struct files_struct *fsp, const char *name,
2330 void *value, size_t size)
2332 VFS_FIND(fgetxattr);
2333 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2336 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2337 const char *path, char *list, size_t size)
2339 VFS_FIND(listxattr);
2340 return handle->fns->listxattr_fn(handle, path, list, size);
2343 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2344 struct files_struct *fsp, char *list,
2345 size_t size)
2347 VFS_FIND(flistxattr);
2348 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2351 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2352 const char *path, const char *name)
2354 VFS_FIND(removexattr);
2355 return handle->fns->removexattr_fn(handle, path, name);
2358 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2359 struct files_struct *fsp, const char *name)
2361 VFS_FIND(fremovexattr);
2362 return handle->fns->fremovexattr_fn(handle, fsp, name);
2365 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2366 const char *name, const void *value, size_t size,
2367 int flags)
2369 VFS_FIND(setxattr);
2370 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2373 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2374 struct files_struct *fsp, const char *name,
2375 const void *value, size_t size, int flags)
2377 VFS_FIND(fsetxattr);
2378 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2381 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2382 struct files_struct *fsp)
2384 VFS_FIND(aio_force);
2385 return handle->fns->aio_force_fn(handle, fsp);
2388 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2389 const struct smb_filename *fname,
2390 SMB_STRUCT_STAT *sbuf)
2392 VFS_FIND(is_offline);
2393 return handle->fns->is_offline_fn(handle, fname, sbuf);
2396 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2397 const struct smb_filename *fname)
2399 VFS_FIND(set_offline);
2400 return handle->fns->set_offline_fn(handle, fname);
2403 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2404 struct files_struct *fsp,
2405 TALLOC_CTX *mem_ctx,
2406 DATA_BLOB *cookie)
2408 VFS_FIND(durable_cookie);
2409 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2412 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2413 struct files_struct *fsp,
2414 const DATA_BLOB old_cookie,
2415 TALLOC_CTX *mem_ctx,
2416 DATA_BLOB *new_cookie)
2418 VFS_FIND(durable_disconnect);
2419 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2420 mem_ctx, new_cookie);
2423 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2424 struct smb_request *smb1req,
2425 struct smbXsrv_open *op,
2426 const DATA_BLOB old_cookie,
2427 TALLOC_CTX *mem_ctx,
2428 struct files_struct **fsp,
2429 DATA_BLOB *new_cookie)
2431 VFS_FIND(durable_reconnect);
2432 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2433 old_cookie, mem_ctx, fsp,
2434 new_cookie);