libcli/smb: add basic session->smb2.channel_sequence handling
[Samba/gebeck_regimport.git] / source3 / smbd / vfs.c
blob349f0a0b2f93bc5e49540113bfbf35c98af901d6
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);
331 vfs_objects = lp_vfs_objects(SNUM(conn));
333 /* Override VFS functions if 'vfs object' was not specified*/
334 if (!vfs_objects || !vfs_objects[0])
335 return True;
337 for (i=0; vfs_objects[i] ;) {
338 i++;
341 for (j=i-1; j >= 0; j--) {
342 if (!vfs_init_custom(conn, vfs_objects[j])) {
343 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
344 return False;
347 return True;
350 /*******************************************************************
351 Check if a file exists in the vfs.
352 ********************************************************************/
354 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
356 /* Only return OK if stat was successful and S_ISREG */
357 if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
358 S_ISREG(smb_fname->st.st_ex_mode)) {
359 return NT_STATUS_OK;
362 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
365 /****************************************************************************
366 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
367 ****************************************************************************/
369 ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
371 size_t total=0;
373 while (total < byte_count)
375 ssize_t ret = SMB_VFS_READ(fsp, buf + total,
376 byte_count - total);
378 if (ret == 0) return total;
379 if (ret == -1) {
380 if (errno == EINTR)
381 continue;
382 else
383 return -1;
385 total += ret;
387 return (ssize_t)total;
390 ssize_t vfs_pread_data(files_struct *fsp, char *buf,
391 size_t byte_count, off_t offset)
393 size_t total=0;
395 while (total < byte_count)
397 ssize_t ret = SMB_VFS_PREAD(fsp, buf + total,
398 byte_count - total, offset + total);
400 if (ret == 0) return total;
401 if (ret == -1) {
402 if (errno == EINTR)
403 continue;
404 else
405 return -1;
407 total += ret;
409 return (ssize_t)total;
412 /****************************************************************************
413 Write data to a fd on the vfs.
414 ****************************************************************************/
416 ssize_t vfs_write_data(struct smb_request *req,
417 files_struct *fsp,
418 const char *buffer,
419 size_t N)
421 size_t total=0;
422 ssize_t ret;
424 if (req && req->unread_bytes) {
425 SMB_ASSERT(req->unread_bytes == N);
426 /* VFS_RECVFILE must drain the socket
427 * before returning. */
428 req->unread_bytes = 0;
429 return SMB_VFS_RECVFILE(req->sconn->sock,
430 fsp,
431 (off_t)-1,
435 while (total < N) {
436 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
438 if (ret == -1)
439 return -1;
440 if (ret == 0)
441 return total;
443 total += ret;
445 return (ssize_t)total;
448 ssize_t vfs_pwrite_data(struct smb_request *req,
449 files_struct *fsp,
450 const char *buffer,
451 size_t N,
452 off_t offset)
454 size_t total=0;
455 ssize_t ret;
457 if (req && req->unread_bytes) {
458 SMB_ASSERT(req->unread_bytes == N);
459 /* VFS_RECVFILE must drain the socket
460 * before returning. */
461 req->unread_bytes = 0;
462 return SMB_VFS_RECVFILE(req->sconn->sock,
463 fsp,
464 offset,
468 while (total < N) {
469 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
470 offset + total);
472 if (ret == -1)
473 return -1;
474 if (ret == 0)
475 return total;
477 total += ret;
479 return (ssize_t)total;
481 /****************************************************************************
482 An allocate file space call using the vfs interface.
483 Allocates space for a file from a filedescriptor.
484 Returns 0 on success, -1 on failure.
485 ****************************************************************************/
487 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
489 int ret;
490 connection_struct *conn = fsp->conn;
491 uint64_t space_avail;
492 uint64_t bsize,dfree,dsize;
493 NTSTATUS status;
496 * Actually try and commit the space on disk....
499 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
500 fsp_str_dbg(fsp), (double)len));
502 if (((off_t)len) < 0) {
503 DEBUG(0,("vfs_allocate_file_space: %s negative len "
504 "requested.\n", fsp_str_dbg(fsp)));
505 errno = EINVAL;
506 return -1;
509 status = vfs_stat_fsp(fsp);
510 if (!NT_STATUS_IS_OK(status)) {
511 return -1;
514 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
515 return 0;
517 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
518 /* Shrink - use ftruncate. */
520 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
521 "size %.0f\n", fsp_str_dbg(fsp),
522 (double)fsp->fsp_name->st.st_ex_size));
524 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
526 flush_write_cache(fsp, SIZECHANGE_FLUSH);
527 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
528 set_filelen_write_cache(fsp, len);
531 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
533 return ret;
536 if (!lp_strict_allocate(SNUM(fsp->conn)))
537 return 0;
539 /* Grow - we need to test if we have enough space. */
541 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
543 /* See if we have a syscall that will allocate beyond end-of-file
544 without changing EOF. */
545 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
547 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
549 if (ret == 0) {
550 /* We changed the allocation size on disk, but not
551 EOF - exactly as required. We're done ! */
552 return 0;
555 len -= fsp->fsp_name->st.st_ex_size;
556 len /= 1024; /* Len is now number of 1k blocks needed. */
557 space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
558 &bsize, &dfree, &dsize);
559 if (space_avail == (uint64_t)-1) {
560 return -1;
563 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
564 "needed blocks = %.0f, space avail = %.0f\n",
565 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
566 (double)space_avail));
568 if (len > space_avail) {
569 errno = ENOSPC;
570 return -1;
573 return 0;
576 /****************************************************************************
577 A vfs set_filelen call.
578 set the length of a file from a filedescriptor.
579 Returns 0 on success, -1 on failure.
580 ****************************************************************************/
582 int vfs_set_filelen(files_struct *fsp, off_t len)
584 int ret;
586 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
588 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
589 fsp_str_dbg(fsp), (double)len));
590 flush_write_cache(fsp, SIZECHANGE_FLUSH);
591 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
592 set_filelen_write_cache(fsp, len);
593 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
594 FILE_NOTIFY_CHANGE_SIZE
595 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
596 fsp->fsp_name->base_name);
599 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
601 return ret;
604 /****************************************************************************
605 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
606 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
607 as this is also called from the default SMB_VFS_FTRUNCATE code.
608 Always extends the file size.
609 Returns 0 on success, errno on failure.
610 ****************************************************************************/
612 #define SPARSE_BUF_WRITE_SIZE (32*1024)
614 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
616 ssize_t pwrite_ret;
617 size_t total = 0;
619 if (!sparse_buf) {
620 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
621 if (!sparse_buf) {
622 errno = ENOMEM;
623 return ENOMEM;
627 while (total < len) {
628 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
630 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
631 if (pwrite_ret == -1) {
632 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
633 "%s failed with error %s\n",
634 fsp_str_dbg(fsp), strerror(errno)));
635 return errno;
637 total += pwrite_ret;
640 return 0;
643 /****************************************************************************
644 A vfs fill sparse call.
645 Writes zeros from the end of file to len, if len is greater than EOF.
646 Used only by strict_sync.
647 Returns 0 on success, -1 on failure.
648 ****************************************************************************/
650 int vfs_fill_sparse(files_struct *fsp, off_t len)
652 int ret;
653 NTSTATUS status;
654 off_t offset;
655 size_t num_to_write;
657 status = vfs_stat_fsp(fsp);
658 if (!NT_STATUS_IS_OK(status)) {
659 return -1;
662 if (len <= fsp->fsp_name->st.st_ex_size) {
663 return 0;
666 #ifdef S_ISFIFO
667 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
668 return 0;
670 #endif
672 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
673 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
674 (double)fsp->fsp_name->st.st_ex_size, (double)len,
675 (double)(len - fsp->fsp_name->st.st_ex_size)));
677 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
679 flush_write_cache(fsp, SIZECHANGE_FLUSH);
681 offset = fsp->fsp_name->st.st_ex_size;
682 num_to_write = len - fsp->fsp_name->st.st_ex_size;
684 /* Only do this on non-stream file handles. */
685 if (fsp->base_fsp == NULL) {
686 /* for allocation try fallocate first. This can fail on some
687 * platforms e.g. when the filesystem doesn't support it and no
688 * emulation is being done by the libc (like on AIX with JFS1). In that
689 * case we do our own emulation. fallocate implementations can
690 * return ENOTSUP or EINVAL in cases like that. */
691 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
692 offset, num_to_write);
693 if (ret == ENOSPC) {
694 errno = ENOSPC;
695 ret = -1;
696 goto out;
698 if (ret == 0) {
699 goto out;
701 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
702 "error %d. Falling back to slow manual allocation\n", ret));
705 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
706 if (ret != 0) {
707 errno = ret;
708 ret = -1;
711 out:
713 if (ret == 0) {
714 set_filelen_write_cache(fsp, len);
717 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
718 return ret;
721 /****************************************************************************
722 Transfer some data (n bytes) between two file_struct's.
723 ****************************************************************************/
725 static ssize_t vfs_read_fn(void *file, void *buf, size_t len)
727 struct files_struct *fsp = (struct files_struct *)file;
729 return SMB_VFS_READ(fsp, buf, len);
732 static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
734 struct files_struct *fsp = (struct files_struct *)file;
736 return SMB_VFS_WRITE(fsp, buf, len);
739 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
741 return transfer_file_internal((void *)in, (void *)out, n,
742 vfs_read_fn, vfs_write_fn);
745 /*******************************************************************
746 A vfs_readdir wrapper which just returns the file name.
747 ********************************************************************/
749 const char *vfs_readdirname(connection_struct *conn, void *p,
750 SMB_STRUCT_STAT *sbuf, char **talloced)
752 struct dirent *ptr= NULL;
753 const char *dname;
754 char *translated;
755 NTSTATUS status;
757 if (!p)
758 return(NULL);
760 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
761 if (!ptr)
762 return(NULL);
764 dname = ptr->d_name;
767 #ifdef NEXT2
768 if (telldir(p) < 0)
769 return(NULL);
770 #endif
772 #ifdef HAVE_BROKEN_READDIR_NAME
773 /* using /usr/ucb/cc is BAD */
774 dname = dname - 2;
775 #endif
777 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
778 talloc_tos(), &translated);
779 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
780 *talloced = NULL;
781 return dname;
783 *talloced = translated;
784 if (!NT_STATUS_IS_OK(status)) {
785 return NULL;
787 return translated;
790 /*******************************************************************
791 A wrapper for vfs_chdir().
792 ********************************************************************/
794 int vfs_ChDir(connection_struct *conn, const char *path)
796 int res;
798 if (!LastDir) {
799 LastDir = SMB_STRDUP("");
802 if (strcsequal(path,"."))
803 return(0);
805 if (*path == '/' && strcsequal(LastDir,path))
806 return(0);
808 DEBUG(4,("vfs_ChDir to %s\n",path));
810 res = SMB_VFS_CHDIR(conn,path);
811 if (!res) {
812 SAFE_FREE(LastDir);
813 LastDir = SMB_STRDUP(path);
815 return(res);
818 /*******************************************************************
819 Return the absolute current directory path - given a UNIX pathname.
820 Note that this path is returned in DOS format, not UNIX
821 format. Note this can be called with conn == NULL.
822 ********************************************************************/
824 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
826 char *current_dir = NULL;
827 char *result = NULL;
828 DATA_BLOB cache_value;
829 struct file_id key;
830 struct smb_filename *smb_fname_dot = NULL;
831 struct smb_filename *smb_fname_full = NULL;
832 NTSTATUS status;
834 if (!lp_getwd_cache()) {
835 goto nocache;
838 status = create_synthetic_smb_fname(ctx, ".", NULL, NULL,
839 &smb_fname_dot);
840 if (!NT_STATUS_IS_OK(status)) {
841 errno = map_errno_from_nt_status(status);
842 goto out;
845 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
847 * Known to fail for root: the directory may be NFS-mounted
848 * and exported with root_squash (so has no root access).
850 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
851 "(NFS problem ?)\n", strerror(errno) ));
852 goto nocache;
855 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
857 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
858 data_blob_const(&key, sizeof(key)),
859 &cache_value)) {
860 goto nocache;
863 SMB_ASSERT((cache_value.length > 0)
864 && (cache_value.data[cache_value.length-1] == '\0'));
866 status = create_synthetic_smb_fname(ctx, (char *)cache_value.data,
867 NULL, NULL, &smb_fname_full);
868 if (!NT_STATUS_IS_OK(status)) {
869 errno = map_errno_from_nt_status(status);
870 goto out;
873 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
874 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
875 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
876 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
878 * Ok, we're done
880 result = talloc_strdup(ctx, smb_fname_full->base_name);
881 if (result == NULL) {
882 errno = ENOMEM;
884 goto out;
887 nocache:
890 * We don't have the information to hand so rely on traditional
891 * methods. The very slow getcwd, which spawns a process on some
892 * systems, or the not quite so bad getwd.
895 current_dir = SMB_VFS_GETWD(conn);
896 if (current_dir == NULL) {
897 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
898 strerror(errno)));
899 goto out;
902 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
903 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
905 memcache_add(smbd_memcache(), GETWD_CACHE,
906 data_blob_const(&key, sizeof(key)),
907 data_blob_const(current_dir,
908 strlen(current_dir)+1));
911 result = talloc_strdup(ctx, current_dir);
912 if (result == NULL) {
913 errno = ENOMEM;
916 out:
917 TALLOC_FREE(smb_fname_dot);
918 TALLOC_FREE(smb_fname_full);
919 SAFE_FREE(current_dir);
920 return result;
923 /*******************************************************************
924 Reduce a file name, removing .. elements and checking that
925 it is below dir in the heirachy. This uses realpath.
926 This function must run as root, and will return names
927 and valid stat structs that can be checked on open.
928 ********************************************************************/
930 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
931 const char *fname,
932 struct smb_request *smbreq)
934 NTSTATUS status;
935 TALLOC_CTX *ctx = talloc_tos();
936 const char *conn_rootdir;
937 size_t rootdir_len;
938 char *dir_name = NULL;
939 const char *last_component = NULL;
940 char *resolved_name = NULL;
941 char *saved_dir = NULL;
942 struct smb_filename *smb_fname_cwd = NULL;
943 struct privilege_paths *priv_paths = NULL;
944 int ret;
946 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
947 fname,
948 conn->connectpath));
951 priv_paths = talloc_zero(smbreq, struct privilege_paths);
952 if (!priv_paths) {
953 status = NT_STATUS_NO_MEMORY;
954 goto err;
957 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
958 status = NT_STATUS_NO_MEMORY;
959 goto err;
962 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
963 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
965 if (priv_paths->parent_name.base_name == NULL ||
966 priv_paths->file_name.base_name == NULL) {
967 status = NT_STATUS_NO_MEMORY;
968 goto err;
971 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
972 status = map_nt_error_from_unix(errno);
973 goto err;
975 /* Remember where we were. */
976 saved_dir = vfs_GetWd(ctx, conn);
977 if (!saved_dir) {
978 status = map_nt_error_from_unix(errno);
979 goto err;
982 /* Go to the parent directory to lock in memory. */
983 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
984 status = map_nt_error_from_unix(errno);
985 goto err;
988 /* Get the absolute path of the parent directory. */
989 resolved_name = SMB_VFS_REALPATH(conn,".");
990 if (!resolved_name) {
991 status = map_nt_error_from_unix(errno);
992 goto err;
995 if (*resolved_name != '/') {
996 DEBUG(0,("check_reduced_name_with_privilege: realpath "
997 "doesn't return absolute paths !\n"));
998 status = NT_STATUS_OBJECT_NAME_INVALID;
999 goto err;
1002 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1003 priv_paths->parent_name.base_name,
1004 resolved_name));
1006 /* Now check the stat value is the same. */
1007 status = create_synthetic_smb_fname(talloc_tos(), ".",
1008 NULL, NULL,
1009 &smb_fname_cwd);
1010 if (!NT_STATUS_IS_OK(status)) {
1011 goto err;
1014 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1015 status = map_nt_error_from_unix(errno);
1016 goto err;
1019 /* Ensure we're pointing at the same place. */
1020 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1021 DEBUG(0,("check_reduced_name_with_privilege: "
1022 "device/inode/uid/gid on directory %s changed. "
1023 "Denying access !\n",
1024 priv_paths->parent_name.base_name));
1025 status = NT_STATUS_ACCESS_DENIED;
1026 goto err;
1029 /* Ensure we're below the connect path. */
1031 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1032 if (conn_rootdir == NULL) {
1033 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1034 "conn_rootdir\n"));
1035 status = NT_STATUS_ACCESS_DENIED;
1036 goto err;
1039 rootdir_len = strlen(conn_rootdir);
1040 if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1041 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1042 "attempt: %s is a symlink outside the "
1043 "share path\n",
1044 dir_name));
1045 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1046 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1047 status = NT_STATUS_ACCESS_DENIED;
1048 goto err;
1051 /* Now ensure that the last component either doesn't
1052 exist, or is *NOT* a symlink. */
1054 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1055 if (ret == -1) {
1056 /* Errno must be ENOENT for this be ok. */
1057 if (errno != ENOENT) {
1058 status = map_nt_error_from_unix(errno);
1059 DEBUG(2, ("check_reduced_name_with_privilege: "
1060 "LSTAT on %s failed with %s\n",
1061 priv_paths->file_name.base_name,
1062 nt_errstr(status)));
1063 goto err;
1067 if (VALID_STAT(priv_paths->file_name.st) &&
1068 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1069 DEBUG(2, ("check_reduced_name_with_privilege: "
1070 "Last component %s is a symlink. Denying"
1071 "access.\n",
1072 priv_paths->file_name.base_name));
1073 status = NT_STATUS_ACCESS_DENIED;
1074 goto err;
1077 smbreq->priv_paths = priv_paths;
1078 status = NT_STATUS_OK;
1080 err:
1082 if (saved_dir) {
1083 vfs_ChDir(conn, saved_dir);
1085 SAFE_FREE(resolved_name);
1086 if (!NT_STATUS_IS_OK(status)) {
1087 TALLOC_FREE(priv_paths);
1089 return status;
1092 /*******************************************************************
1093 Reduce a file name, removing .. elements and checking that
1094 it is below dir in the heirachy. This uses realpath.
1095 ********************************************************************/
1097 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1099 char *resolved_name = NULL;
1100 bool allow_symlinks = true;
1101 bool allow_widelinks = false;
1103 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1105 resolved_name = SMB_VFS_REALPATH(conn,fname);
1107 if (!resolved_name) {
1108 switch (errno) {
1109 case ENOTDIR:
1110 DEBUG(3,("check_reduced_name: Component not a "
1111 "directory in getting realpath for "
1112 "%s\n", fname));
1113 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1114 case ENOENT:
1116 TALLOC_CTX *ctx = talloc_tos();
1117 char *dir_name = NULL;
1118 const char *last_component = NULL;
1119 char *new_name = NULL;
1120 int ret;
1122 /* Last component didn't exist.
1123 Remove it and try and canonicalise
1124 the directory name. */
1125 if (!parent_dirname(ctx, fname,
1126 &dir_name,
1127 &last_component)) {
1128 return NT_STATUS_NO_MEMORY;
1131 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1132 if (!resolved_name) {
1133 NTSTATUS status = map_nt_error_from_unix(errno);
1135 if (errno == ENOENT || errno == ENOTDIR) {
1136 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1139 DEBUG(3,("check_reduce_name: "
1140 "couldn't get realpath for "
1141 "%s (%s)\n",
1142 fname,
1143 nt_errstr(status)));
1144 return status;
1146 ret = asprintf(&new_name, "%s/%s",
1147 resolved_name, last_component);
1148 SAFE_FREE(resolved_name);
1149 if (ret == -1) {
1150 return NT_STATUS_NO_MEMORY;
1152 resolved_name = new_name;
1153 break;
1155 default:
1156 DEBUG(3,("check_reduced_name: couldn't get "
1157 "realpath for %s\n", fname));
1158 return map_nt_error_from_unix(errno);
1162 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1163 resolved_name));
1165 if (*resolved_name != '/') {
1166 DEBUG(0,("check_reduced_name: realpath doesn't return "
1167 "absolute paths !\n"));
1168 SAFE_FREE(resolved_name);
1169 return NT_STATUS_OBJECT_NAME_INVALID;
1172 allow_widelinks = lp_widelinks(SNUM(conn));
1173 allow_symlinks = lp_symlinks(SNUM(conn));
1175 /* Common widelinks and symlinks checks. */
1176 if (!allow_widelinks || !allow_symlinks) {
1177 const char *conn_rootdir;
1178 size_t rootdir_len;
1180 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1181 if (conn_rootdir == NULL) {
1182 DEBUG(2, ("check_reduced_name: Could not get "
1183 "conn_rootdir\n"));
1184 SAFE_FREE(resolved_name);
1185 return NT_STATUS_ACCESS_DENIED;
1188 rootdir_len = strlen(conn_rootdir);
1189 if (strncmp(conn_rootdir, resolved_name,
1190 rootdir_len) != 0) {
1191 DEBUG(2, ("check_reduced_name: Bad access "
1192 "attempt: %s is a symlink outside the "
1193 "share path\n", fname));
1194 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1195 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1196 SAFE_FREE(resolved_name);
1197 return NT_STATUS_ACCESS_DENIED;
1200 /* Extra checks if all symlinks are disallowed. */
1201 if (!allow_symlinks) {
1202 /* fname can't have changed in resolved_path. */
1203 const char *p = &resolved_name[rootdir_len];
1205 /* *p can be '\0' if fname was "." */
1206 if (*p == '\0' && ISDOT(fname)) {
1207 goto out;
1210 if (*p != '/') {
1211 DEBUG(2, ("check_reduced_name: logic error (%c) "
1212 "in resolved_name: %s\n",
1214 fname));
1215 SAFE_FREE(resolved_name);
1216 return NT_STATUS_ACCESS_DENIED;
1219 p++;
1220 if (strcmp(fname, p)!=0) {
1221 DEBUG(2, ("check_reduced_name: Bad access "
1222 "attempt: %s is a symlink\n",
1223 fname));
1224 SAFE_FREE(resolved_name);
1225 return NT_STATUS_ACCESS_DENIED;
1230 out:
1232 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1233 resolved_name));
1234 SAFE_FREE(resolved_name);
1235 return NT_STATUS_OK;
1239 * XXX: This is temporary and there should be no callers of this once
1240 * smb_filename is plumbed through all path based operations.
1242 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1243 SMB_STRUCT_STAT *psbuf)
1245 struct smb_filename *smb_fname = NULL;
1246 NTSTATUS status;
1247 int ret;
1249 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1250 &smb_fname);
1251 if (!NT_STATUS_IS_OK(status)) {
1252 errno = map_errno_from_nt_status(status);
1253 return -1;
1256 if (lp_posix_pathnames()) {
1257 ret = SMB_VFS_LSTAT(conn, smb_fname);
1258 } else {
1259 ret = SMB_VFS_STAT(conn, smb_fname);
1262 if (ret != -1) {
1263 *psbuf = smb_fname->st;
1266 TALLOC_FREE(smb_fname);
1267 return ret;
1271 * XXX: This is temporary and there should be no callers of this once
1272 * smb_filename is plumbed through all path based operations.
1274 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1275 SMB_STRUCT_STAT *psbuf)
1277 struct smb_filename *smb_fname = NULL;
1278 NTSTATUS status;
1279 int ret;
1281 status = create_synthetic_smb_fname_split(talloc_tos(), fname, NULL,
1282 &smb_fname);
1283 if (!NT_STATUS_IS_OK(status)) {
1284 errno = map_errno_from_nt_status(status);
1285 return -1;
1288 ret = SMB_VFS_LSTAT(conn, smb_fname);
1289 if (ret != -1) {
1290 *psbuf = smb_fname->st;
1293 TALLOC_FREE(smb_fname);
1294 return ret;
1298 * Ensure LSTAT is called for POSIX paths.
1301 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1303 int ret;
1305 if(fsp->fh->fd == -1) {
1306 if (fsp->posix_open) {
1307 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1308 } else {
1309 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1311 if (ret == -1) {
1312 return map_nt_error_from_unix(errno);
1314 } else {
1315 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1316 return map_nt_error_from_unix(errno);
1319 return NT_STATUS_OK;
1323 * Initialize num_streams and streams, then call VFS op streaminfo
1325 NTSTATUS vfs_streaminfo(connection_struct *conn,
1326 struct files_struct *fsp,
1327 const char *fname,
1328 TALLOC_CTX *mem_ctx,
1329 unsigned int *num_streams,
1330 struct stream_struct **streams)
1332 *num_streams = 0;
1333 *streams = NULL;
1334 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1338 generate a file_id from a stat structure
1340 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1342 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1345 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1346 const char *service, const char *user)
1348 VFS_FIND(connect);
1349 return handle->fns->connect_fn(handle, service, user);
1352 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1354 VFS_FIND(disconnect);
1355 handle->fns->disconnect_fn(handle);
1358 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1359 const char *path, bool small_query,
1360 uint64_t *bsize, uint64_t *dfree,
1361 uint64_t *dsize)
1363 VFS_FIND(disk_free);
1364 return handle->fns->disk_free_fn(handle, path, small_query, bsize,
1365 dfree, dsize);
1368 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1369 enum SMB_QUOTA_TYPE qtype, unid_t id,
1370 SMB_DISK_QUOTA *qt)
1372 VFS_FIND(get_quota);
1373 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1376 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1377 enum SMB_QUOTA_TYPE qtype, unid_t id,
1378 SMB_DISK_QUOTA *qt)
1380 VFS_FIND(set_quota);
1381 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1384 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1385 struct files_struct *fsp,
1386 struct shadow_copy_data *shadow_copy_data,
1387 bool labels)
1389 VFS_FIND(get_shadow_copy_data);
1390 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1391 shadow_copy_data,
1392 labels);
1394 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1395 struct vfs_statvfs_struct *statbuf)
1397 VFS_FIND(statvfs);
1398 return handle->fns->statvfs_fn(handle, path, statbuf);
1401 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1402 enum timestamp_set_resolution *p_ts_res)
1404 VFS_FIND(fs_capabilities);
1405 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1408 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1409 struct dfs_GetDFSReferral *r)
1411 VFS_FIND(get_dfs_referrals);
1412 return handle->fns->get_dfs_referrals_fn(handle, r);
1415 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1416 const char *fname, const char *mask,
1417 uint32 attributes)
1419 VFS_FIND(opendir);
1420 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1423 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1424 struct files_struct *fsp,
1425 const char *mask,
1426 uint32 attributes)
1428 VFS_FIND(fdopendir);
1429 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1432 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1433 DIR *dirp,
1434 SMB_STRUCT_STAT *sbuf)
1436 VFS_FIND(readdir);
1437 return handle->fns->readdir_fn(handle, dirp, sbuf);
1440 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1441 DIR *dirp, long offset)
1443 VFS_FIND(seekdir);
1444 handle->fns->seekdir_fn(handle, dirp, offset);
1447 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1448 DIR *dirp)
1450 VFS_FIND(telldir);
1451 return handle->fns->telldir_fn(handle, dirp);
1454 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1455 DIR *dirp)
1457 VFS_FIND(rewind_dir);
1458 handle->fns->rewind_dir_fn(handle, dirp);
1461 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1462 mode_t mode)
1464 VFS_FIND(mkdir);
1465 return handle->fns->mkdir_fn(handle, path, mode);
1468 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1470 VFS_FIND(rmdir);
1471 return handle->fns->rmdir_fn(handle, path);
1474 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1475 DIR *dir)
1477 VFS_FIND(closedir);
1478 return handle->fns->closedir_fn(handle, dir);
1481 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1482 DIR *dirp)
1484 VFS_FIND(init_search_op);
1485 handle->fns->init_search_op_fn(handle, dirp);
1488 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1489 struct smb_filename *smb_fname, struct files_struct *fsp,
1490 int flags, mode_t mode)
1492 VFS_FIND(open);
1493 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1496 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1497 struct smb_request *req,
1498 uint16_t root_dir_fid,
1499 struct smb_filename *smb_fname,
1500 uint32_t access_mask,
1501 uint32_t share_access,
1502 uint32_t create_disposition,
1503 uint32_t create_options,
1504 uint32_t file_attributes,
1505 uint32_t oplock_request,
1506 uint64_t allocation_size,
1507 uint32_t private_flags,
1508 struct security_descriptor *sd,
1509 struct ea_list *ea_list,
1510 files_struct **result,
1511 int *pinfo)
1513 VFS_FIND(create_file);
1514 return handle->fns->create_file_fn(
1515 handle, req, root_dir_fid, smb_fname, access_mask,
1516 share_access, create_disposition, create_options,
1517 file_attributes, oplock_request, allocation_size,
1518 private_flags, sd, ea_list,
1519 result, pinfo);
1522 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1523 struct files_struct *fsp)
1525 VFS_FIND(close);
1526 return handle->fns->close_fn(handle, fsp);
1529 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1530 struct files_struct *fsp, void *data, size_t n)
1532 VFS_FIND(read);
1533 return handle->fns->read_fn(handle, fsp, data, n);
1536 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1537 struct files_struct *fsp, void *data, size_t n,
1538 off_t offset)
1540 VFS_FIND(pread);
1541 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1544 struct smb_vfs_call_pread_state {
1545 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1546 ssize_t retval;
1549 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1551 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1552 TALLOC_CTX *mem_ctx,
1553 struct tevent_context *ev,
1554 struct files_struct *fsp,
1555 void *data,
1556 size_t n, off_t offset)
1558 struct tevent_req *req, *subreq;
1559 struct smb_vfs_call_pread_state *state;
1561 req = tevent_req_create(mem_ctx, &state,
1562 struct smb_vfs_call_pread_state);
1563 if (req == NULL) {
1564 return NULL;
1566 VFS_FIND(pread_send);
1567 state->recv_fn = handle->fns->pread_recv_fn;
1569 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1570 offset);
1571 if (tevent_req_nomem(subreq, req)) {
1572 return tevent_req_post(req, ev);
1574 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1575 return req;
1578 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1580 struct tevent_req *req = tevent_req_callback_data(
1581 subreq, struct tevent_req);
1582 struct smb_vfs_call_pread_state *state = tevent_req_data(
1583 req, struct smb_vfs_call_pread_state);
1584 int err;
1586 state->retval = state->recv_fn(subreq, &err);
1587 TALLOC_FREE(subreq);
1588 if (state->retval == -1) {
1589 tevent_req_error(req, err);
1590 return;
1592 tevent_req_done(req);
1595 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req, int *perrno)
1597 struct smb_vfs_call_pread_state *state = tevent_req_data(
1598 req, struct smb_vfs_call_pread_state);
1599 int err;
1601 if (tevent_req_is_unix_error(req, &err)) {
1602 *perrno = err;
1603 return -1;
1605 return state->retval;
1608 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1609 struct files_struct *fsp, const void *data,
1610 size_t n)
1612 VFS_FIND(write);
1613 return handle->fns->write_fn(handle, fsp, data, n);
1616 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1617 struct files_struct *fsp, const void *data,
1618 size_t n, off_t offset)
1620 VFS_FIND(pwrite);
1621 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1624 struct smb_vfs_call_pwrite_state {
1625 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1626 ssize_t retval;
1629 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1631 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1632 TALLOC_CTX *mem_ctx,
1633 struct tevent_context *ev,
1634 struct files_struct *fsp,
1635 const void *data,
1636 size_t n, off_t offset)
1638 struct tevent_req *req, *subreq;
1639 struct smb_vfs_call_pwrite_state *state;
1641 req = tevent_req_create(mem_ctx, &state,
1642 struct smb_vfs_call_pwrite_state);
1643 if (req == NULL) {
1644 return NULL;
1646 VFS_FIND(pwrite_send);
1647 state->recv_fn = handle->fns->pwrite_recv_fn;
1649 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1650 offset);
1651 if (tevent_req_nomem(subreq, req)) {
1652 return tevent_req_post(req, ev);
1654 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1655 return req;
1658 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1660 struct tevent_req *req = tevent_req_callback_data(
1661 subreq, struct tevent_req);
1662 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1663 req, struct smb_vfs_call_pwrite_state);
1664 int err;
1666 state->retval = state->recv_fn(subreq, &err);
1667 TALLOC_FREE(subreq);
1668 if (state->retval == -1) {
1669 tevent_req_error(req, err);
1670 return;
1672 tevent_req_done(req);
1675 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req, int *perrno)
1677 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1678 req, struct smb_vfs_call_pwrite_state);
1679 int err;
1681 if (tevent_req_is_unix_error(req, &err)) {
1682 *perrno = err;
1683 return -1;
1685 return state->retval;
1688 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1689 struct files_struct *fsp, off_t offset,
1690 int whence)
1692 VFS_FIND(lseek);
1693 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1696 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1697 files_struct *fromfsp, const DATA_BLOB *header,
1698 off_t offset, size_t count)
1700 VFS_FIND(sendfile);
1701 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1702 count);
1705 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1706 files_struct *tofsp, off_t offset,
1707 size_t count)
1709 VFS_FIND(recvfile);
1710 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1713 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1714 const struct smb_filename *smb_fname_src,
1715 const struct smb_filename *smb_fname_dst)
1717 VFS_FIND(rename);
1718 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1721 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1722 struct files_struct *fsp)
1724 VFS_FIND(fsync);
1725 return handle->fns->fsync_fn(handle, fsp);
1728 struct smb_vfs_call_fsync_state {
1729 int (*recv_fn)(struct tevent_req *req, int *err);
1730 int retval;
1733 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1735 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1736 TALLOC_CTX *mem_ctx,
1737 struct tevent_context *ev,
1738 struct files_struct *fsp)
1740 struct tevent_req *req, *subreq;
1741 struct smb_vfs_call_fsync_state *state;
1743 req = tevent_req_create(mem_ctx, &state,
1744 struct smb_vfs_call_fsync_state);
1745 if (req == NULL) {
1746 return NULL;
1748 VFS_FIND(fsync_send);
1749 state->recv_fn = handle->fns->fsync_recv_fn;
1751 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1752 if (tevent_req_nomem(subreq, req)) {
1753 return tevent_req_post(req, ev);
1755 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1756 return req;
1759 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1761 struct tevent_req *req = tevent_req_callback_data(
1762 subreq, struct tevent_req);
1763 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1764 req, struct smb_vfs_call_fsync_state);
1765 int err;
1767 state->retval = state->recv_fn(subreq, &err);
1768 TALLOC_FREE(subreq);
1769 if (state->retval == -1) {
1770 tevent_req_error(req, err);
1771 return;
1773 tevent_req_done(req);
1776 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, int *perrno)
1778 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1779 req, struct smb_vfs_call_fsync_state);
1780 int err;
1782 if (tevent_req_is_unix_error(req, &err)) {
1783 *perrno = err;
1784 return -1;
1786 return state->retval;
1790 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1791 struct smb_filename *smb_fname)
1793 VFS_FIND(stat);
1794 return handle->fns->stat_fn(handle, smb_fname);
1797 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1798 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1800 VFS_FIND(fstat);
1801 return handle->fns->fstat_fn(handle, fsp, sbuf);
1804 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1805 struct smb_filename *smb_filename)
1807 VFS_FIND(lstat);
1808 return handle->fns->lstat_fn(handle, smb_filename);
1811 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1812 struct files_struct *fsp,
1813 const SMB_STRUCT_STAT *sbuf)
1815 VFS_FIND(get_alloc_size);
1816 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1819 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1820 const struct smb_filename *smb_fname)
1822 VFS_FIND(unlink);
1823 return handle->fns->unlink_fn(handle, smb_fname);
1826 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1827 mode_t mode)
1829 VFS_FIND(chmod);
1830 return handle->fns->chmod_fn(handle, path, mode);
1833 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1834 struct files_struct *fsp, mode_t mode)
1836 VFS_FIND(fchmod);
1837 return handle->fns->fchmod_fn(handle, fsp, mode);
1840 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1841 uid_t uid, gid_t gid)
1843 VFS_FIND(chown);
1844 return handle->fns->chown_fn(handle, path, uid, gid);
1847 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1848 struct files_struct *fsp, uid_t uid, gid_t gid)
1850 VFS_FIND(fchown);
1851 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1854 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1855 uid_t uid, gid_t gid)
1857 VFS_FIND(lchown);
1858 return handle->fns->lchown_fn(handle, path, uid, gid);
1861 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1863 int ret;
1864 bool as_root = false;
1865 const char *path;
1866 char *saved_dir = NULL;
1867 char *parent_dir = NULL;
1868 NTSTATUS status;
1870 if (fsp->fh->fd != -1) {
1871 /* Try fchown. */
1872 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1873 if (ret == 0) {
1874 return NT_STATUS_OK;
1876 if (ret == -1 && errno != ENOSYS) {
1877 return map_nt_error_from_unix(errno);
1881 as_root = (geteuid() == 0);
1883 if (as_root) {
1885 * We are being asked to chown as root. Make
1886 * sure we chdir() into the path to pin it,
1887 * and always act using lchown to ensure we
1888 * don't deref any symbolic links.
1890 const char *final_component = NULL;
1891 struct smb_filename local_fname;
1893 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1894 if (!saved_dir) {
1895 status = map_nt_error_from_unix(errno);
1896 DEBUG(0,("vfs_chown_fsp: failed to get "
1897 "current working directory. Error was %s\n",
1898 strerror(errno)));
1899 return status;
1902 if (!parent_dirname(talloc_tos(),
1903 fsp->fsp_name->base_name,
1904 &parent_dir,
1905 &final_component)) {
1906 return NT_STATUS_NO_MEMORY;
1909 /* cd into the parent dir to pin it. */
1910 ret = vfs_ChDir(fsp->conn, parent_dir);
1911 if (ret == -1) {
1912 return map_nt_error_from_unix(errno);
1915 ZERO_STRUCT(local_fname);
1916 local_fname.base_name = discard_const_p(char, final_component);
1918 /* Must use lstat here. */
1919 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1920 if (ret == -1) {
1921 status = map_nt_error_from_unix(errno);
1922 goto out;
1925 /* Ensure it matches the fsp stat. */
1926 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1927 status = NT_STATUS_ACCESS_DENIED;
1928 goto out;
1930 path = final_component;
1931 } else {
1932 path = fsp->fsp_name->base_name;
1935 if (fsp->posix_open || as_root) {
1936 ret = SMB_VFS_LCHOWN(fsp->conn,
1937 path,
1938 uid, gid);
1939 } else {
1940 ret = SMB_VFS_CHOWN(fsp->conn,
1941 path,
1942 uid, gid);
1945 if (ret == 0) {
1946 status = NT_STATUS_OK;
1947 } else {
1948 status = map_nt_error_from_unix(errno);
1951 out:
1953 if (as_root) {
1954 vfs_ChDir(fsp->conn,saved_dir);
1955 TALLOC_FREE(saved_dir);
1956 TALLOC_FREE(parent_dir);
1958 return status;
1961 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
1963 VFS_FIND(chdir);
1964 return handle->fns->chdir_fn(handle, path);
1967 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
1969 VFS_FIND(getwd);
1970 return handle->fns->getwd_fn(handle);
1973 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
1974 const struct smb_filename *smb_fname,
1975 struct smb_file_time *ft)
1977 VFS_FIND(ntimes);
1978 return handle->fns->ntimes_fn(handle, smb_fname, ft);
1981 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
1982 struct files_struct *fsp, off_t offset)
1984 VFS_FIND(ftruncate);
1985 return handle->fns->ftruncate_fn(handle, fsp, offset);
1988 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
1989 struct files_struct *fsp,
1990 enum vfs_fallocate_mode mode,
1991 off_t offset,
1992 off_t len)
1994 VFS_FIND(fallocate);
1995 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
1998 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
1999 struct files_struct *fsp, uint32 share_mode,
2000 uint32_t access_mask)
2002 VFS_FIND(kernel_flock);
2003 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2004 access_mask);
2007 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2008 struct files_struct *fsp, int leasetype)
2010 VFS_FIND(linux_setlease);
2011 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2014 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
2015 const char *newpath)
2017 VFS_FIND(symlink);
2018 return handle->fns->symlink_fn(handle, oldpath, newpath);
2021 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2022 const char *path, char *buf, size_t bufsiz)
2024 VFS_FIND(readlink);
2025 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
2028 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
2029 const char *newpath)
2031 VFS_FIND(link);
2032 return handle->fns->link_fn(handle, oldpath, newpath);
2035 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
2036 mode_t mode, SMB_DEV_T dev)
2038 VFS_FIND(mknod);
2039 return handle->fns->mknod_fn(handle, path, mode, dev);
2042 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
2044 VFS_FIND(realpath);
2045 return handle->fns->realpath_fn(handle, path);
2048 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
2049 struct sys_notify_context *ctx,
2050 const char *path,
2051 uint32_t *filter,
2052 uint32_t *subdir_filter,
2053 void (*callback)(struct sys_notify_context *ctx,
2054 void *private_data,
2055 struct notify_event *ev),
2056 void *private_data, void *handle_p)
2058 VFS_FIND(notify_watch);
2059 return handle->fns->notify_watch_fn(handle, ctx, path,
2060 filter, subdir_filter, callback,
2061 private_data, handle_p);
2064 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
2065 unsigned int flags)
2067 VFS_FIND(chflags);
2068 return handle->fns->chflags_fn(handle, path, flags);
2071 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2072 const SMB_STRUCT_STAT *sbuf)
2074 VFS_FIND(file_id_create);
2075 return handle->fns->file_id_create_fn(handle, sbuf);
2078 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2079 struct files_struct *fsp,
2080 const char *fname,
2081 TALLOC_CTX *mem_ctx,
2082 unsigned int *num_streams,
2083 struct stream_struct **streams)
2085 VFS_FIND(streaminfo);
2086 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
2087 num_streams, streams);
2090 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2091 const char *path, const char *name,
2092 TALLOC_CTX *mem_ctx, char **found_name)
2094 VFS_FIND(get_real_filename);
2095 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2096 found_name);
2099 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2100 const char *filename)
2102 VFS_FIND(connectpath);
2103 return handle->fns->connectpath_fn(handle, filename);
2106 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2107 struct files_struct *fsp,
2108 struct lock_struct *plock)
2110 VFS_FIND(strict_lock);
2111 return handle->fns->strict_lock_fn(handle, fsp, plock);
2114 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2115 struct files_struct *fsp,
2116 struct lock_struct *plock)
2118 VFS_FIND(strict_unlock);
2119 handle->fns->strict_unlock_fn(handle, fsp, plock);
2122 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2123 const char *name,
2124 enum vfs_translate_direction direction,
2125 TALLOC_CTX *mem_ctx,
2126 char **mapped_name)
2128 VFS_FIND(translate_name);
2129 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2130 mapped_name);
2133 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2134 struct files_struct *fsp,
2135 TALLOC_CTX *ctx,
2136 uint32_t function,
2137 uint16_t req_flags,
2138 const uint8_t *in_data,
2139 uint32_t in_len,
2140 uint8_t **out_data,
2141 uint32_t max_out_len,
2142 uint32_t *out_len)
2144 VFS_FIND(fsctl);
2145 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2146 in_data, in_len, out_data, max_out_len,
2147 out_len);
2150 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2151 struct files_struct *fsp,
2152 uint32 security_info,
2153 struct security_descriptor **ppdesc)
2155 VFS_FIND(fget_nt_acl);
2156 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2157 ppdesc);
2160 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2161 const char *name,
2162 uint32 security_info,
2163 struct security_descriptor **ppdesc)
2165 VFS_FIND(get_nt_acl);
2166 return handle->fns->get_nt_acl_fn(handle, name, security_info, ppdesc);
2169 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2170 struct files_struct *fsp,
2171 uint32 security_info_sent,
2172 const struct security_descriptor *psd)
2174 VFS_FIND(fset_nt_acl);
2175 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2176 psd);
2179 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2180 struct smb_filename *file,
2181 struct security_acl *sacl,
2182 uint32_t access_requested,
2183 uint32_t access_denied)
2185 VFS_FIND(audit_file);
2186 return handle->fns->audit_file_fn(handle,
2187 file,
2188 sacl,
2189 access_requested,
2190 access_denied);
2193 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2194 mode_t mode)
2196 VFS_FIND(chmod_acl);
2197 return handle->fns->chmod_acl_fn(handle, name, mode);
2200 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2201 struct files_struct *fsp, mode_t mode)
2203 VFS_FIND(fchmod_acl);
2204 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2207 int smb_vfs_call_sys_acl_get_entry(struct vfs_handle_struct *handle,
2208 SMB_ACL_T theacl, int entry_id,
2209 SMB_ACL_ENTRY_T *entry_p)
2211 VFS_FIND(sys_acl_get_entry);
2212 return handle->fns->sys_acl_get_entry_fn(handle, theacl, entry_id,
2213 entry_p);
2216 int smb_vfs_call_sys_acl_get_tag_type(struct vfs_handle_struct *handle,
2217 SMB_ACL_ENTRY_T entry_d,
2218 SMB_ACL_TAG_T *tag_type_p)
2220 VFS_FIND(sys_acl_get_tag_type);
2221 return handle->fns->sys_acl_get_tag_type_fn(handle, entry_d,
2222 tag_type_p);
2225 int smb_vfs_call_sys_acl_get_permset(struct vfs_handle_struct *handle,
2226 SMB_ACL_ENTRY_T entry_d,
2227 SMB_ACL_PERMSET_T *permset_p)
2229 VFS_FIND(sys_acl_get_permset);
2230 return handle->fns->sys_acl_get_permset_fn(handle, entry_d, permset_p);
2233 void * smb_vfs_call_sys_acl_get_qualifier(struct vfs_handle_struct *handle,
2234 SMB_ACL_ENTRY_T entry_d)
2236 VFS_FIND(sys_acl_get_qualifier);
2237 return handle->fns->sys_acl_get_qualifier_fn(handle, entry_d);
2240 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2241 const char *path_p,
2242 SMB_ACL_TYPE_T type)
2244 VFS_FIND(sys_acl_get_file);
2245 return handle->fns->sys_acl_get_file_fn(handle, path_p, type);
2248 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2249 struct files_struct *fsp)
2251 VFS_FIND(sys_acl_get_fd);
2252 return handle->fns->sys_acl_get_fd_fn(handle, fsp);
2255 int smb_vfs_call_sys_acl_clear_perms(struct vfs_handle_struct *handle,
2256 SMB_ACL_PERMSET_T permset)
2258 VFS_FIND(sys_acl_clear_perms);
2259 return handle->fns->sys_acl_clear_perms_fn(handle, permset);
2262 int smb_vfs_call_sys_acl_add_perm(struct vfs_handle_struct *handle,
2263 SMB_ACL_PERMSET_T permset,
2264 SMB_ACL_PERM_T perm)
2266 VFS_FIND(sys_acl_add_perm);
2267 return handle->fns->sys_acl_add_perm_fn(handle, permset, perm);
2270 char * smb_vfs_call_sys_acl_to_text(struct vfs_handle_struct *handle,
2271 SMB_ACL_T theacl, ssize_t *plen)
2273 VFS_FIND(sys_acl_to_text);
2274 return handle->fns->sys_acl_to_text_fn(handle, theacl, plen);
2277 SMB_ACL_T smb_vfs_call_sys_acl_init(struct vfs_handle_struct *handle,
2278 int count)
2280 VFS_FIND(sys_acl_init);
2281 return handle->fns->sys_acl_init_fn(handle, count);
2284 int smb_vfs_call_sys_acl_create_entry(struct vfs_handle_struct *handle,
2285 SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2287 VFS_FIND(sys_acl_create_entry);
2288 return handle->fns->sys_acl_create_entry_fn(handle, pacl, pentry);
2291 int smb_vfs_call_sys_acl_set_tag_type(struct vfs_handle_struct *handle,
2292 SMB_ACL_ENTRY_T entry,
2293 SMB_ACL_TAG_T tagtype)
2295 VFS_FIND(sys_acl_set_tag_type);
2296 return handle->fns->sys_acl_set_tag_type_fn(handle, entry, tagtype);
2299 int smb_vfs_call_sys_acl_set_qualifier(struct vfs_handle_struct *handle,
2300 SMB_ACL_ENTRY_T entry, void *qual)
2302 VFS_FIND(sys_acl_set_qualifier);
2303 return handle->fns->sys_acl_set_qualifier_fn(handle, entry, qual);
2306 int smb_vfs_call_sys_acl_set_permset(struct vfs_handle_struct *handle,
2307 SMB_ACL_ENTRY_T entry,
2308 SMB_ACL_PERMSET_T permset)
2310 VFS_FIND(sys_acl_set_permset);
2311 return handle->fns->sys_acl_set_permset_fn(handle, entry, permset);
2314 int smb_vfs_call_sys_acl_valid(struct vfs_handle_struct *handle,
2315 SMB_ACL_T theacl)
2317 VFS_FIND(sys_acl_valid);
2318 return handle->fns->sys_acl_valid_fn(handle, theacl);
2321 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2322 const char *name, SMB_ACL_TYPE_T acltype,
2323 SMB_ACL_T theacl)
2325 VFS_FIND(sys_acl_set_file);
2326 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2329 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2330 struct files_struct *fsp, SMB_ACL_T theacl)
2332 VFS_FIND(sys_acl_set_fd);
2333 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2336 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2337 const char *path)
2339 VFS_FIND(sys_acl_delete_def_file);
2340 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2343 int smb_vfs_call_sys_acl_get_perm(struct vfs_handle_struct *handle,
2344 SMB_ACL_PERMSET_T permset,
2345 SMB_ACL_PERM_T perm)
2347 VFS_FIND(sys_acl_get_perm);
2348 return handle->fns->sys_acl_get_perm_fn(handle, permset, perm);
2351 int smb_vfs_call_sys_acl_free_text(struct vfs_handle_struct *handle,
2352 char *text)
2354 VFS_FIND(sys_acl_free_text);
2355 return handle->fns->sys_acl_free_text_fn(handle, text);
2358 int smb_vfs_call_sys_acl_free_acl(struct vfs_handle_struct *handle,
2359 SMB_ACL_T posix_acl)
2361 VFS_FIND(sys_acl_free_acl);
2362 return handle->fns->sys_acl_free_acl_fn(handle, posix_acl);
2365 int smb_vfs_call_sys_acl_free_qualifier(struct vfs_handle_struct *handle,
2366 void *qualifier, SMB_ACL_TAG_T tagtype)
2368 VFS_FIND(sys_acl_free_qualifier);
2369 return handle->fns->sys_acl_free_qualifier_fn(handle, qualifier,
2370 tagtype);
2373 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2374 const char *path, const char *name, void *value,
2375 size_t size)
2377 VFS_FIND(getxattr);
2378 return handle->fns->getxattr_fn(handle, path, name, value, size);
2381 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2382 struct files_struct *fsp, const char *name,
2383 void *value, size_t size)
2385 VFS_FIND(fgetxattr);
2386 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2389 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2390 const char *path, char *list, size_t size)
2392 VFS_FIND(listxattr);
2393 return handle->fns->listxattr_fn(handle, path, list, size);
2396 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2397 struct files_struct *fsp, char *list,
2398 size_t size)
2400 VFS_FIND(flistxattr);
2401 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2404 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2405 const char *path, const char *name)
2407 VFS_FIND(removexattr);
2408 return handle->fns->removexattr_fn(handle, path, name);
2411 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2412 struct files_struct *fsp, const char *name)
2414 VFS_FIND(fremovexattr);
2415 return handle->fns->fremovexattr_fn(handle, fsp, name);
2418 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2419 const char *name, const void *value, size_t size,
2420 int flags)
2422 VFS_FIND(setxattr);
2423 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2426 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2427 struct files_struct *fsp, const char *name,
2428 const void *value, size_t size, int flags)
2430 VFS_FIND(fsetxattr);
2431 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2434 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2435 struct files_struct *fsp)
2437 VFS_FIND(aio_force);
2438 return handle->fns->aio_force_fn(handle, fsp);
2441 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2442 const struct smb_filename *fname,
2443 SMB_STRUCT_STAT *sbuf)
2445 VFS_FIND(is_offline);
2446 return handle->fns->is_offline_fn(handle, fname, sbuf);
2449 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2450 const struct smb_filename *fname)
2452 VFS_FIND(set_offline);
2453 return handle->fns->set_offline_fn(handle, fname);