s3:smbd: pass the final numtoread reply_outbuf() for the lockread reply.
[Samba.git] / source3 / smbd / vfs.c
blob124981c9941fc9ea422bed04bd4881d5fbc85617
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;
868 NTSTATUS status;
870 if (!lp_getwd_cache()) {
871 goto nocache;
874 status = create_synthetic_smb_fname(ctx, ".", NULL, NULL,
875 &smb_fname_dot);
876 if (!NT_STATUS_IS_OK(status)) {
877 errno = map_errno_from_nt_status(status);
878 goto out;
881 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
883 * Known to fail for root: the directory may be NFS-mounted
884 * and exported with root_squash (so has no root access).
886 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
887 "(NFS problem ?)\n", strerror(errno) ));
888 goto nocache;
891 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
893 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
894 data_blob_const(&key, sizeof(key)),
895 &cache_value)) {
896 goto nocache;
899 SMB_ASSERT((cache_value.length > 0)
900 && (cache_value.data[cache_value.length-1] == '\0'));
902 status = create_synthetic_smb_fname(ctx, (char *)cache_value.data,
903 NULL, NULL, &smb_fname_full);
904 if (!NT_STATUS_IS_OK(status)) {
905 errno = map_errno_from_nt_status(status);
906 goto out;
909 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
910 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
911 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
912 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
914 * Ok, we're done
916 result = talloc_strdup(ctx, smb_fname_full->base_name);
917 if (result == NULL) {
918 errno = ENOMEM;
920 goto out;
923 nocache:
926 * We don't have the information to hand so rely on traditional
927 * methods. The very slow getcwd, which spawns a process on some
928 * systems, or the not quite so bad getwd.
931 current_dir = SMB_VFS_GETWD(conn);
932 if (current_dir == NULL) {
933 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
934 strerror(errno)));
935 goto out;
938 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
939 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
941 memcache_add(smbd_memcache(), GETWD_CACHE,
942 data_blob_const(&key, sizeof(key)),
943 data_blob_const(current_dir,
944 strlen(current_dir)+1));
947 result = talloc_strdup(ctx, current_dir);
948 if (result == NULL) {
949 errno = ENOMEM;
952 out:
953 TALLOC_FREE(smb_fname_dot);
954 TALLOC_FREE(smb_fname_full);
955 SAFE_FREE(current_dir);
956 return result;
959 /*******************************************************************
960 Reduce a file name, removing .. elements and checking that
961 it is below dir in the heirachy. This uses realpath.
962 This function must run as root, and will return names
963 and valid stat structs that can be checked on open.
964 ********************************************************************/
966 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
967 const char *fname,
968 struct smb_request *smbreq)
970 NTSTATUS status;
971 TALLOC_CTX *ctx = talloc_tos();
972 const char *conn_rootdir;
973 size_t rootdir_len;
974 char *dir_name = NULL;
975 const char *last_component = NULL;
976 char *resolved_name = NULL;
977 char *saved_dir = NULL;
978 struct smb_filename *smb_fname_cwd = NULL;
979 struct privilege_paths *priv_paths = NULL;
980 int ret;
982 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
983 fname,
984 conn->connectpath));
987 priv_paths = talloc_zero(smbreq, struct privilege_paths);
988 if (!priv_paths) {
989 status = NT_STATUS_NO_MEMORY;
990 goto err;
993 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
994 status = NT_STATUS_NO_MEMORY;
995 goto err;
998 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
999 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
1001 if (priv_paths->parent_name.base_name == NULL ||
1002 priv_paths->file_name.base_name == NULL) {
1003 status = NT_STATUS_NO_MEMORY;
1004 goto err;
1007 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
1008 status = map_nt_error_from_unix(errno);
1009 goto err;
1011 /* Remember where we were. */
1012 saved_dir = vfs_GetWd(ctx, conn);
1013 if (!saved_dir) {
1014 status = map_nt_error_from_unix(errno);
1015 goto err;
1018 /* Go to the parent directory to lock in memory. */
1019 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
1020 status = map_nt_error_from_unix(errno);
1021 goto err;
1024 /* Get the absolute path of the parent directory. */
1025 resolved_name = SMB_VFS_REALPATH(conn,".");
1026 if (!resolved_name) {
1027 status = map_nt_error_from_unix(errno);
1028 goto err;
1031 if (*resolved_name != '/') {
1032 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1033 "doesn't return absolute paths !\n"));
1034 status = NT_STATUS_OBJECT_NAME_INVALID;
1035 goto err;
1038 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1039 priv_paths->parent_name.base_name,
1040 resolved_name));
1042 /* Now check the stat value is the same. */
1043 status = create_synthetic_smb_fname(talloc_tos(), ".",
1044 NULL, NULL,
1045 &smb_fname_cwd);
1046 if (!NT_STATUS_IS_OK(status)) {
1047 goto err;
1050 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1051 status = map_nt_error_from_unix(errno);
1052 goto err;
1055 /* Ensure we're pointing at the same place. */
1056 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1057 DEBUG(0,("check_reduced_name_with_privilege: "
1058 "device/inode/uid/gid on directory %s changed. "
1059 "Denying access !\n",
1060 priv_paths->parent_name.base_name));
1061 status = NT_STATUS_ACCESS_DENIED;
1062 goto err;
1065 /* Ensure we're below the connect path. */
1067 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1068 if (conn_rootdir == NULL) {
1069 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1070 "conn_rootdir\n"));
1071 status = NT_STATUS_ACCESS_DENIED;
1072 goto err;
1075 rootdir_len = strlen(conn_rootdir);
1076 if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1077 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1078 "attempt: %s is a symlink outside the "
1079 "share path\n",
1080 dir_name));
1081 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1082 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1083 status = NT_STATUS_ACCESS_DENIED;
1084 goto err;
1087 /* Now ensure that the last component either doesn't
1088 exist, or is *NOT* a symlink. */
1090 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1091 if (ret == -1) {
1092 /* Errno must be ENOENT for this be ok. */
1093 if (errno != ENOENT) {
1094 status = map_nt_error_from_unix(errno);
1095 DEBUG(2, ("check_reduced_name_with_privilege: "
1096 "LSTAT on %s failed with %s\n",
1097 priv_paths->file_name.base_name,
1098 nt_errstr(status)));
1099 goto err;
1103 if (VALID_STAT(priv_paths->file_name.st) &&
1104 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1105 DEBUG(2, ("check_reduced_name_with_privilege: "
1106 "Last component %s is a symlink. Denying"
1107 "access.\n",
1108 priv_paths->file_name.base_name));
1109 status = NT_STATUS_ACCESS_DENIED;
1110 goto err;
1113 smbreq->priv_paths = priv_paths;
1114 status = NT_STATUS_OK;
1116 err:
1118 if (saved_dir) {
1119 vfs_ChDir(conn, saved_dir);
1121 SAFE_FREE(resolved_name);
1122 if (!NT_STATUS_IS_OK(status)) {
1123 TALLOC_FREE(priv_paths);
1125 TALLOC_FREE(dir_name);
1126 return status;
1129 /*******************************************************************
1130 Reduce a file name, removing .. elements and checking that
1131 it is below dir in the heirachy. This uses realpath.
1132 ********************************************************************/
1134 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1136 char *resolved_name = NULL;
1137 bool allow_symlinks = true;
1138 bool allow_widelinks = false;
1140 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1142 resolved_name = SMB_VFS_REALPATH(conn,fname);
1144 if (!resolved_name) {
1145 switch (errno) {
1146 case ENOTDIR:
1147 DEBUG(3,("check_reduced_name: Component not a "
1148 "directory in getting realpath for "
1149 "%s\n", fname));
1150 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1151 case ENOENT:
1153 TALLOC_CTX *ctx = talloc_tos();
1154 char *dir_name = NULL;
1155 const char *last_component = NULL;
1156 char *new_name = NULL;
1157 int ret;
1159 /* Last component didn't exist.
1160 Remove it and try and canonicalise
1161 the directory name. */
1162 if (!parent_dirname(ctx, fname,
1163 &dir_name,
1164 &last_component)) {
1165 return NT_STATUS_NO_MEMORY;
1168 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1169 if (!resolved_name) {
1170 NTSTATUS status = map_nt_error_from_unix(errno);
1172 if (errno == ENOENT || errno == ENOTDIR) {
1173 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1176 DEBUG(3,("check_reduce_name: "
1177 "couldn't get realpath for "
1178 "%s (%s)\n",
1179 fname,
1180 nt_errstr(status)));
1181 return status;
1183 ret = asprintf(&new_name, "%s/%s",
1184 resolved_name, last_component);
1185 SAFE_FREE(resolved_name);
1186 if (ret == -1) {
1187 return NT_STATUS_NO_MEMORY;
1189 resolved_name = new_name;
1190 break;
1192 default:
1193 DEBUG(3,("check_reduced_name: couldn't get "
1194 "realpath for %s\n", fname));
1195 return map_nt_error_from_unix(errno);
1199 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1200 resolved_name));
1202 if (*resolved_name != '/') {
1203 DEBUG(0,("check_reduced_name: realpath doesn't return "
1204 "absolute paths !\n"));
1205 SAFE_FREE(resolved_name);
1206 return NT_STATUS_OBJECT_NAME_INVALID;
1209 allow_widelinks = lp_widelinks(SNUM(conn));
1210 allow_symlinks = lp_symlinks(SNUM(conn));
1212 /* Common widelinks and symlinks checks. */
1213 if (!allow_widelinks || !allow_symlinks) {
1214 const char *conn_rootdir;
1215 size_t rootdir_len;
1217 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1218 if (conn_rootdir == NULL) {
1219 DEBUG(2, ("check_reduced_name: Could not get "
1220 "conn_rootdir\n"));
1221 SAFE_FREE(resolved_name);
1222 return NT_STATUS_ACCESS_DENIED;
1225 rootdir_len = strlen(conn_rootdir);
1226 if (strncmp(conn_rootdir, resolved_name,
1227 rootdir_len) != 0) {
1228 DEBUG(2, ("check_reduced_name: Bad access "
1229 "attempt: %s is a symlink outside the "
1230 "share path\n", fname));
1231 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1232 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1233 SAFE_FREE(resolved_name);
1234 return NT_STATUS_ACCESS_DENIED;
1237 /* Extra checks if all symlinks are disallowed. */
1238 if (!allow_symlinks) {
1239 /* fname can't have changed in resolved_path. */
1240 const char *p = &resolved_name[rootdir_len];
1242 /* *p can be '\0' if fname was "." */
1243 if (*p == '\0' && ISDOT(fname)) {
1244 goto out;
1247 if (*p != '/') {
1248 DEBUG(2, ("check_reduced_name: logic error (%c) "
1249 "in resolved_name: %s\n",
1251 fname));
1252 SAFE_FREE(resolved_name);
1253 return NT_STATUS_ACCESS_DENIED;
1256 p++;
1257 if (strcmp(fname, p)!=0) {
1258 DEBUG(2, ("check_reduced_name: Bad access "
1259 "attempt: %s is a symlink to %s\n",
1260 fname, p));
1261 SAFE_FREE(resolved_name);
1262 return NT_STATUS_ACCESS_DENIED;
1267 out:
1269 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1270 resolved_name));
1271 SAFE_FREE(resolved_name);
1272 return NT_STATUS_OK;
1276 * XXX: This is temporary and there should be no callers of this once
1277 * smb_filename is plumbed through all path based operations.
1279 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1280 SMB_STRUCT_STAT *psbuf)
1282 struct smb_filename *smb_fname = NULL;
1283 NTSTATUS status;
1284 int ret;
1286 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1287 &smb_fname);
1288 if (!NT_STATUS_IS_OK(status)) {
1289 errno = map_errno_from_nt_status(status);
1290 return -1;
1293 if (lp_posix_pathnames()) {
1294 ret = SMB_VFS_LSTAT(conn, smb_fname);
1295 } else {
1296 ret = SMB_VFS_STAT(conn, smb_fname);
1299 if (ret != -1) {
1300 *psbuf = smb_fname->st;
1303 TALLOC_FREE(smb_fname);
1304 return ret;
1308 * XXX: This is temporary and there should be no callers of this once
1309 * smb_filename is plumbed through all path based operations.
1311 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1312 SMB_STRUCT_STAT *psbuf)
1314 struct smb_filename *smb_fname = NULL;
1315 NTSTATUS status;
1316 int ret;
1318 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1319 &smb_fname);
1320 if (!NT_STATUS_IS_OK(status)) {
1321 errno = map_errno_from_nt_status(status);
1322 return -1;
1325 ret = SMB_VFS_LSTAT(conn, smb_fname);
1326 if (ret != -1) {
1327 *psbuf = smb_fname->st;
1330 TALLOC_FREE(smb_fname);
1331 return ret;
1335 * Ensure LSTAT is called for POSIX paths.
1338 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1340 int ret;
1342 if(fsp->fh->fd == -1) {
1343 if (fsp->posix_open) {
1344 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1345 } else {
1346 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1348 if (ret == -1) {
1349 return map_nt_error_from_unix(errno);
1351 } else {
1352 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1353 return map_nt_error_from_unix(errno);
1356 return NT_STATUS_OK;
1360 * Initialize num_streams and streams, then call VFS op streaminfo
1362 NTSTATUS vfs_streaminfo(connection_struct *conn,
1363 struct files_struct *fsp,
1364 const char *fname,
1365 TALLOC_CTX *mem_ctx,
1366 unsigned int *num_streams,
1367 struct stream_struct **streams)
1369 *num_streams = 0;
1370 *streams = NULL;
1371 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1375 generate a file_id from a stat structure
1377 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1379 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1382 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1383 const char *service, const char *user)
1385 VFS_FIND(connect);
1386 return handle->fns->connect_fn(handle, service, user);
1389 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1391 VFS_FIND(disconnect);
1392 handle->fns->disconnect_fn(handle);
1395 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1396 const char *path, bool small_query,
1397 uint64_t *bsize, uint64_t *dfree,
1398 uint64_t *dsize)
1400 VFS_FIND(disk_free);
1401 return handle->fns->disk_free_fn(handle, path, small_query, bsize,
1402 dfree, dsize);
1405 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1406 enum SMB_QUOTA_TYPE qtype, unid_t id,
1407 SMB_DISK_QUOTA *qt)
1409 VFS_FIND(get_quota);
1410 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1413 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1414 enum SMB_QUOTA_TYPE qtype, unid_t id,
1415 SMB_DISK_QUOTA *qt)
1417 VFS_FIND(set_quota);
1418 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1421 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1422 struct files_struct *fsp,
1423 struct shadow_copy_data *shadow_copy_data,
1424 bool labels)
1426 VFS_FIND(get_shadow_copy_data);
1427 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1428 shadow_copy_data,
1429 labels);
1431 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1432 struct vfs_statvfs_struct *statbuf)
1434 VFS_FIND(statvfs);
1435 return handle->fns->statvfs_fn(handle, path, statbuf);
1438 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1439 enum timestamp_set_resolution *p_ts_res)
1441 VFS_FIND(fs_capabilities);
1442 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1445 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1446 struct dfs_GetDFSReferral *r)
1448 VFS_FIND(get_dfs_referrals);
1449 return handle->fns->get_dfs_referrals_fn(handle, r);
1452 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1453 const char *fname, const char *mask,
1454 uint32 attributes)
1456 VFS_FIND(opendir);
1457 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1460 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1461 struct files_struct *fsp,
1462 const char *mask,
1463 uint32 attributes)
1465 VFS_FIND(fdopendir);
1466 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1469 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1470 DIR *dirp,
1471 SMB_STRUCT_STAT *sbuf)
1473 VFS_FIND(readdir);
1474 return handle->fns->readdir_fn(handle, dirp, sbuf);
1477 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1478 DIR *dirp, long offset)
1480 VFS_FIND(seekdir);
1481 handle->fns->seekdir_fn(handle, dirp, offset);
1484 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1485 DIR *dirp)
1487 VFS_FIND(telldir);
1488 return handle->fns->telldir_fn(handle, dirp);
1491 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1492 DIR *dirp)
1494 VFS_FIND(rewind_dir);
1495 handle->fns->rewind_dir_fn(handle, dirp);
1498 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1499 mode_t mode)
1501 VFS_FIND(mkdir);
1502 return handle->fns->mkdir_fn(handle, path, mode);
1505 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1507 VFS_FIND(rmdir);
1508 return handle->fns->rmdir_fn(handle, path);
1511 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1512 DIR *dir)
1514 VFS_FIND(closedir);
1515 return handle->fns->closedir_fn(handle, dir);
1518 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1519 DIR *dirp)
1521 VFS_FIND(init_search_op);
1522 handle->fns->init_search_op_fn(handle, dirp);
1525 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1526 struct smb_filename *smb_fname, struct files_struct *fsp,
1527 int flags, mode_t mode)
1529 VFS_FIND(open);
1530 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1533 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1534 struct smb_request *req,
1535 uint16_t root_dir_fid,
1536 struct smb_filename *smb_fname,
1537 uint32_t access_mask,
1538 uint32_t share_access,
1539 uint32_t create_disposition,
1540 uint32_t create_options,
1541 uint32_t file_attributes,
1542 uint32_t oplock_request,
1543 uint64_t allocation_size,
1544 uint32_t private_flags,
1545 struct security_descriptor *sd,
1546 struct ea_list *ea_list,
1547 files_struct **result,
1548 int *pinfo)
1550 VFS_FIND(create_file);
1551 return handle->fns->create_file_fn(
1552 handle, req, root_dir_fid, smb_fname, access_mask,
1553 share_access, create_disposition, create_options,
1554 file_attributes, oplock_request, allocation_size,
1555 private_flags, sd, ea_list,
1556 result, pinfo);
1559 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1560 struct files_struct *fsp)
1562 VFS_FIND(close);
1563 return handle->fns->close_fn(handle, fsp);
1566 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1567 struct files_struct *fsp, void *data, size_t n)
1569 VFS_FIND(read);
1570 return handle->fns->read_fn(handle, fsp, data, n);
1573 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1574 struct files_struct *fsp, void *data, size_t n,
1575 off_t offset)
1577 VFS_FIND(pread);
1578 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1581 struct smb_vfs_call_pread_state {
1582 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1583 ssize_t retval;
1586 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1588 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1589 TALLOC_CTX *mem_ctx,
1590 struct tevent_context *ev,
1591 struct files_struct *fsp,
1592 void *data,
1593 size_t n, off_t offset)
1595 struct tevent_req *req, *subreq;
1596 struct smb_vfs_call_pread_state *state;
1598 req = tevent_req_create(mem_ctx, &state,
1599 struct smb_vfs_call_pread_state);
1600 if (req == NULL) {
1601 return NULL;
1603 VFS_FIND(pread_send);
1604 state->recv_fn = handle->fns->pread_recv_fn;
1606 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1607 offset);
1608 if (tevent_req_nomem(subreq, req)) {
1609 return tevent_req_post(req, ev);
1611 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1612 return req;
1615 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1617 struct tevent_req *req = tevent_req_callback_data(
1618 subreq, struct tevent_req);
1619 struct smb_vfs_call_pread_state *state = tevent_req_data(
1620 req, struct smb_vfs_call_pread_state);
1621 int err;
1623 state->retval = state->recv_fn(subreq, &err);
1624 TALLOC_FREE(subreq);
1625 if (state->retval == -1) {
1626 tevent_req_error(req, err);
1627 return;
1629 tevent_req_done(req);
1632 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req, int *perrno)
1634 struct smb_vfs_call_pread_state *state = tevent_req_data(
1635 req, struct smb_vfs_call_pread_state);
1636 int err;
1638 if (tevent_req_is_unix_error(req, &err)) {
1639 *perrno = err;
1640 return -1;
1642 return state->retval;
1645 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1646 struct files_struct *fsp, const void *data,
1647 size_t n)
1649 VFS_FIND(write);
1650 return handle->fns->write_fn(handle, fsp, data, n);
1653 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1654 struct files_struct *fsp, const void *data,
1655 size_t n, off_t offset)
1657 VFS_FIND(pwrite);
1658 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1661 struct smb_vfs_call_pwrite_state {
1662 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1663 ssize_t retval;
1666 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1668 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1669 TALLOC_CTX *mem_ctx,
1670 struct tevent_context *ev,
1671 struct files_struct *fsp,
1672 const void *data,
1673 size_t n, off_t offset)
1675 struct tevent_req *req, *subreq;
1676 struct smb_vfs_call_pwrite_state *state;
1678 req = tevent_req_create(mem_ctx, &state,
1679 struct smb_vfs_call_pwrite_state);
1680 if (req == NULL) {
1681 return NULL;
1683 VFS_FIND(pwrite_send);
1684 state->recv_fn = handle->fns->pwrite_recv_fn;
1686 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1687 offset);
1688 if (tevent_req_nomem(subreq, req)) {
1689 return tevent_req_post(req, ev);
1691 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1692 return req;
1695 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1697 struct tevent_req *req = tevent_req_callback_data(
1698 subreq, struct tevent_req);
1699 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1700 req, struct smb_vfs_call_pwrite_state);
1701 int err;
1703 state->retval = state->recv_fn(subreq, &err);
1704 TALLOC_FREE(subreq);
1705 if (state->retval == -1) {
1706 tevent_req_error(req, err);
1707 return;
1709 tevent_req_done(req);
1712 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req, int *perrno)
1714 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1715 req, struct smb_vfs_call_pwrite_state);
1716 int err;
1718 if (tevent_req_is_unix_error(req, &err)) {
1719 *perrno = err;
1720 return -1;
1722 return state->retval;
1725 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1726 struct files_struct *fsp, off_t offset,
1727 int whence)
1729 VFS_FIND(lseek);
1730 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1733 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1734 files_struct *fromfsp, const DATA_BLOB *header,
1735 off_t offset, size_t count)
1737 VFS_FIND(sendfile);
1738 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1739 count);
1742 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1743 files_struct *tofsp, off_t offset,
1744 size_t count)
1746 VFS_FIND(recvfile);
1747 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1750 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1751 const struct smb_filename *smb_fname_src,
1752 const struct smb_filename *smb_fname_dst)
1754 VFS_FIND(rename);
1755 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1758 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1759 struct files_struct *fsp)
1761 VFS_FIND(fsync);
1762 return handle->fns->fsync_fn(handle, fsp);
1765 struct smb_vfs_call_fsync_state {
1766 int (*recv_fn)(struct tevent_req *req, int *err);
1767 int retval;
1770 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1772 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1773 TALLOC_CTX *mem_ctx,
1774 struct tevent_context *ev,
1775 struct files_struct *fsp)
1777 struct tevent_req *req, *subreq;
1778 struct smb_vfs_call_fsync_state *state;
1780 req = tevent_req_create(mem_ctx, &state,
1781 struct smb_vfs_call_fsync_state);
1782 if (req == NULL) {
1783 return NULL;
1785 VFS_FIND(fsync_send);
1786 state->recv_fn = handle->fns->fsync_recv_fn;
1788 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1789 if (tevent_req_nomem(subreq, req)) {
1790 return tevent_req_post(req, ev);
1792 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1793 return req;
1796 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1798 struct tevent_req *req = tevent_req_callback_data(
1799 subreq, struct tevent_req);
1800 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1801 req, struct smb_vfs_call_fsync_state);
1802 int err;
1804 state->retval = state->recv_fn(subreq, &err);
1805 TALLOC_FREE(subreq);
1806 if (state->retval == -1) {
1807 tevent_req_error(req, err);
1808 return;
1810 tevent_req_done(req);
1813 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, int *perrno)
1815 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1816 req, struct smb_vfs_call_fsync_state);
1817 int err;
1819 if (tevent_req_is_unix_error(req, &err)) {
1820 *perrno = err;
1821 return -1;
1823 return state->retval;
1827 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1828 struct smb_filename *smb_fname)
1830 VFS_FIND(stat);
1831 return handle->fns->stat_fn(handle, smb_fname);
1834 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1835 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1837 VFS_FIND(fstat);
1838 return handle->fns->fstat_fn(handle, fsp, sbuf);
1841 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1842 struct smb_filename *smb_filename)
1844 VFS_FIND(lstat);
1845 return handle->fns->lstat_fn(handle, smb_filename);
1848 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1849 struct files_struct *fsp,
1850 const SMB_STRUCT_STAT *sbuf)
1852 VFS_FIND(get_alloc_size);
1853 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1856 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1857 const struct smb_filename *smb_fname)
1859 VFS_FIND(unlink);
1860 return handle->fns->unlink_fn(handle, smb_fname);
1863 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1864 mode_t mode)
1866 VFS_FIND(chmod);
1867 return handle->fns->chmod_fn(handle, path, mode);
1870 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1871 struct files_struct *fsp, mode_t mode)
1873 VFS_FIND(fchmod);
1874 return handle->fns->fchmod_fn(handle, fsp, mode);
1877 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1878 uid_t uid, gid_t gid)
1880 VFS_FIND(chown);
1881 return handle->fns->chown_fn(handle, path, uid, gid);
1884 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1885 struct files_struct *fsp, uid_t uid, gid_t gid)
1887 VFS_FIND(fchown);
1888 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1891 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1892 uid_t uid, gid_t gid)
1894 VFS_FIND(lchown);
1895 return handle->fns->lchown_fn(handle, path, uid, gid);
1898 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1900 int ret;
1901 bool as_root = false;
1902 const char *path;
1903 char *saved_dir = NULL;
1904 char *parent_dir = NULL;
1905 NTSTATUS status;
1907 if (fsp->fh->fd != -1) {
1908 /* Try fchown. */
1909 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1910 if (ret == 0) {
1911 return NT_STATUS_OK;
1913 if (ret == -1 && errno != ENOSYS) {
1914 return map_nt_error_from_unix(errno);
1918 as_root = (geteuid() == 0);
1920 if (as_root) {
1922 * We are being asked to chown as root. Make
1923 * sure we chdir() into the path to pin it,
1924 * and always act using lchown to ensure we
1925 * don't deref any symbolic links.
1927 const char *final_component = NULL;
1928 struct smb_filename local_fname;
1930 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1931 if (!saved_dir) {
1932 status = map_nt_error_from_unix(errno);
1933 DEBUG(0,("vfs_chown_fsp: failed to get "
1934 "current working directory. Error was %s\n",
1935 strerror(errno)));
1936 return status;
1939 if (!parent_dirname(talloc_tos(),
1940 fsp->fsp_name->base_name,
1941 &parent_dir,
1942 &final_component)) {
1943 return NT_STATUS_NO_MEMORY;
1946 /* cd into the parent dir to pin it. */
1947 ret = vfs_ChDir(fsp->conn, parent_dir);
1948 if (ret == -1) {
1949 return map_nt_error_from_unix(errno);
1952 ZERO_STRUCT(local_fname);
1953 local_fname.base_name = discard_const_p(char, final_component);
1955 /* Must use lstat here. */
1956 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1957 if (ret == -1) {
1958 status = map_nt_error_from_unix(errno);
1959 goto out;
1962 /* Ensure it matches the fsp stat. */
1963 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1964 status = NT_STATUS_ACCESS_DENIED;
1965 goto out;
1967 path = final_component;
1968 } else {
1969 path = fsp->fsp_name->base_name;
1972 if (fsp->posix_open || as_root) {
1973 ret = SMB_VFS_LCHOWN(fsp->conn,
1974 path,
1975 uid, gid);
1976 } else {
1977 ret = SMB_VFS_CHOWN(fsp->conn,
1978 path,
1979 uid, gid);
1982 if (ret == 0) {
1983 status = NT_STATUS_OK;
1984 } else {
1985 status = map_nt_error_from_unix(errno);
1988 out:
1990 if (as_root) {
1991 vfs_ChDir(fsp->conn,saved_dir);
1992 TALLOC_FREE(saved_dir);
1993 TALLOC_FREE(parent_dir);
1995 return status;
1998 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
2000 VFS_FIND(chdir);
2001 return handle->fns->chdir_fn(handle, path);
2004 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
2006 VFS_FIND(getwd);
2007 return handle->fns->getwd_fn(handle);
2010 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
2011 const struct smb_filename *smb_fname,
2012 struct smb_file_time *ft)
2014 VFS_FIND(ntimes);
2015 return handle->fns->ntimes_fn(handle, smb_fname, ft);
2018 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2019 struct files_struct *fsp, off_t offset)
2021 VFS_FIND(ftruncate);
2022 return handle->fns->ftruncate_fn(handle, fsp, offset);
2025 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2026 struct files_struct *fsp,
2027 enum vfs_fallocate_mode mode,
2028 off_t offset,
2029 off_t len)
2031 VFS_FIND(fallocate);
2032 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2035 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2036 struct files_struct *fsp, uint32 share_mode,
2037 uint32_t access_mask)
2039 VFS_FIND(kernel_flock);
2040 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2041 access_mask);
2044 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2045 struct files_struct *fsp, int leasetype)
2047 VFS_FIND(linux_setlease);
2048 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2051 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
2052 const char *newpath)
2054 VFS_FIND(symlink);
2055 return handle->fns->symlink_fn(handle, oldpath, newpath);
2058 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2059 const char *path, char *buf, size_t bufsiz)
2061 VFS_FIND(readlink);
2062 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
2065 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
2066 const char *newpath)
2068 VFS_FIND(link);
2069 return handle->fns->link_fn(handle, oldpath, newpath);
2072 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
2073 mode_t mode, SMB_DEV_T dev)
2075 VFS_FIND(mknod);
2076 return handle->fns->mknod_fn(handle, path, mode, dev);
2079 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
2081 VFS_FIND(realpath);
2082 return handle->fns->realpath_fn(handle, path);
2085 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
2086 struct sys_notify_context *ctx,
2087 const char *path,
2088 uint32_t *filter,
2089 uint32_t *subdir_filter,
2090 void (*callback)(struct sys_notify_context *ctx,
2091 void *private_data,
2092 struct notify_event *ev),
2093 void *private_data, void *handle_p)
2095 VFS_FIND(notify_watch);
2096 return handle->fns->notify_watch_fn(handle, ctx, path,
2097 filter, subdir_filter, callback,
2098 private_data, handle_p);
2101 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
2102 unsigned int flags)
2104 VFS_FIND(chflags);
2105 return handle->fns->chflags_fn(handle, path, flags);
2108 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2109 const SMB_STRUCT_STAT *sbuf)
2111 VFS_FIND(file_id_create);
2112 return handle->fns->file_id_create_fn(handle, sbuf);
2115 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2116 struct files_struct *fsp,
2117 const char *fname,
2118 TALLOC_CTX *mem_ctx,
2119 unsigned int *num_streams,
2120 struct stream_struct **streams)
2122 VFS_FIND(streaminfo);
2123 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
2124 num_streams, streams);
2127 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2128 const char *path, const char *name,
2129 TALLOC_CTX *mem_ctx, char **found_name)
2131 VFS_FIND(get_real_filename);
2132 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2133 found_name);
2136 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2137 const char *filename)
2139 VFS_FIND(connectpath);
2140 return handle->fns->connectpath_fn(handle, filename);
2143 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2144 struct files_struct *fsp,
2145 struct lock_struct *plock)
2147 VFS_FIND(strict_lock);
2148 return handle->fns->strict_lock_fn(handle, fsp, plock);
2151 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2152 struct files_struct *fsp,
2153 struct lock_struct *plock)
2155 VFS_FIND(strict_unlock);
2156 handle->fns->strict_unlock_fn(handle, fsp, plock);
2159 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2160 const char *name,
2161 enum vfs_translate_direction direction,
2162 TALLOC_CTX *mem_ctx,
2163 char **mapped_name)
2165 VFS_FIND(translate_name);
2166 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2167 mapped_name);
2170 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2171 struct files_struct *fsp,
2172 TALLOC_CTX *ctx,
2173 uint32_t function,
2174 uint16_t req_flags,
2175 const uint8_t *in_data,
2176 uint32_t in_len,
2177 uint8_t **out_data,
2178 uint32_t max_out_len,
2179 uint32_t *out_len)
2181 VFS_FIND(fsctl);
2182 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2183 in_data, in_len, out_data, max_out_len,
2184 out_len);
2187 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2188 struct files_struct *fsp,
2189 uint32 security_info,
2190 TALLOC_CTX *mem_ctx,
2191 struct security_descriptor **ppdesc)
2193 VFS_FIND(fget_nt_acl);
2194 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2195 mem_ctx, ppdesc);
2198 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2199 const char *name,
2200 uint32 security_info,
2201 TALLOC_CTX *mem_ctx,
2202 struct security_descriptor **ppdesc)
2204 VFS_FIND(get_nt_acl);
2205 return handle->fns->get_nt_acl_fn(handle, name, security_info, mem_ctx, ppdesc);
2208 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2209 struct files_struct *fsp,
2210 uint32 security_info_sent,
2211 const struct security_descriptor *psd)
2213 VFS_FIND(fset_nt_acl);
2214 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2215 psd);
2218 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2219 struct smb_filename *file,
2220 struct security_acl *sacl,
2221 uint32_t access_requested,
2222 uint32_t access_denied)
2224 VFS_FIND(audit_file);
2225 return handle->fns->audit_file_fn(handle,
2226 file,
2227 sacl,
2228 access_requested,
2229 access_denied);
2232 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2233 mode_t mode)
2235 VFS_FIND(chmod_acl);
2236 return handle->fns->chmod_acl_fn(handle, name, mode);
2239 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2240 struct files_struct *fsp, mode_t mode)
2242 VFS_FIND(fchmod_acl);
2243 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2246 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2247 const char *path_p,
2248 SMB_ACL_TYPE_T type,
2249 TALLOC_CTX *mem_ctx)
2251 VFS_FIND(sys_acl_get_file);
2252 return handle->fns->sys_acl_get_file_fn(handle, path_p, type, mem_ctx);
2255 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2256 struct files_struct *fsp,
2257 TALLOC_CTX *mem_ctx)
2259 VFS_FIND(sys_acl_get_fd);
2260 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2263 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2264 const char *path_p,
2265 TALLOC_CTX *mem_ctx,
2266 char **blob_description,
2267 DATA_BLOB *blob)
2269 VFS_FIND(sys_acl_blob_get_file);
2270 return handle->fns->sys_acl_blob_get_file_fn(handle, path_p, mem_ctx, blob_description, blob);
2273 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2274 struct files_struct *fsp,
2275 TALLOC_CTX *mem_ctx,
2276 char **blob_description,
2277 DATA_BLOB *blob)
2279 VFS_FIND(sys_acl_blob_get_fd);
2280 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2283 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2284 const char *name, SMB_ACL_TYPE_T acltype,
2285 SMB_ACL_T theacl)
2287 VFS_FIND(sys_acl_set_file);
2288 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2291 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2292 struct files_struct *fsp, SMB_ACL_T theacl)
2294 VFS_FIND(sys_acl_set_fd);
2295 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2298 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2299 const char *path)
2301 VFS_FIND(sys_acl_delete_def_file);
2302 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2305 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2306 const char *path, const char *name, void *value,
2307 size_t size)
2309 VFS_FIND(getxattr);
2310 return handle->fns->getxattr_fn(handle, path, name, value, size);
2313 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2314 struct files_struct *fsp, const char *name,
2315 void *value, size_t size)
2317 VFS_FIND(fgetxattr);
2318 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2321 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2322 const char *path, char *list, size_t size)
2324 VFS_FIND(listxattr);
2325 return handle->fns->listxattr_fn(handle, path, list, size);
2328 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2329 struct files_struct *fsp, char *list,
2330 size_t size)
2332 VFS_FIND(flistxattr);
2333 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2336 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2337 const char *path, const char *name)
2339 VFS_FIND(removexattr);
2340 return handle->fns->removexattr_fn(handle, path, name);
2343 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2344 struct files_struct *fsp, const char *name)
2346 VFS_FIND(fremovexattr);
2347 return handle->fns->fremovexattr_fn(handle, fsp, name);
2350 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2351 const char *name, const void *value, size_t size,
2352 int flags)
2354 VFS_FIND(setxattr);
2355 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2358 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2359 struct files_struct *fsp, const char *name,
2360 const void *value, size_t size, int flags)
2362 VFS_FIND(fsetxattr);
2363 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2366 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2367 struct files_struct *fsp)
2369 VFS_FIND(aio_force);
2370 return handle->fns->aio_force_fn(handle, fsp);
2373 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2374 const struct smb_filename *fname,
2375 SMB_STRUCT_STAT *sbuf)
2377 VFS_FIND(is_offline);
2378 return handle->fns->is_offline_fn(handle, fname, sbuf);
2381 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2382 const struct smb_filename *fname)
2384 VFS_FIND(set_offline);
2385 return handle->fns->set_offline_fn(handle, fname);
2388 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2389 struct files_struct *fsp,
2390 TALLOC_CTX *mem_ctx,
2391 DATA_BLOB *cookie)
2393 VFS_FIND(durable_cookie);
2394 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2397 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2398 struct files_struct *fsp,
2399 const DATA_BLOB old_cookie,
2400 TALLOC_CTX *mem_ctx,
2401 DATA_BLOB *new_cookie)
2403 VFS_FIND(durable_disconnect);
2404 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2405 mem_ctx, new_cookie);
2408 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2409 struct smb_request *smb1req,
2410 struct smbXsrv_open *op,
2411 const DATA_BLOB old_cookie,
2412 TALLOC_CTX *mem_ctx,
2413 struct files_struct **fsp,
2414 DATA_BLOB *new_cookie)
2416 VFS_FIND(durable_reconnect);
2417 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2418 old_cookie, mem_ctx, fsp,
2419 new_cookie);