s3:libsmb: make use of get_cmdline_auth_info_* helper functions in get_ipc_connect()
[Samba.git] / source3 / smbd / vfs.c
blob35f560b86763ac92db29a7869f6a5d406ce7c455
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 VFS initialisation and support functions
5 Copyright (C) Tim Potter 1999
6 Copyright (C) Alexander Bokovoy 2002
7 Copyright (C) James Peach 2006
8 Copyright (C) Volker Lendecke 2009
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 This work was sponsored by Optifacio Software Services, Inc.
26 #include "includes.h"
27 #include "system/filesys.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "../lib/util/memcache.h"
31 #include "transfer_file.h"
32 #include "ntioctl.h"
33 #include "lib/util/tevent_unix.h"
35 #undef DBGC_CLASS
36 #define DBGC_CLASS DBGC_VFS
38 static_decl_vfs;
40 struct vfs_fsp_data {
41 struct vfs_fsp_data *next;
42 struct vfs_handle_struct *owner;
43 void (*destroy)(void *p_data);
44 void *_dummy_;
45 /* NOTE: This structure contains four pointers so that we can guarantee
46 * that the end of the structure is always both 4-byte and 8-byte aligned.
50 struct vfs_init_function_entry {
51 char *name;
52 struct vfs_init_function_entry *prev, *next;
53 const struct vfs_fn_pointers *fns;
56 /****************************************************************************
57 maintain the list of available backends
58 ****************************************************************************/
60 static struct vfs_init_function_entry *vfs_find_backend_entry(const char *name)
62 struct vfs_init_function_entry *entry = backends;
64 DEBUG(10, ("vfs_find_backend_entry called for %s\n", name));
66 while(entry) {
67 if (strcmp(entry->name, name)==0) return entry;
68 entry = entry->next;
71 return NULL;
74 NTSTATUS smb_register_vfs(int version, const char *name,
75 const struct vfs_fn_pointers *fns)
77 struct vfs_init_function_entry *entry = backends;
79 if ((version != SMB_VFS_INTERFACE_VERSION)) {
80 DEBUG(0, ("Failed to register vfs module.\n"
81 "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
82 "current SMB_VFS_INTERFACE_VERSION is %d.\n"
83 "Please recompile against the current Samba Version!\n",
84 version, SMB_VFS_INTERFACE_VERSION));
85 return NT_STATUS_OBJECT_TYPE_MISMATCH;
88 if (!name || !name[0]) {
89 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
90 return NT_STATUS_INVALID_PARAMETER;
93 if (vfs_find_backend_entry(name)) {
94 DEBUG(0,("VFS module %s already loaded!\n", name));
95 return NT_STATUS_OBJECT_NAME_COLLISION;
98 entry = SMB_XMALLOC_P(struct vfs_init_function_entry);
99 entry->name = smb_xstrdup(name);
100 entry->fns = fns;
102 DLIST_ADD(backends, entry);
103 DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
104 return NT_STATUS_OK;
107 /****************************************************************************
108 initialise default vfs hooks
109 ****************************************************************************/
111 static void vfs_init_default(connection_struct *conn)
113 DEBUG(3, ("Initialising default vfs hooks\n"));
114 vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME);
117 /****************************************************************************
118 initialise custom vfs hooks
119 ****************************************************************************/
121 bool vfs_init_custom(connection_struct *conn, const char *vfs_object)
123 char *module_path = NULL;
124 char *module_name = NULL;
125 char *module_param = NULL, *p;
126 vfs_handle_struct *handle;
127 const struct vfs_init_function_entry *entry;
129 if (!conn||!vfs_object||!vfs_object[0]) {
130 DEBUG(0, ("vfs_init_custom() called with NULL pointer or "
131 "empty vfs_object!\n"));
132 return False;
135 if(!backends) {
136 static_init_vfs;
139 DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
141 module_path = smb_xstrdup(vfs_object);
143 p = strchr_m(module_path, ':');
145 if (p) {
146 *p = 0;
147 module_param = p+1;
148 trim_char(module_param, ' ', ' ');
151 trim_char(module_path, ' ', ' ');
153 module_name = smb_xstrdup(module_path);
155 if ((module_name[0] == '/') &&
156 (strcmp(module_path, DEFAULT_VFS_MODULE_NAME) != 0)) {
159 * Extract the module name from the path. Just use the base
160 * name of the last path component.
163 SAFE_FREE(module_name);
164 module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
166 p = strchr_m(module_name, '.');
168 if (p != NULL) {
169 *p = '\0';
173 /* First, try to load the module with the new module system */
174 entry = vfs_find_backend_entry(module_name);
175 if (!entry) {
176 NTSTATUS status;
178 DEBUG(5, ("vfs module [%s] not loaded - trying to load...\n",
179 vfs_object));
181 status = smb_load_module("vfs", module_path);
182 if (!NT_STATUS_IS_OK(status)) {
183 DEBUG(0, ("error probing vfs module '%s': %s\n",
184 module_path, nt_errstr(status)));
185 goto fail;
188 entry = vfs_find_backend_entry(module_name);
189 if (!entry) {
190 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
191 goto fail;
195 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
197 handle = talloc_zero(conn, vfs_handle_struct);
198 if (!handle) {
199 DEBUG(0,("TALLOC_ZERO() failed!\n"));
200 goto fail;
202 handle->conn = conn;
203 handle->fns = entry->fns;
204 if (module_param) {
205 handle->param = talloc_strdup(conn, module_param);
207 DLIST_ADD(conn->vfs_handles, handle);
209 SAFE_FREE(module_path);
210 SAFE_FREE(module_name);
211 return True;
213 fail:
214 SAFE_FREE(module_path);
215 SAFE_FREE(module_name);
216 return False;
219 /*****************************************************************
220 Allow VFS modules to extend files_struct with VFS-specific state.
221 This will be ok for small numbers of extensions, but might need to
222 be refactored if it becomes more widely used.
223 ******************************************************************/
225 #define EXT_DATA_AREA(e) ((uint8_t *)(e) + sizeof(struct vfs_fsp_data))
227 void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle,
228 files_struct *fsp, size_t ext_size,
229 void (*destroy_fn)(void *p_data))
231 struct vfs_fsp_data *ext;
232 void * ext_data;
234 /* Prevent VFS modules adding multiple extensions. */
235 if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
236 return ext_data;
239 ext = (struct vfs_fsp_data *)TALLOC_ZERO(
240 handle->conn, sizeof(struct vfs_fsp_data) + ext_size);
241 if (ext == NULL) {
242 return NULL;
245 ext->owner = handle;
246 ext->next = fsp->vfs_extension;
247 ext->destroy = destroy_fn;
248 fsp->vfs_extension = ext;
249 return EXT_DATA_AREA(ext);
252 void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
254 struct vfs_fsp_data *curr;
255 struct vfs_fsp_data *prev;
257 for (curr = fsp->vfs_extension, prev = NULL;
258 curr;
259 prev = curr, curr = curr->next) {
260 if (curr->owner == handle) {
261 if (prev) {
262 prev->next = curr->next;
263 } else {
264 fsp->vfs_extension = curr->next;
266 if (curr->destroy) {
267 curr->destroy(EXT_DATA_AREA(curr));
269 TALLOC_FREE(curr);
270 return;
275 void vfs_remove_all_fsp_extensions(files_struct *fsp)
277 struct vfs_fsp_data *curr;
278 struct vfs_fsp_data *next;
280 for (curr = fsp->vfs_extension; curr; curr = next) {
282 next = curr->next;
283 fsp->vfs_extension = next;
285 if (curr->destroy) {
286 curr->destroy(EXT_DATA_AREA(curr));
288 TALLOC_FREE(curr);
292 void *vfs_memctx_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
294 struct vfs_fsp_data *head;
296 for (head = fsp->vfs_extension; head; head = head->next) {
297 if (head->owner == handle) {
298 return head;
302 return NULL;
305 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
307 struct vfs_fsp_data *head;
309 head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
310 if (head != NULL) {
311 return EXT_DATA_AREA(head);
314 return NULL;
317 #undef EXT_DATA_AREA
320 * Ensure this module catches all VFS functions.
322 #ifdef DEVELOPER
323 void smb_vfs_assert_all_fns(const struct vfs_fn_pointers* fns,
324 const char *module)
326 bool missing_fn = false;
327 unsigned int idx;
328 const uintptr_t *end = (const uintptr_t *)(fns + 1);
330 for (idx = 0; ((const uintptr_t *)fns + idx) < end; idx++) {
331 if (*((const uintptr_t *)fns + idx) == 0) {
332 DBG_ERR("VFS function at index %d not implemented "
333 "in module %s\n", idx, module);
334 missing_fn = true;
338 if (missing_fn) {
339 smb_panic("Required VFS function not implemented in module.\n");
342 #else
343 void smb_vfs_assert_all_fns(const struct vfs_fn_pointers* fns,
344 const char *module)
347 #endif
349 /*****************************************************************
350 Generic VFS init.
351 ******************************************************************/
353 bool smbd_vfs_init(connection_struct *conn)
355 const char **vfs_objects;
356 unsigned int i = 0;
357 int j = 0;
359 /* Normal share - initialise with disk access functions */
360 vfs_init_default(conn);
362 /* No need to load vfs modules for printer connections */
363 if (conn->printer) {
364 return True;
367 vfs_objects = lp_vfs_objects(SNUM(conn));
369 /* Override VFS functions if 'vfs object' was not specified*/
370 if (!vfs_objects || !vfs_objects[0])
371 return True;
373 for (i=0; vfs_objects[i] ;) {
374 i++;
377 for (j=i-1; j >= 0; j--) {
378 if (!vfs_init_custom(conn, vfs_objects[j])) {
379 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
380 return False;
383 return True;
386 /*******************************************************************
387 Check if a file exists in the vfs.
388 ********************************************************************/
390 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
392 /* Only return OK if stat was successful and S_ISREG */
393 if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
394 S_ISREG(smb_fname->st.st_ex_mode)) {
395 return NT_STATUS_OK;
398 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
401 /****************************************************************************
402 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
403 ****************************************************************************/
405 ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
407 size_t total=0;
409 while (total < byte_count)
411 ssize_t ret = SMB_VFS_READ(fsp, buf + total,
412 byte_count - total);
414 if (ret == 0) return total;
415 if (ret == -1) {
416 if (errno == EINTR)
417 continue;
418 else
419 return -1;
421 total += ret;
423 return (ssize_t)total;
426 /****************************************************************************
427 Write data to a fd on the vfs.
428 ****************************************************************************/
430 ssize_t vfs_write_data(struct smb_request *req,
431 files_struct *fsp,
432 const char *buffer,
433 size_t N)
435 size_t total=0;
436 ssize_t ret;
438 if (req && req->unread_bytes) {
439 int sockfd = req->xconn->transport.sock;
440 int old_flags;
441 SMB_ASSERT(req->unread_bytes == N);
442 /* VFS_RECVFILE must drain the socket
443 * before returning. */
444 req->unread_bytes = 0;
445 /* Ensure the socket is blocking. */
446 old_flags = fcntl(sockfd, F_GETFL, 0);
447 if (set_blocking(sockfd, true) == -1) {
448 return (ssize_t)-1;
450 ret = SMB_VFS_RECVFILE(sockfd,
451 fsp,
452 (off_t)-1,
454 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
455 return (ssize_t)-1;
457 return ret;
460 while (total < N) {
461 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
463 if (ret == -1)
464 return -1;
465 if (ret == 0)
466 return total;
468 total += ret;
470 return (ssize_t)total;
473 ssize_t vfs_pwrite_data(struct smb_request *req,
474 files_struct *fsp,
475 const char *buffer,
476 size_t N,
477 off_t offset)
479 size_t total=0;
480 ssize_t ret;
482 if (req && req->unread_bytes) {
483 int sockfd = req->xconn->transport.sock;
484 SMB_ASSERT(req->unread_bytes == N);
485 /* VFS_RECVFILE must drain the socket
486 * before returning. */
487 req->unread_bytes = 0;
489 * Leave the socket non-blocking and
490 * use SMB_VFS_RECVFILE. If it returns
491 * EAGAIN || EWOULDBLOCK temporarily set
492 * the socket blocking and retry
493 * the RECVFILE.
495 while (total < N) {
496 ret = SMB_VFS_RECVFILE(sockfd,
497 fsp,
498 offset + total,
499 N - total);
500 if (ret == 0 || (ret == -1 &&
501 (errno == EAGAIN ||
502 errno == EWOULDBLOCK))) {
503 int old_flags;
504 /* Ensure the socket is blocking. */
505 old_flags = fcntl(sockfd, F_GETFL, 0);
506 if (set_blocking(sockfd, true) == -1) {
507 return (ssize_t)-1;
509 ret = SMB_VFS_RECVFILE(sockfd,
510 fsp,
511 offset + total,
512 N - total);
513 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
514 return (ssize_t)-1;
516 if (ret == -1) {
517 return (ssize_t)-1;
519 total += ret;
520 return (ssize_t)total;
522 /* Any other error case. */
523 if (ret == -1) {
524 return ret;
526 total += ret;
528 return (ssize_t)total;
531 while (total < N) {
532 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
533 offset + total);
535 if (ret == -1)
536 return -1;
537 if (ret == 0)
538 return total;
540 total += ret;
542 return (ssize_t)total;
544 /****************************************************************************
545 An allocate file space call using the vfs interface.
546 Allocates space for a file from a filedescriptor.
547 Returns 0 on success, -1 on failure.
548 ****************************************************************************/
550 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
552 int ret;
553 connection_struct *conn = fsp->conn;
554 uint64_t space_avail;
555 uint64_t bsize,dfree,dsize;
556 NTSTATUS status;
559 * Actually try and commit the space on disk....
562 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
563 fsp_str_dbg(fsp), (double)len));
565 if (((off_t)len) < 0) {
566 DEBUG(0,("vfs_allocate_file_space: %s negative len "
567 "requested.\n", fsp_str_dbg(fsp)));
568 errno = EINVAL;
569 return -1;
572 status = vfs_stat_fsp(fsp);
573 if (!NT_STATUS_IS_OK(status)) {
574 return -1;
577 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
578 return 0;
580 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
581 /* Shrink - use ftruncate. */
583 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
584 "size %.0f\n", fsp_str_dbg(fsp),
585 (double)fsp->fsp_name->st.st_ex_size));
587 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
589 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
590 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
591 set_filelen_write_cache(fsp, len);
594 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
596 return ret;
599 /* Grow - we need to test if we have enough space. */
601 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
603 if (lp_strict_allocate(SNUM(fsp->conn))) {
604 /* See if we have a syscall that will allocate beyond
605 end-of-file without changing EOF. */
606 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_FL_KEEP_SIZE,
607 0, len);
608 } else {
609 ret = 0;
612 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
614 if (ret == 0) {
615 /* We changed the allocation size on disk, but not
616 EOF - exactly as required. We're done ! */
617 return 0;
620 if (ret == -1 && errno == ENOSPC) {
621 return -1;
624 len -= fsp->fsp_name->st.st_ex_size;
625 len /= 1024; /* Len is now number of 1k blocks needed. */
626 space_avail =
627 get_dfree_info(conn, fsp->fsp_name, &bsize, &dfree, &dsize);
628 if (space_avail == (uint64_t)-1) {
629 return -1;
632 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
633 "needed blocks = %.0f, space avail = %.0f\n",
634 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
635 (double)space_avail));
637 if (len > space_avail) {
638 errno = ENOSPC;
639 return -1;
642 return 0;
645 /****************************************************************************
646 A vfs set_filelen call.
647 set the length of a file from a filedescriptor.
648 Returns 0 on success, -1 on failure.
649 ****************************************************************************/
651 int vfs_set_filelen(files_struct *fsp, off_t len)
653 int ret;
655 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
657 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
658 fsp_str_dbg(fsp), (double)len));
659 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
660 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
661 set_filelen_write_cache(fsp, len);
662 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
663 FILE_NOTIFY_CHANGE_SIZE
664 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
665 fsp->fsp_name->base_name);
668 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
670 return ret;
673 /****************************************************************************
674 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
675 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
676 as this is also called from the default SMB_VFS_FTRUNCATE code.
677 Always extends the file size.
678 Returns 0 on success, -1 on failure.
679 ****************************************************************************/
681 #define SPARSE_BUF_WRITE_SIZE (32*1024)
683 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
685 ssize_t pwrite_ret;
686 size_t total = 0;
688 if (!sparse_buf) {
689 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
690 if (!sparse_buf) {
691 errno = ENOMEM;
692 return -1;
696 while (total < len) {
697 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
699 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
700 if (pwrite_ret == -1) {
701 int saved_errno = errno;
702 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
703 "%s failed with error %s\n",
704 fsp_str_dbg(fsp), strerror(saved_errno)));
705 errno = saved_errno;
706 return -1;
708 total += pwrite_ret;
711 return 0;
714 /****************************************************************************
715 A vfs fill sparse call.
716 Writes zeros from the end of file to len, if len is greater than EOF.
717 Used only by strict_sync.
718 Returns 0 on success, -1 on failure.
719 ****************************************************************************/
721 int vfs_fill_sparse(files_struct *fsp, off_t len)
723 int ret;
724 NTSTATUS status;
725 off_t offset;
726 size_t num_to_write;
728 status = vfs_stat_fsp(fsp);
729 if (!NT_STATUS_IS_OK(status)) {
730 return -1;
733 if (len <= fsp->fsp_name->st.st_ex_size) {
734 return 0;
737 #ifdef S_ISFIFO
738 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
739 return 0;
741 #endif
743 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
744 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
745 (double)fsp->fsp_name->st.st_ex_size, (double)len,
746 (double)(len - fsp->fsp_name->st.st_ex_size)));
748 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
750 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
752 offset = fsp->fsp_name->st.st_ex_size;
753 num_to_write = len - fsp->fsp_name->st.st_ex_size;
755 /* Only do this on non-stream file handles. */
756 if (fsp->base_fsp == NULL) {
757 /* for allocation try fallocate first. This can fail on some
758 * platforms e.g. when the filesystem doesn't support it and no
759 * emulation is being done by the libc (like on AIX with JFS1). In that
760 * case we do our own emulation. fallocate implementations can
761 * return ENOTSUP or EINVAL in cases like that. */
762 ret = SMB_VFS_FALLOCATE(fsp, 0, offset, num_to_write);
763 if (ret == -1 && errno == ENOSPC) {
764 goto out;
766 if (ret == 0) {
767 goto out;
769 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
770 "error %d. Falling back to slow manual allocation\n", ret));
773 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
775 out:
777 if (ret == 0) {
778 set_filelen_write_cache(fsp, len);
781 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
782 return ret;
785 /****************************************************************************
786 Transfer some data (n bytes) between two file_struct's.
787 ****************************************************************************/
789 static ssize_t vfs_pread_fn(void *file, void *buf, size_t len, off_t offset)
791 struct files_struct *fsp = (struct files_struct *)file;
793 return SMB_VFS_PREAD(fsp, buf, len, offset);
796 static ssize_t vfs_pwrite_fn(void *file, const void *buf, size_t len, off_t offset)
798 struct files_struct *fsp = (struct files_struct *)file;
800 return SMB_VFS_PWRITE(fsp, buf, len, offset);
803 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
805 return transfer_file_internal((void *)in, (void *)out, n,
806 vfs_pread_fn, vfs_pwrite_fn);
809 /*******************************************************************
810 A vfs_readdir wrapper which just returns the file name.
811 ********************************************************************/
813 const char *vfs_readdirname(connection_struct *conn, void *p,
814 SMB_STRUCT_STAT *sbuf, char **talloced)
816 struct dirent *ptr= NULL;
817 const char *dname;
818 char *translated;
819 NTSTATUS status;
821 if (!p)
822 return(NULL);
824 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
825 if (!ptr)
826 return(NULL);
828 dname = ptr->d_name;
831 #ifdef NEXT2
832 if (telldir(p) < 0)
833 return(NULL);
834 #endif
836 #ifdef HAVE_BROKEN_READDIR_NAME
837 /* using /usr/ucb/cc is BAD */
838 dname = dname - 2;
839 #endif
841 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
842 talloc_tos(), &translated);
843 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
844 *talloced = NULL;
845 return dname;
847 *talloced = translated;
848 if (!NT_STATUS_IS_OK(status)) {
849 return NULL;
851 return translated;
854 /*******************************************************************
855 A wrapper for vfs_chdir().
856 ********************************************************************/
858 int vfs_ChDir(connection_struct *conn, const char *path)
860 int ret;
862 if (!LastDir) {
863 LastDir = SMB_STRDUP("");
866 if (ISDOT(path)) {
867 return 0;
870 if (*path == '/' && strcsequal(LastDir,path)) {
871 return 0;
874 DEBUG(4,("vfs_ChDir to %s\n",path));
876 ret = SMB_VFS_CHDIR(conn,path);
877 if (ret == 0) {
878 /* Global cache. */
879 SAFE_FREE(LastDir);
880 LastDir = SMB_STRDUP(path);
882 /* conn cache. */
883 TALLOC_FREE(conn->cwd);
884 conn->cwd = vfs_GetWd(conn, conn);
885 DEBUG(4,("vfs_ChDir got %s\n",conn->cwd));
887 return ret;
890 /*******************************************************************
891 Return the absolute current directory path - given a UNIX pathname.
892 Note that this path is returned in DOS format, not UNIX
893 format. Note this can be called with conn == NULL.
894 ********************************************************************/
896 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
898 char *current_dir = NULL;
899 char *result = NULL;
900 DATA_BLOB cache_value;
901 struct file_id key;
902 struct smb_filename *smb_fname_dot = NULL;
903 struct smb_filename *smb_fname_full = NULL;
905 if (!lp_getwd_cache()) {
906 goto nocache;
909 smb_fname_dot = synthetic_smb_fname(ctx, ".", NULL, NULL, 0);
910 if (smb_fname_dot == NULL) {
911 errno = ENOMEM;
912 goto out;
915 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
917 * Known to fail for root: the directory may be NFS-mounted
918 * and exported with root_squash (so has no root access).
920 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
921 "(NFS problem ?)\n", strerror(errno) ));
922 goto nocache;
925 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
927 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
928 data_blob_const(&key, sizeof(key)),
929 &cache_value)) {
930 goto nocache;
933 SMB_ASSERT((cache_value.length > 0)
934 && (cache_value.data[cache_value.length-1] == '\0'));
936 smb_fname_full = synthetic_smb_fname(ctx, (char *)cache_value.data,
937 NULL, NULL, 0);
938 if (smb_fname_full == NULL) {
939 errno = ENOMEM;
940 goto out;
943 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
944 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
945 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
946 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
948 * Ok, we're done
950 result = talloc_strdup(ctx, smb_fname_full->base_name);
951 if (result == NULL) {
952 errno = ENOMEM;
954 goto out;
957 nocache:
960 * We don't have the information to hand so rely on traditional
961 * methods. The very slow getcwd, which spawns a process on some
962 * systems, or the not quite so bad getwd.
965 current_dir = SMB_VFS_GETWD(conn);
966 if (current_dir == NULL) {
967 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
968 strerror(errno)));
969 goto out;
972 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
973 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
975 memcache_add(smbd_memcache(), GETWD_CACHE,
976 data_blob_const(&key, sizeof(key)),
977 data_blob_const(current_dir,
978 strlen(current_dir)+1));
981 result = talloc_strdup(ctx, current_dir);
982 if (result == NULL) {
983 errno = ENOMEM;
986 out:
987 TALLOC_FREE(smb_fname_dot);
988 TALLOC_FREE(smb_fname_full);
989 SAFE_FREE(current_dir);
990 return result;
993 /*******************************************************************
994 Reduce a file name, removing .. elements and checking that
995 it is below dir in the heirachy. This uses realpath.
996 This function must run as root, and will return names
997 and valid stat structs that can be checked on open.
998 ********************************************************************/
1000 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
1001 const char *fname,
1002 struct smb_request *smbreq)
1004 NTSTATUS status;
1005 TALLOC_CTX *ctx = talloc_tos();
1006 const char *conn_rootdir;
1007 size_t rootdir_len;
1008 char *dir_name = NULL;
1009 const char *last_component = NULL;
1010 char *resolved_name = NULL;
1011 char *saved_dir = NULL;
1012 struct smb_filename *smb_fname_cwd = NULL;
1013 struct privilege_paths *priv_paths = NULL;
1014 int ret;
1016 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
1017 fname,
1018 conn->connectpath));
1021 priv_paths = talloc_zero(smbreq, struct privilege_paths);
1022 if (!priv_paths) {
1023 status = NT_STATUS_NO_MEMORY;
1024 goto err;
1027 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
1028 status = NT_STATUS_NO_MEMORY;
1029 goto err;
1032 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
1033 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
1035 if (priv_paths->parent_name.base_name == NULL ||
1036 priv_paths->file_name.base_name == NULL) {
1037 status = NT_STATUS_NO_MEMORY;
1038 goto err;
1041 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
1042 status = map_nt_error_from_unix(errno);
1043 goto err;
1045 /* Remember where we were. */
1046 saved_dir = vfs_GetWd(ctx, conn);
1047 if (!saved_dir) {
1048 status = map_nt_error_from_unix(errno);
1049 goto err;
1052 /* Go to the parent directory to lock in memory. */
1053 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
1054 status = map_nt_error_from_unix(errno);
1055 goto err;
1058 /* Get the absolute path of the parent directory. */
1059 resolved_name = SMB_VFS_REALPATH(conn,".");
1060 if (!resolved_name) {
1061 status = map_nt_error_from_unix(errno);
1062 goto err;
1065 if (*resolved_name != '/') {
1066 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1067 "doesn't return absolute paths !\n"));
1068 status = NT_STATUS_OBJECT_NAME_INVALID;
1069 goto err;
1072 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1073 priv_paths->parent_name.base_name,
1074 resolved_name));
1076 /* Now check the stat value is the same. */
1077 smb_fname_cwd = synthetic_smb_fname(talloc_tos(), ".", NULL, NULL, 0);
1078 if (smb_fname_cwd == NULL) {
1079 status = NT_STATUS_NO_MEMORY;
1080 goto err;
1083 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1084 status = map_nt_error_from_unix(errno);
1085 goto err;
1088 /* Ensure we're pointing at the same place. */
1089 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1090 DEBUG(0,("check_reduced_name_with_privilege: "
1091 "device/inode/uid/gid on directory %s changed. "
1092 "Denying access !\n",
1093 priv_paths->parent_name.base_name));
1094 status = NT_STATUS_ACCESS_DENIED;
1095 goto err;
1098 /* Ensure we're below the connect path. */
1100 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1101 if (conn_rootdir == NULL) {
1102 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1103 "conn_rootdir\n"));
1104 status = NT_STATUS_ACCESS_DENIED;
1105 goto err;
1108 rootdir_len = strlen(conn_rootdir);
1111 * In the case of rootdir_len == 1, we know that conn_rootdir is
1112 * "/", and we also know that resolved_name starts with a slash.
1113 * So, in this corner case, resolved_name is automatically a
1114 * sub-directory of the conn_rootdir. Thus we can skip the string
1115 * comparison and the next character checks (which are even
1116 * wrong in this case).
1118 if (rootdir_len != 1) {
1119 bool matched;
1121 matched = (strncmp(conn_rootdir, resolved_name,
1122 rootdir_len) == 0);
1124 if (!matched || (resolved_name[rootdir_len] != '/' &&
1125 resolved_name[rootdir_len] != '\0')) {
1126 DEBUG(2, ("check_reduced_name_with_privilege: Bad "
1127 "access attempt: %s is a symlink outside the "
1128 "share path\n",
1129 dir_name));
1130 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1131 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1132 status = NT_STATUS_ACCESS_DENIED;
1133 goto err;
1137 /* Now ensure that the last component either doesn't
1138 exist, or is *NOT* a symlink. */
1140 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1141 if (ret == -1) {
1142 /* Errno must be ENOENT for this be ok. */
1143 if (errno != ENOENT) {
1144 status = map_nt_error_from_unix(errno);
1145 DEBUG(2, ("check_reduced_name_with_privilege: "
1146 "LSTAT on %s failed with %s\n",
1147 priv_paths->file_name.base_name,
1148 nt_errstr(status)));
1149 goto err;
1153 if (VALID_STAT(priv_paths->file_name.st) &&
1154 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1155 DEBUG(2, ("check_reduced_name_with_privilege: "
1156 "Last component %s is a symlink. Denying"
1157 "access.\n",
1158 priv_paths->file_name.base_name));
1159 status = NT_STATUS_ACCESS_DENIED;
1160 goto err;
1163 smbreq->priv_paths = priv_paths;
1164 status = NT_STATUS_OK;
1166 err:
1168 if (saved_dir) {
1169 vfs_ChDir(conn, saved_dir);
1171 SAFE_FREE(resolved_name);
1172 if (!NT_STATUS_IS_OK(status)) {
1173 TALLOC_FREE(priv_paths);
1175 TALLOC_FREE(dir_name);
1176 return status;
1179 /*******************************************************************
1180 Reduce a file name, removing .. elements and checking that
1181 it is below dir in the heirachy. This uses realpath.
1182 ********************************************************************/
1184 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1186 char *resolved_name = NULL;
1187 bool allow_symlinks = true;
1188 bool allow_widelinks = false;
1190 DBG_DEBUG("check_reduced_name [%s] [%s]\n", fname, conn->connectpath);
1192 resolved_name = SMB_VFS_REALPATH(conn,fname);
1194 if (!resolved_name) {
1195 switch (errno) {
1196 case ENOTDIR:
1197 DEBUG(3,("check_reduced_name: Component not a "
1198 "directory in getting realpath for "
1199 "%s\n", fname));
1200 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1201 case ENOENT:
1203 TALLOC_CTX *ctx = talloc_tos();
1204 char *dir_name = NULL;
1205 const char *last_component = NULL;
1206 char *new_name = NULL;
1207 int ret;
1209 /* Last component didn't exist.
1210 Remove it and try and canonicalise
1211 the directory name. */
1212 if (!parent_dirname(ctx, fname,
1213 &dir_name,
1214 &last_component)) {
1215 return NT_STATUS_NO_MEMORY;
1218 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1219 if (!resolved_name) {
1220 NTSTATUS status = map_nt_error_from_unix(errno);
1222 if (errno == ENOENT || errno == ENOTDIR) {
1223 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1226 DEBUG(3,("check_reduce_name: "
1227 "couldn't get realpath for "
1228 "%s (%s)\n",
1229 fname,
1230 nt_errstr(status)));
1231 return status;
1233 ret = asprintf(&new_name, "%s/%s",
1234 resolved_name, last_component);
1235 SAFE_FREE(resolved_name);
1236 if (ret == -1) {
1237 return NT_STATUS_NO_MEMORY;
1239 resolved_name = new_name;
1240 break;
1242 default:
1243 DEBUG(3,("check_reduced_name: couldn't get "
1244 "realpath for %s\n", fname));
1245 return map_nt_error_from_unix(errno);
1249 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1250 resolved_name));
1252 if (*resolved_name != '/') {
1253 DEBUG(0,("check_reduced_name: realpath doesn't return "
1254 "absolute paths !\n"));
1255 SAFE_FREE(resolved_name);
1256 return NT_STATUS_OBJECT_NAME_INVALID;
1259 allow_widelinks = lp_widelinks(SNUM(conn));
1260 allow_symlinks = lp_follow_symlinks(SNUM(conn));
1262 /* Common widelinks and symlinks checks. */
1263 if (!allow_widelinks || !allow_symlinks) {
1264 const char *conn_rootdir;
1265 size_t rootdir_len;
1267 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1268 if (conn_rootdir == NULL) {
1269 DEBUG(2, ("check_reduced_name: Could not get "
1270 "conn_rootdir\n"));
1271 SAFE_FREE(resolved_name);
1272 return NT_STATUS_ACCESS_DENIED;
1275 rootdir_len = strlen(conn_rootdir);
1278 * In the case of rootdir_len == 1, we know that
1279 * conn_rootdir is "/", and we also know that
1280 * resolved_name starts with a slash. So, in this
1281 * corner case, resolved_name is automatically a
1282 * sub-directory of the conn_rootdir. Thus we can skip
1283 * the string comparison and the next character checks
1284 * (which are even wrong in this case).
1286 if (rootdir_len != 1) {
1287 bool matched;
1289 matched = (strncmp(conn_rootdir, resolved_name,
1290 rootdir_len) == 0);
1291 if (!matched || (resolved_name[rootdir_len] != '/' &&
1292 resolved_name[rootdir_len] != '\0')) {
1293 DEBUG(2, ("check_reduced_name: Bad access "
1294 "attempt: %s is a symlink outside the "
1295 "share path\n", fname));
1296 DEBUGADD(2, ("conn_rootdir =%s\n",
1297 conn_rootdir));
1298 DEBUGADD(2, ("resolved_name=%s\n",
1299 resolved_name));
1300 SAFE_FREE(resolved_name);
1301 return NT_STATUS_ACCESS_DENIED;
1305 /* Extra checks if all symlinks are disallowed. */
1306 if (!allow_symlinks) {
1307 /* fname can't have changed in resolved_path. */
1308 const char *p = &resolved_name[rootdir_len];
1310 /* *p can be '\0' if fname was "." */
1311 if (*p == '\0' && ISDOT(fname)) {
1312 goto out;
1315 if (*p != '/') {
1316 DEBUG(2, ("check_reduced_name: logic error (%c) "
1317 "in resolved_name: %s\n",
1319 fname));
1320 SAFE_FREE(resolved_name);
1321 return NT_STATUS_ACCESS_DENIED;
1324 p++;
1325 if (strcmp(fname, p)!=0) {
1326 DEBUG(2, ("check_reduced_name: Bad access "
1327 "attempt: %s is a symlink to %s\n",
1328 fname, p));
1329 SAFE_FREE(resolved_name);
1330 return NT_STATUS_ACCESS_DENIED;
1335 out:
1337 DBG_INFO("%s reduced to %s\n", fname, resolved_name);
1338 SAFE_FREE(resolved_name);
1339 return NT_STATUS_OK;
1343 * XXX: This is temporary and there should be no callers of this once
1344 * smb_filename is plumbed through all path based operations.
1346 * Called when we know stream name parsing has already been done.
1348 int vfs_stat_smb_basename(struct connection_struct *conn,
1349 const struct smb_filename *smb_fname_in,
1350 SMB_STRUCT_STAT *psbuf)
1352 struct smb_filename smb_fname = {
1353 .base_name = discard_const_p(char, smb_fname_in->base_name),
1354 .flags = smb_fname_in->flags
1356 int ret;
1358 if (smb_fname.flags & SMB_FILENAME_POSIX_PATH) {
1359 ret = SMB_VFS_LSTAT(conn, &smb_fname);
1360 } else {
1361 ret = SMB_VFS_STAT(conn, &smb_fname);
1364 if (ret != -1) {
1365 *psbuf = smb_fname.st;
1367 return ret;
1371 * Ensure LSTAT is called for POSIX paths.
1374 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1376 int ret;
1378 if(fsp->fh->fd == -1) {
1379 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1380 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1381 } else {
1382 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1384 if (ret == -1) {
1385 return map_nt_error_from_unix(errno);
1387 } else {
1388 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1389 return map_nt_error_from_unix(errno);
1392 return NT_STATUS_OK;
1396 * Initialize num_streams and streams, then call VFS op streaminfo
1398 NTSTATUS vfs_streaminfo(connection_struct *conn,
1399 struct files_struct *fsp,
1400 const struct smb_filename *smb_fname,
1401 TALLOC_CTX *mem_ctx,
1402 unsigned int *num_streams,
1403 struct stream_struct **streams)
1405 *num_streams = 0;
1406 *streams = NULL;
1407 return SMB_VFS_STREAMINFO(conn,
1408 fsp,
1409 smb_fname,
1410 mem_ctx,
1411 num_streams,
1412 streams);
1416 generate a file_id from a stat structure
1418 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1420 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1423 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1424 const char *service, const char *user)
1426 VFS_FIND(connect);
1427 return handle->fns->connect_fn(handle, service, user);
1430 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1432 VFS_FIND(disconnect);
1433 handle->fns->disconnect_fn(handle);
1436 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1437 const char *path, uint64_t *bsize,
1438 uint64_t *dfree, uint64_t *dsize)
1440 VFS_FIND(disk_free);
1441 return handle->fns->disk_free_fn(handle, path, bsize, dfree, dsize);
1444 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle, const char *path,
1445 enum SMB_QUOTA_TYPE qtype, unid_t id,
1446 SMB_DISK_QUOTA *qt)
1448 VFS_FIND(get_quota);
1449 return handle->fns->get_quota_fn(handle, path, qtype, id, qt);
1452 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1453 enum SMB_QUOTA_TYPE qtype, unid_t id,
1454 SMB_DISK_QUOTA *qt)
1456 VFS_FIND(set_quota);
1457 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1460 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1461 struct files_struct *fsp,
1462 struct shadow_copy_data *shadow_copy_data,
1463 bool labels)
1465 VFS_FIND(get_shadow_copy_data);
1466 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1467 shadow_copy_data,
1468 labels);
1470 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1471 struct vfs_statvfs_struct *statbuf)
1473 VFS_FIND(statvfs);
1474 return handle->fns->statvfs_fn(handle, path, statbuf);
1477 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1478 enum timestamp_set_resolution *p_ts_res)
1480 VFS_FIND(fs_capabilities);
1481 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1484 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1485 struct dfs_GetDFSReferral *r)
1487 VFS_FIND(get_dfs_referrals);
1488 return handle->fns->get_dfs_referrals_fn(handle, r);
1491 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1492 const struct smb_filename *smb_fname,
1493 const char *mask,
1494 uint32_t attributes)
1496 VFS_FIND(opendir);
1497 return handle->fns->opendir_fn(handle, smb_fname, mask, attributes);
1500 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1501 struct files_struct *fsp,
1502 const char *mask,
1503 uint32_t attributes)
1505 VFS_FIND(fdopendir);
1506 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1509 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1510 DIR *dirp,
1511 SMB_STRUCT_STAT *sbuf)
1513 VFS_FIND(readdir);
1514 return handle->fns->readdir_fn(handle, dirp, sbuf);
1517 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1518 DIR *dirp, long offset)
1520 VFS_FIND(seekdir);
1521 handle->fns->seekdir_fn(handle, dirp, offset);
1524 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1525 DIR *dirp)
1527 VFS_FIND(telldir);
1528 return handle->fns->telldir_fn(handle, dirp);
1531 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1532 DIR *dirp)
1534 VFS_FIND(rewind_dir);
1535 handle->fns->rewind_dir_fn(handle, dirp);
1538 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle,
1539 const struct smb_filename *smb_fname,
1540 mode_t mode)
1542 VFS_FIND(mkdir);
1543 return handle->fns->mkdir_fn(handle, smb_fname, mode);
1546 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle,
1547 const struct smb_filename *smb_fname)
1549 VFS_FIND(rmdir);
1550 return handle->fns->rmdir_fn(handle, smb_fname);
1553 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1554 DIR *dir)
1556 VFS_FIND(closedir);
1557 return handle->fns->closedir_fn(handle, dir);
1560 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1561 DIR *dirp)
1563 VFS_FIND(init_search_op);
1564 handle->fns->init_search_op_fn(handle, dirp);
1567 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1568 struct smb_filename *smb_fname, struct files_struct *fsp,
1569 int flags, mode_t mode)
1571 VFS_FIND(open);
1572 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1575 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1576 struct smb_request *req,
1577 uint16_t root_dir_fid,
1578 struct smb_filename *smb_fname,
1579 uint32_t access_mask,
1580 uint32_t share_access,
1581 uint32_t create_disposition,
1582 uint32_t create_options,
1583 uint32_t file_attributes,
1584 uint32_t oplock_request,
1585 struct smb2_lease *lease,
1586 uint64_t allocation_size,
1587 uint32_t private_flags,
1588 struct security_descriptor *sd,
1589 struct ea_list *ea_list,
1590 files_struct **result,
1591 int *pinfo,
1592 const struct smb2_create_blobs *in_context_blobs,
1593 struct smb2_create_blobs *out_context_blobs)
1595 VFS_FIND(create_file);
1596 return handle->fns->create_file_fn(
1597 handle, req, root_dir_fid, smb_fname, access_mask,
1598 share_access, create_disposition, create_options,
1599 file_attributes, oplock_request, lease, allocation_size,
1600 private_flags, sd, ea_list,
1601 result, pinfo, in_context_blobs, out_context_blobs);
1604 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1605 struct files_struct *fsp)
1607 VFS_FIND(close);
1608 return handle->fns->close_fn(handle, fsp);
1611 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1612 struct files_struct *fsp, void *data, size_t n)
1614 VFS_FIND(read);
1615 return handle->fns->read_fn(handle, fsp, data, n);
1618 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1619 struct files_struct *fsp, void *data, size_t n,
1620 off_t offset)
1622 VFS_FIND(pread);
1623 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1626 struct smb_vfs_call_pread_state {
1627 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1628 ssize_t retval;
1629 struct vfs_aio_state vfs_aio_state;
1632 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1634 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1635 TALLOC_CTX *mem_ctx,
1636 struct tevent_context *ev,
1637 struct files_struct *fsp,
1638 void *data,
1639 size_t n, off_t offset)
1641 struct tevent_req *req, *subreq;
1642 struct smb_vfs_call_pread_state *state;
1644 req = tevent_req_create(mem_ctx, &state,
1645 struct smb_vfs_call_pread_state);
1646 if (req == NULL) {
1647 return NULL;
1649 VFS_FIND(pread_send);
1650 state->recv_fn = handle->fns->pread_recv_fn;
1652 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1653 offset);
1654 if (tevent_req_nomem(subreq, req)) {
1655 return tevent_req_post(req, ev);
1657 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1658 return req;
1661 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1663 struct tevent_req *req = tevent_req_callback_data(
1664 subreq, struct tevent_req);
1665 struct smb_vfs_call_pread_state *state = tevent_req_data(
1666 req, struct smb_vfs_call_pread_state);
1668 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1669 TALLOC_FREE(subreq);
1670 if (state->retval == -1) {
1671 tevent_req_error(req, state->vfs_aio_state.error);
1672 return;
1674 tevent_req_done(req);
1677 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req,
1678 struct vfs_aio_state *vfs_aio_state)
1680 struct smb_vfs_call_pread_state *state = tevent_req_data(
1681 req, struct smb_vfs_call_pread_state);
1683 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1684 return -1;
1686 *vfs_aio_state = state->vfs_aio_state;
1687 return state->retval;
1690 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1691 struct files_struct *fsp, const void *data,
1692 size_t n)
1694 VFS_FIND(write);
1695 return handle->fns->write_fn(handle, fsp, data, n);
1698 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1699 struct files_struct *fsp, const void *data,
1700 size_t n, off_t offset)
1702 VFS_FIND(pwrite);
1703 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1706 struct smb_vfs_call_pwrite_state {
1707 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1708 ssize_t retval;
1709 struct vfs_aio_state vfs_aio_state;
1712 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1714 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1715 TALLOC_CTX *mem_ctx,
1716 struct tevent_context *ev,
1717 struct files_struct *fsp,
1718 const void *data,
1719 size_t n, off_t offset)
1721 struct tevent_req *req, *subreq;
1722 struct smb_vfs_call_pwrite_state *state;
1724 req = tevent_req_create(mem_ctx, &state,
1725 struct smb_vfs_call_pwrite_state);
1726 if (req == NULL) {
1727 return NULL;
1729 VFS_FIND(pwrite_send);
1730 state->recv_fn = handle->fns->pwrite_recv_fn;
1732 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1733 offset);
1734 if (tevent_req_nomem(subreq, req)) {
1735 return tevent_req_post(req, ev);
1737 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1738 return req;
1741 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1743 struct tevent_req *req = tevent_req_callback_data(
1744 subreq, struct tevent_req);
1745 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1746 req, struct smb_vfs_call_pwrite_state);
1748 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1749 TALLOC_FREE(subreq);
1750 if (state->retval == -1) {
1751 tevent_req_error(req, state->vfs_aio_state.error);
1752 return;
1754 tevent_req_done(req);
1757 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req,
1758 struct vfs_aio_state *vfs_aio_state)
1760 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1761 req, struct smb_vfs_call_pwrite_state);
1763 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1764 return -1;
1766 *vfs_aio_state = state->vfs_aio_state;
1767 return state->retval;
1770 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1771 struct files_struct *fsp, off_t offset,
1772 int whence)
1774 VFS_FIND(lseek);
1775 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1778 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1779 files_struct *fromfsp, const DATA_BLOB *header,
1780 off_t offset, size_t count)
1782 VFS_FIND(sendfile);
1783 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1784 count);
1787 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1788 files_struct *tofsp, off_t offset,
1789 size_t count)
1791 VFS_FIND(recvfile);
1792 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1795 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1796 const struct smb_filename *smb_fname_src,
1797 const struct smb_filename *smb_fname_dst)
1799 VFS_FIND(rename);
1800 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1803 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1804 struct files_struct *fsp)
1806 VFS_FIND(fsync);
1807 return handle->fns->fsync_fn(handle, fsp);
1810 struct smb_vfs_call_fsync_state {
1811 int (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1812 int retval;
1813 struct vfs_aio_state vfs_aio_state;
1816 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1818 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1819 TALLOC_CTX *mem_ctx,
1820 struct tevent_context *ev,
1821 struct files_struct *fsp)
1823 struct tevent_req *req, *subreq;
1824 struct smb_vfs_call_fsync_state *state;
1826 req = tevent_req_create(mem_ctx, &state,
1827 struct smb_vfs_call_fsync_state);
1828 if (req == NULL) {
1829 return NULL;
1831 VFS_FIND(fsync_send);
1832 state->recv_fn = handle->fns->fsync_recv_fn;
1834 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1835 if (tevent_req_nomem(subreq, req)) {
1836 return tevent_req_post(req, ev);
1838 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1839 return req;
1842 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1844 struct tevent_req *req = tevent_req_callback_data(
1845 subreq, struct tevent_req);
1846 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1847 req, struct smb_vfs_call_fsync_state);
1849 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1850 TALLOC_FREE(subreq);
1851 if (state->retval == -1) {
1852 tevent_req_error(req, state->vfs_aio_state.error);
1853 return;
1855 tevent_req_done(req);
1858 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state)
1860 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1861 req, struct smb_vfs_call_fsync_state);
1863 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1864 return -1;
1866 *vfs_aio_state = state->vfs_aio_state;
1867 return state->retval;
1871 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1872 struct smb_filename *smb_fname)
1874 VFS_FIND(stat);
1875 return handle->fns->stat_fn(handle, smb_fname);
1878 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1879 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1881 VFS_FIND(fstat);
1882 return handle->fns->fstat_fn(handle, fsp, sbuf);
1885 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1886 struct smb_filename *smb_filename)
1888 VFS_FIND(lstat);
1889 return handle->fns->lstat_fn(handle, smb_filename);
1892 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1893 struct files_struct *fsp,
1894 const SMB_STRUCT_STAT *sbuf)
1896 VFS_FIND(get_alloc_size);
1897 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1900 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1901 const struct smb_filename *smb_fname)
1903 VFS_FIND(unlink);
1904 return handle->fns->unlink_fn(handle, smb_fname);
1907 int smb_vfs_call_chmod(struct vfs_handle_struct *handle,
1908 const struct smb_filename *smb_fname,
1909 mode_t mode)
1911 VFS_FIND(chmod);
1912 return handle->fns->chmod_fn(handle, smb_fname, mode);
1915 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1916 struct files_struct *fsp, mode_t mode)
1918 VFS_FIND(fchmod);
1919 return handle->fns->fchmod_fn(handle, fsp, mode);
1922 int smb_vfs_call_chown(struct vfs_handle_struct *handle,
1923 const struct smb_filename *smb_fname,
1924 uid_t uid,
1925 gid_t gid)
1927 VFS_FIND(chown);
1928 return handle->fns->chown_fn(handle, smb_fname, uid, gid);
1931 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1932 struct files_struct *fsp, uid_t uid, gid_t gid)
1934 VFS_FIND(fchown);
1935 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1938 int smb_vfs_call_lchown(struct vfs_handle_struct *handle,
1939 const struct smb_filename *smb_fname,
1940 uid_t uid,
1941 gid_t gid)
1943 VFS_FIND(lchown);
1944 return handle->fns->lchown_fn(handle, smb_fname, uid, gid);
1947 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1949 int ret;
1950 bool as_root = false;
1951 NTSTATUS status;
1953 if (fsp->fh->fd != -1) {
1954 /* Try fchown. */
1955 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1956 if (ret == 0) {
1957 return NT_STATUS_OK;
1959 if (ret == -1 && errno != ENOSYS) {
1960 return map_nt_error_from_unix(errno);
1964 as_root = (geteuid() == 0);
1966 if (as_root) {
1968 * We are being asked to chown as root. Make
1969 * sure we chdir() into the path to pin it,
1970 * and always act using lchown to ensure we
1971 * don't deref any symbolic links.
1973 char *saved_dir = NULL;
1974 char *parent_dir = NULL;
1975 const char *final_component = NULL;
1976 struct smb_filename *local_smb_fname = NULL;
1978 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1979 if (!saved_dir) {
1980 status = map_nt_error_from_unix(errno);
1981 DEBUG(0,("vfs_chown_fsp: failed to get "
1982 "current working directory. Error was %s\n",
1983 strerror(errno)));
1984 return status;
1987 if (!parent_dirname(talloc_tos(),
1988 fsp->fsp_name->base_name,
1989 &parent_dir,
1990 &final_component)) {
1991 return NT_STATUS_NO_MEMORY;
1994 /* cd into the parent dir to pin it. */
1995 ret = vfs_ChDir(fsp->conn, parent_dir);
1996 if (ret == -1) {
1997 return map_nt_error_from_unix(errno);
2000 local_smb_fname = synthetic_smb_fname(talloc_tos(),
2001 final_component,
2002 NULL,
2003 NULL,
2004 fsp->fsp_name->flags);
2005 if (local_smb_fname == NULL) {
2006 status = NT_STATUS_NO_MEMORY;
2007 goto out;
2010 /* Must use lstat here. */
2011 ret = SMB_VFS_LSTAT(fsp->conn, local_smb_fname);
2012 if (ret == -1) {
2013 status = map_nt_error_from_unix(errno);
2014 goto out;
2017 /* Ensure it matches the fsp stat. */
2018 if (!check_same_stat(&local_smb_fname->st,
2019 &fsp->fsp_name->st)) {
2020 status = NT_STATUS_ACCESS_DENIED;
2021 goto out;
2024 ret = SMB_VFS_LCHOWN(fsp->conn,
2025 local_smb_fname,
2026 uid, gid);
2028 if (ret == 0) {
2029 status = NT_STATUS_OK;
2030 } else {
2031 status = map_nt_error_from_unix(errno);
2034 out:
2036 vfs_ChDir(fsp->conn,saved_dir);
2037 TALLOC_FREE(local_smb_fname);
2038 TALLOC_FREE(saved_dir);
2039 TALLOC_FREE(parent_dir);
2041 return status;
2044 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
2045 ret = SMB_VFS_LCHOWN(fsp->conn,
2046 fsp->fsp_name,
2047 uid, gid);
2048 } else {
2049 ret = SMB_VFS_CHOWN(fsp->conn,
2050 fsp->fsp_name,
2051 uid, gid);
2054 if (ret == 0) {
2055 status = NT_STATUS_OK;
2056 } else {
2057 status = map_nt_error_from_unix(errno);
2059 return status;
2062 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
2064 VFS_FIND(chdir);
2065 return handle->fns->chdir_fn(handle, path);
2068 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
2070 VFS_FIND(getwd);
2071 return handle->fns->getwd_fn(handle);
2074 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
2075 const struct smb_filename *smb_fname,
2076 struct smb_file_time *ft)
2078 VFS_FIND(ntimes);
2079 return handle->fns->ntimes_fn(handle, smb_fname, ft);
2082 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2083 struct files_struct *fsp, off_t offset)
2085 VFS_FIND(ftruncate);
2086 return handle->fns->ftruncate_fn(handle, fsp, offset);
2089 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2090 struct files_struct *fsp,
2091 uint32_t mode,
2092 off_t offset,
2093 off_t len)
2095 VFS_FIND(fallocate);
2096 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2099 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2100 struct files_struct *fsp, uint32_t share_mode,
2101 uint32_t access_mask)
2103 VFS_FIND(kernel_flock);
2104 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2105 access_mask);
2108 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2109 struct files_struct *fsp, int leasetype)
2111 VFS_FIND(linux_setlease);
2112 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2115 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
2116 const char *newpath)
2118 VFS_FIND(symlink);
2119 return handle->fns->symlink_fn(handle, oldpath, newpath);
2122 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2123 const char *path, char *buf, size_t bufsiz)
2125 VFS_FIND(readlink);
2126 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
2129 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
2130 const char *newpath)
2132 VFS_FIND(link);
2133 return handle->fns->link_fn(handle, oldpath, newpath);
2136 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
2137 mode_t mode, SMB_DEV_T dev)
2139 VFS_FIND(mknod);
2140 return handle->fns->mknod_fn(handle, path, mode, dev);
2143 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
2145 VFS_FIND(realpath);
2146 return handle->fns->realpath_fn(handle, path);
2149 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
2150 unsigned int flags)
2152 VFS_FIND(chflags);
2153 return handle->fns->chflags_fn(handle, path, flags);
2156 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2157 const SMB_STRUCT_STAT *sbuf)
2159 VFS_FIND(file_id_create);
2160 return handle->fns->file_id_create_fn(handle, sbuf);
2163 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2164 struct files_struct *fsp,
2165 const struct smb_filename *smb_fname,
2166 TALLOC_CTX *mem_ctx,
2167 unsigned int *num_streams,
2168 struct stream_struct **streams)
2170 VFS_FIND(streaminfo);
2171 return handle->fns->streaminfo_fn(handle, fsp, smb_fname, mem_ctx,
2172 num_streams, streams);
2175 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2176 const char *path, const char *name,
2177 TALLOC_CTX *mem_ctx, char **found_name)
2179 VFS_FIND(get_real_filename);
2180 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2181 found_name);
2184 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2185 const char *filename)
2187 VFS_FIND(connectpath);
2188 return handle->fns->connectpath_fn(handle, filename);
2191 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2192 struct files_struct *fsp,
2193 struct lock_struct *plock)
2195 VFS_FIND(strict_lock);
2196 return handle->fns->strict_lock_fn(handle, fsp, plock);
2199 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2200 struct files_struct *fsp,
2201 struct lock_struct *plock)
2203 VFS_FIND(strict_unlock);
2204 handle->fns->strict_unlock_fn(handle, fsp, plock);
2207 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2208 const char *name,
2209 enum vfs_translate_direction direction,
2210 TALLOC_CTX *mem_ctx,
2211 char **mapped_name)
2213 VFS_FIND(translate_name);
2214 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2215 mapped_name);
2218 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2219 struct files_struct *fsp,
2220 TALLOC_CTX *ctx,
2221 uint32_t function,
2222 uint16_t req_flags,
2223 const uint8_t *in_data,
2224 uint32_t in_len,
2225 uint8_t **out_data,
2226 uint32_t max_out_len,
2227 uint32_t *out_len)
2229 VFS_FIND(fsctl);
2230 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2231 in_data, in_len, out_data, max_out_len,
2232 out_len);
2235 NTSTATUS smb_vfs_call_get_dos_attributes(struct vfs_handle_struct *handle,
2236 struct smb_filename *smb_fname,
2237 uint32_t *dosmode)
2239 VFS_FIND(get_dos_attributes);
2240 return handle->fns->get_dos_attributes_fn(handle, smb_fname, dosmode);
2243 NTSTATUS smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct *handle,
2244 struct files_struct *fsp,
2245 uint32_t *dosmode)
2247 VFS_FIND(fget_dos_attributes);
2248 return handle->fns->fget_dos_attributes_fn(handle, fsp, dosmode);
2251 NTSTATUS smb_vfs_call_set_dos_attributes(struct vfs_handle_struct *handle,
2252 const struct smb_filename *smb_fname,
2253 uint32_t dosmode)
2255 VFS_FIND(set_dos_attributes);
2256 return handle->fns->set_dos_attributes_fn(handle, smb_fname, dosmode);
2259 NTSTATUS smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct *handle,
2260 struct files_struct *fsp,
2261 uint32_t dosmode)
2263 VFS_FIND(set_dos_attributes);
2264 return handle->fns->fset_dos_attributes_fn(handle, fsp, dosmode);
2267 struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle,
2268 TALLOC_CTX *mem_ctx,
2269 struct tevent_context *ev,
2270 struct files_struct *src_fsp,
2271 off_t src_off,
2272 struct files_struct *dest_fsp,
2273 off_t dest_off,
2274 off_t num)
2276 VFS_FIND(copy_chunk_send);
2277 return handle->fns->copy_chunk_send_fn(handle, mem_ctx, ev, src_fsp,
2278 src_off, dest_fsp, dest_off, num);
2281 NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,
2282 struct tevent_req *req,
2283 off_t *copied)
2285 VFS_FIND(copy_chunk_recv);
2286 return handle->fns->copy_chunk_recv_fn(handle, req, copied);
2289 NTSTATUS smb_vfs_call_get_compression(vfs_handle_struct *handle,
2290 TALLOC_CTX *mem_ctx,
2291 struct files_struct *fsp,
2292 struct smb_filename *smb_fname,
2293 uint16_t *_compression_fmt)
2295 VFS_FIND(get_compression);
2296 return handle->fns->get_compression_fn(handle, mem_ctx, fsp, smb_fname,
2297 _compression_fmt);
2300 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2301 TALLOC_CTX *mem_ctx,
2302 struct files_struct *fsp,
2303 uint16_t compression_fmt)
2305 VFS_FIND(set_compression);
2306 return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2307 compression_fmt);
2310 NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
2311 TALLOC_CTX *mem_ctx,
2312 const char *service_path,
2313 char **base_volume)
2315 VFS_FIND(snap_check_path);
2316 return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path,
2317 base_volume);
2320 NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle,
2321 TALLOC_CTX *mem_ctx,
2322 const char *base_volume,
2323 time_t *tstamp,
2324 bool rw,
2325 char **base_path,
2326 char **snap_path)
2328 VFS_FIND(snap_create);
2329 return handle->fns->snap_create_fn(handle, mem_ctx, base_volume, tstamp,
2330 rw, base_path, snap_path);
2333 NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle,
2334 TALLOC_CTX *mem_ctx,
2335 char *base_path,
2336 char *snap_path)
2338 VFS_FIND(snap_delete);
2339 return handle->fns->snap_delete_fn(handle, mem_ctx, base_path,
2340 snap_path);
2343 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2344 struct files_struct *fsp,
2345 uint32_t security_info,
2346 TALLOC_CTX *mem_ctx,
2347 struct security_descriptor **ppdesc)
2349 VFS_FIND(fget_nt_acl);
2350 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2351 mem_ctx, ppdesc);
2354 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2355 const struct smb_filename *smb_fname,
2356 uint32_t security_info,
2357 TALLOC_CTX *mem_ctx,
2358 struct security_descriptor **ppdesc)
2360 VFS_FIND(get_nt_acl);
2361 return handle->fns->get_nt_acl_fn(handle,
2362 smb_fname,
2363 security_info,
2364 mem_ctx,
2365 ppdesc);
2368 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2369 struct files_struct *fsp,
2370 uint32_t security_info_sent,
2371 const struct security_descriptor *psd)
2373 VFS_FIND(fset_nt_acl);
2374 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2375 psd);
2378 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2379 struct smb_filename *file,
2380 struct security_acl *sacl,
2381 uint32_t access_requested,
2382 uint32_t access_denied)
2384 VFS_FIND(audit_file);
2385 return handle->fns->audit_file_fn(handle,
2386 file,
2387 sacl,
2388 access_requested,
2389 access_denied);
2392 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle,
2393 const struct smb_filename *smb_fname,
2394 mode_t mode)
2396 VFS_FIND(chmod_acl);
2397 return handle->fns->chmod_acl_fn(handle, smb_fname, mode);
2400 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2401 struct files_struct *fsp, mode_t mode)
2403 VFS_FIND(fchmod_acl);
2404 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2407 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2408 const char *path_p,
2409 SMB_ACL_TYPE_T type,
2410 TALLOC_CTX *mem_ctx)
2412 VFS_FIND(sys_acl_get_file);
2413 return handle->fns->sys_acl_get_file_fn(handle, path_p, type, mem_ctx);
2416 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2417 struct files_struct *fsp,
2418 TALLOC_CTX *mem_ctx)
2420 VFS_FIND(sys_acl_get_fd);
2421 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2424 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2425 const char *path_p,
2426 TALLOC_CTX *mem_ctx,
2427 char **blob_description,
2428 DATA_BLOB *blob)
2430 VFS_FIND(sys_acl_blob_get_file);
2431 return handle->fns->sys_acl_blob_get_file_fn(handle, path_p, mem_ctx, blob_description, blob);
2434 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2435 struct files_struct *fsp,
2436 TALLOC_CTX *mem_ctx,
2437 char **blob_description,
2438 DATA_BLOB *blob)
2440 VFS_FIND(sys_acl_blob_get_fd);
2441 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2444 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2445 const char *name, SMB_ACL_TYPE_T acltype,
2446 SMB_ACL_T theacl)
2448 VFS_FIND(sys_acl_set_file);
2449 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2452 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2453 struct files_struct *fsp, SMB_ACL_T theacl)
2455 VFS_FIND(sys_acl_set_fd);
2456 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2459 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2460 const char *path)
2462 VFS_FIND(sys_acl_delete_def_file);
2463 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2466 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2467 const char *path, const char *name, void *value,
2468 size_t size)
2470 VFS_FIND(getxattr);
2471 return handle->fns->getxattr_fn(handle, path, name, value, size);
2474 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2475 struct files_struct *fsp, const char *name,
2476 void *value, size_t size)
2478 VFS_FIND(fgetxattr);
2479 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2482 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2483 const char *path, char *list, size_t size)
2485 VFS_FIND(listxattr);
2486 return handle->fns->listxattr_fn(handle, path, list, size);
2489 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2490 struct files_struct *fsp, char *list,
2491 size_t size)
2493 VFS_FIND(flistxattr);
2494 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2497 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2498 const char *path, const char *name)
2500 VFS_FIND(removexattr);
2501 return handle->fns->removexattr_fn(handle, path, name);
2504 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2505 struct files_struct *fsp, const char *name)
2507 VFS_FIND(fremovexattr);
2508 return handle->fns->fremovexattr_fn(handle, fsp, name);
2511 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2512 const char *name, const void *value, size_t size,
2513 int flags)
2515 VFS_FIND(setxattr);
2516 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2519 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2520 struct files_struct *fsp, const char *name,
2521 const void *value, size_t size, int flags)
2523 VFS_FIND(fsetxattr);
2524 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2527 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2528 struct files_struct *fsp)
2530 VFS_FIND(aio_force);
2531 return handle->fns->aio_force_fn(handle, fsp);
2534 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2535 struct files_struct *fsp,
2536 TALLOC_CTX *mem_ctx,
2537 DATA_BLOB *cookie)
2539 VFS_FIND(durable_cookie);
2540 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2543 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2544 struct files_struct *fsp,
2545 const DATA_BLOB old_cookie,
2546 TALLOC_CTX *mem_ctx,
2547 DATA_BLOB *new_cookie)
2549 VFS_FIND(durable_disconnect);
2550 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2551 mem_ctx, new_cookie);
2554 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2555 struct smb_request *smb1req,
2556 struct smbXsrv_open *op,
2557 const DATA_BLOB old_cookie,
2558 TALLOC_CTX *mem_ctx,
2559 struct files_struct **fsp,
2560 DATA_BLOB *new_cookie)
2562 VFS_FIND(durable_reconnect);
2563 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2564 old_cookie, mem_ctx, fsp,
2565 new_cookie);
2568 NTSTATUS smb_vfs_call_readdir_attr(struct vfs_handle_struct *handle,
2569 const struct smb_filename *fname,
2570 TALLOC_CTX *mem_ctx,
2571 struct readdir_attr_data **attr_data)
2573 VFS_FIND(readdir_attr);
2574 return handle->fns->readdir_attr_fn(handle, fname, mem_ctx, attr_data);