CVE-2018-1050: s3: RPC: spoolss server. Protect against null pointer derefs.
[Samba.git] / source3 / smbd / vfs.c
blob59702203612e4ec5d61d3c828204b3ad63455b40
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(NULL);
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 struct smb_filename *smb_fname)
860 int ret;
861 int saved_errno = 0;
862 struct smb_filename *saved_cwd = NULL;
864 if (!LastDir) {
865 LastDir = SMB_STRDUP("");
868 if (ISDOT(smb_fname->base_name)) {
869 return 0;
872 if (*smb_fname->base_name == '/' &&
873 strcsequal(LastDir,smb_fname->base_name)) {
874 return 0;
877 if (conn->cwd_fname != NULL) {
879 * Save off where we are in case we need to return
880 * on vfs_GetWd() failure after successful SMB_VFS_CHDIR().
882 saved_cwd = cp_smb_filename(conn, conn->cwd_fname);
883 if (saved_cwd == NULL) {
884 return -1;
888 DEBUG(4,("vfs_ChDir to %s\n", smb_fname->base_name));
890 ret = SMB_VFS_CHDIR(conn, smb_fname);
891 if (ret != 0) {
892 saved_errno = errno;
893 TALLOC_FREE(saved_cwd);
894 errno = saved_errno;
895 return -1;
899 * Always replace conn->cwd_fname. We
900 * don't know if it's been modified by
901 * VFS modules in the stack.
904 /* conn cache. */
905 TALLOC_FREE(conn->cwd_fname);
906 conn->cwd_fname = vfs_GetWd(conn, conn);
907 if (conn->cwd_fname == NULL) {
909 * vfs_GetWd() failed.
910 * We must be able to read cwd.
911 * Return to original directory
912 * and return -1.
914 saved_errno = errno;
916 if (saved_cwd == NULL) {
918 * Failed on the very first chdir()+getwd()
919 * for this connection. We can't
920 * continue.
922 smb_panic("conn->cwd getwd failed\n");
923 /* NOTREACHED */
924 return -1;
927 /* Return to the previous $cwd. */
928 ret = SMB_VFS_CHDIR(conn, saved_cwd);
929 if (ret != 0) {
930 smb_panic("conn->cwd getwd failed\n");
931 /* NOTREACHED */
932 return -1;
934 /* Restore original conn->cwd_fname. */
935 conn->cwd_fname = saved_cwd;
936 errno = saved_errno;
937 /* And fail the chdir(). */
938 return -1;
941 /* vfs_GetWd() succeeded. */
942 /* Replace global cache. */
943 SAFE_FREE(LastDir);
944 LastDir = SMB_STRDUP(smb_fname->base_name);
946 DEBUG(4,("vfs_ChDir got %s\n", conn->cwd_fname->base_name));
948 TALLOC_FREE(saved_cwd);
949 if (saved_errno != 0) {
950 errno = saved_errno;
952 return ret;
955 /*******************************************************************
956 Return the absolute current directory path - given a UNIX pathname.
957 Note that this path is returned in DOS format, not UNIX
958 format. Note this can be called with conn == NULL.
959 ********************************************************************/
961 struct smb_filename *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
963 struct smb_filename *current_dir_fname = NULL;
964 struct file_id key;
965 struct smb_filename *smb_fname_dot = NULL;
966 struct smb_filename *smb_fname_full = NULL;
967 struct smb_filename *result = NULL;
969 if (!lp_getwd_cache()) {
970 goto nocache;
973 smb_fname_dot = synthetic_smb_fname(ctx, ".", NULL, NULL, 0);
974 if (smb_fname_dot == NULL) {
975 errno = ENOMEM;
976 goto out;
979 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
981 * Known to fail for root: the directory may be NFS-mounted
982 * and exported with root_squash (so has no root access).
984 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
985 "(NFS problem ?)\n", strerror(errno) ));
986 goto nocache;
989 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
991 smb_fname_full = (struct smb_filename *)memcache_lookup_talloc(
992 smbd_memcache(),
993 GETWD_CACHE,
994 data_blob_const(&key, sizeof(key)));
996 if (smb_fname_full == NULL) {
997 goto nocache;
1000 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
1001 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
1002 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
1003 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
1005 * Ok, we're done
1006 * Note: smb_fname_full is owned by smbd_memcache()
1007 * so we must make a copy to return.
1009 result = cp_smb_filename(ctx, smb_fname_full);
1010 if (result == NULL) {
1011 errno = ENOMEM;
1013 goto out;
1016 nocache:
1019 * We don't have the information to hand so rely on traditional
1020 * methods. The very slow getcwd, which spawns a process on some
1021 * systems, or the not quite so bad getwd.
1024 current_dir_fname = SMB_VFS_GETWD(conn, ctx);
1025 if (current_dir_fname == NULL) {
1026 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
1027 strerror(errno)));
1028 goto out;
1031 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
1032 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
1035 * smbd_memcache() will own current_dir_fname after the
1036 * memcache_add_talloc call, so we must make
1037 * a copy on ctx to return.
1039 result = cp_smb_filename(ctx, current_dir_fname);
1040 if (result == NULL) {
1041 errno = ENOMEM;
1045 * Ensure the memory going into the cache
1046 * doesn't have a destructor so it can be
1047 * cleanly freed.
1049 talloc_set_destructor(current_dir_fname, NULL);
1051 memcache_add_talloc(smbd_memcache(),
1052 GETWD_CACHE,
1053 data_blob_const(&key, sizeof(key)),
1054 &current_dir_fname);
1055 /* current_dir_fname is now == NULL here. */
1056 } else {
1057 /* current_dir_fname is already allocated on ctx. */
1058 result = current_dir_fname;
1061 out:
1062 TALLOC_FREE(smb_fname_dot);
1064 * Don't free current_dir_fname here. It's either been moved
1065 * to the memcache or is being returned in result.
1067 return result;
1070 /*******************************************************************
1071 Reduce a file name, removing .. elements and checking that
1072 it is below dir in the heirachy. This uses realpath.
1073 This function must run as root, and will return names
1074 and valid stat structs that can be checked on open.
1075 ********************************************************************/
1077 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
1078 const struct smb_filename *smb_fname,
1079 struct smb_request *smbreq)
1081 NTSTATUS status;
1082 TALLOC_CTX *ctx = talloc_tos();
1083 const char *conn_rootdir;
1084 size_t rootdir_len;
1085 char *dir_name = NULL;
1086 char *resolved_name = NULL;
1087 const char *last_component = NULL;
1088 struct smb_filename *resolved_fname = NULL;
1089 struct smb_filename *saved_dir_fname = NULL;
1090 struct smb_filename *smb_fname_cwd = NULL;
1091 struct privilege_paths *priv_paths = NULL;
1092 int ret;
1094 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
1095 smb_fname->base_name,
1096 conn->connectpath));
1099 priv_paths = talloc_zero(smbreq, struct privilege_paths);
1100 if (!priv_paths) {
1101 status = NT_STATUS_NO_MEMORY;
1102 goto err;
1105 if (!parent_dirname(ctx, smb_fname->base_name,
1106 &dir_name, &last_component)) {
1107 status = NT_STATUS_NO_MEMORY;
1108 goto err;
1111 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
1112 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
1114 if (priv_paths->parent_name.base_name == NULL ||
1115 priv_paths->file_name.base_name == NULL) {
1116 status = NT_STATUS_NO_MEMORY;
1117 goto err;
1120 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
1121 status = map_nt_error_from_unix(errno);
1122 goto err;
1124 /* Remember where we were. */
1125 saved_dir_fname = vfs_GetWd(ctx, conn);
1126 if (!saved_dir_fname) {
1127 status = map_nt_error_from_unix(errno);
1128 goto err;
1131 if (vfs_ChDir(conn, &priv_paths->parent_name) == -1) {
1132 status = map_nt_error_from_unix(errno);
1133 goto err;
1136 smb_fname_cwd = synthetic_smb_fname(talloc_tos(), ".", NULL, NULL, 0);
1137 if (smb_fname_cwd == NULL) {
1138 status = NT_STATUS_NO_MEMORY;
1139 goto err;
1142 /* Get the absolute path of the parent directory. */
1143 resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname_cwd);
1144 if (resolved_fname == NULL) {
1145 status = map_nt_error_from_unix(errno);
1146 goto err;
1148 resolved_name = resolved_fname->base_name;
1150 if (*resolved_name != '/') {
1151 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1152 "doesn't return absolute paths !\n"));
1153 status = NT_STATUS_OBJECT_NAME_INVALID;
1154 goto err;
1157 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1158 priv_paths->parent_name.base_name,
1159 resolved_name));
1161 /* Now check the stat value is the same. */
1162 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1163 status = map_nt_error_from_unix(errno);
1164 goto err;
1167 /* Ensure we're pointing at the same place. */
1168 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1169 DEBUG(0,("check_reduced_name_with_privilege: "
1170 "device/inode/uid/gid on directory %s changed. "
1171 "Denying access !\n",
1172 priv_paths->parent_name.base_name));
1173 status = NT_STATUS_ACCESS_DENIED;
1174 goto err;
1177 /* Ensure we're below the connect path. */
1179 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
1180 if (conn_rootdir == NULL) {
1181 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1182 "conn_rootdir\n"));
1183 status = NT_STATUS_ACCESS_DENIED;
1184 goto err;
1187 rootdir_len = strlen(conn_rootdir);
1190 * In the case of rootdir_len == 1, we know that conn_rootdir is
1191 * "/", and we also know that resolved_name starts with a slash.
1192 * So, in this corner case, resolved_name is automatically a
1193 * sub-directory of the conn_rootdir. Thus we can skip the string
1194 * comparison and the next character checks (which are even
1195 * wrong in this case).
1197 if (rootdir_len != 1) {
1198 bool matched;
1200 matched = (strncmp(conn_rootdir, resolved_name,
1201 rootdir_len) == 0);
1203 if (!matched || (resolved_name[rootdir_len] != '/' &&
1204 resolved_name[rootdir_len] != '\0')) {
1205 DEBUG(2, ("check_reduced_name_with_privilege: Bad "
1206 "access attempt: %s is a symlink outside the "
1207 "share path\n",
1208 dir_name));
1209 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1210 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1211 status = NT_STATUS_ACCESS_DENIED;
1212 goto err;
1216 /* Now ensure that the last component either doesn't
1217 exist, or is *NOT* a symlink. */
1219 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1220 if (ret == -1) {
1221 /* Errno must be ENOENT for this be ok. */
1222 if (errno != ENOENT) {
1223 status = map_nt_error_from_unix(errno);
1224 DEBUG(2, ("check_reduced_name_with_privilege: "
1225 "LSTAT on %s failed with %s\n",
1226 priv_paths->file_name.base_name,
1227 nt_errstr(status)));
1228 goto err;
1232 if (VALID_STAT(priv_paths->file_name.st) &&
1233 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1234 DEBUG(2, ("check_reduced_name_with_privilege: "
1235 "Last component %s is a symlink. Denying"
1236 "access.\n",
1237 priv_paths->file_name.base_name));
1238 status = NT_STATUS_ACCESS_DENIED;
1239 goto err;
1242 smbreq->priv_paths = priv_paths;
1243 status = NT_STATUS_OK;
1245 err:
1247 if (saved_dir_fname != NULL) {
1248 vfs_ChDir(conn, saved_dir_fname);
1249 TALLOC_FREE(saved_dir_fname);
1251 TALLOC_FREE(resolved_fname);
1252 if (!NT_STATUS_IS_OK(status)) {
1253 TALLOC_FREE(priv_paths);
1255 TALLOC_FREE(dir_name);
1256 return status;
1259 /*******************************************************************
1260 Reduce a file name, removing .. elements and checking that
1261 it is below dir in the heirachy. This uses realpath.
1263 If cwd_name == NULL then fname is a client given path relative
1264 to the root path of the share.
1266 If cwd_name != NULL then fname is a client given path relative
1267 to cwd_name. cwd_name is relative to the root path of the share.
1268 ********************************************************************/
1270 NTSTATUS check_reduced_name(connection_struct *conn,
1271 const struct smb_filename *cwd_fname,
1272 const struct smb_filename *smb_fname)
1274 TALLOC_CTX *ctx = talloc_tos();
1275 const char *cwd_name = cwd_fname ? cwd_fname->base_name : NULL;
1276 const char *fname = smb_fname->base_name;
1277 struct smb_filename *resolved_fname;
1278 char *resolved_name = NULL;
1279 char *new_fname = NULL;
1280 bool allow_symlinks = true;
1281 bool allow_widelinks = false;
1283 DBG_DEBUG("check_reduced_name [%s] [%s]\n", fname, conn->connectpath);
1285 resolved_fname = SMB_VFS_REALPATH(conn, ctx, smb_fname);
1287 if (resolved_fname == NULL) {
1288 switch (errno) {
1289 case ENOTDIR:
1290 DEBUG(3,("check_reduced_name: Component not a "
1291 "directory in getting realpath for "
1292 "%s\n", fname));
1293 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1294 case ENOENT:
1296 char *dir_name = NULL;
1297 struct smb_filename dir_fname = {0};
1298 const char *last_component = NULL;
1300 /* Last component didn't exist.
1301 Remove it and try and canonicalise
1302 the directory name. */
1303 if (!parent_dirname(ctx, fname,
1304 &dir_name,
1305 &last_component)) {
1306 return NT_STATUS_NO_MEMORY;
1309 dir_fname = (struct smb_filename)
1310 { .base_name = dir_name };
1311 resolved_fname = SMB_VFS_REALPATH(conn,
1312 ctx,
1313 &dir_fname);
1314 if (resolved_fname == NULL) {
1315 NTSTATUS status = map_nt_error_from_unix(errno);
1317 if (errno == ENOENT || errno == ENOTDIR) {
1318 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1321 DEBUG(3,("check_reduce_name: "
1322 "couldn't get realpath for "
1323 "%s (%s)\n",
1324 fname,
1325 nt_errstr(status)));
1326 return status;
1328 resolved_name = talloc_asprintf(ctx,
1329 "%s/%s",
1330 resolved_fname->base_name,
1331 last_component);
1332 if (resolved_name == NULL) {
1333 return NT_STATUS_NO_MEMORY;
1335 break;
1337 default:
1338 DEBUG(3,("check_reduced_name: couldn't get "
1339 "realpath for %s\n", fname));
1340 return map_nt_error_from_unix(errno);
1342 } else {
1343 resolved_name = resolved_fname->base_name;
1346 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1347 resolved_name));
1349 if (*resolved_name != '/') {
1350 DEBUG(0,("check_reduced_name: realpath doesn't return "
1351 "absolute paths !\n"));
1352 TALLOC_FREE(resolved_fname);
1353 return NT_STATUS_OBJECT_NAME_INVALID;
1356 allow_widelinks = lp_widelinks(SNUM(conn));
1357 allow_symlinks = lp_follow_symlinks(SNUM(conn));
1359 /* Common widelinks and symlinks checks. */
1360 if (!allow_widelinks || !allow_symlinks) {
1361 const char *conn_rootdir;
1362 size_t rootdir_len;
1364 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
1365 if (conn_rootdir == NULL) {
1366 DEBUG(2, ("check_reduced_name: Could not get "
1367 "conn_rootdir\n"));
1368 TALLOC_FREE(resolved_fname);
1369 return NT_STATUS_ACCESS_DENIED;
1372 rootdir_len = strlen(conn_rootdir);
1375 * In the case of rootdir_len == 1, we know that
1376 * conn_rootdir is "/", and we also know that
1377 * resolved_name starts with a slash. So, in this
1378 * corner case, resolved_name is automatically a
1379 * sub-directory of the conn_rootdir. Thus we can skip
1380 * the string comparison and the next character checks
1381 * (which are even wrong in this case).
1383 if (rootdir_len != 1) {
1384 bool matched;
1386 matched = (strncmp(conn_rootdir, resolved_name,
1387 rootdir_len) == 0);
1388 if (!matched || (resolved_name[rootdir_len] != '/' &&
1389 resolved_name[rootdir_len] != '\0')) {
1390 DEBUG(2, ("check_reduced_name: Bad access "
1391 "attempt: %s is a symlink outside the "
1392 "share path\n", fname));
1393 DEBUGADD(2, ("conn_rootdir =%s\n",
1394 conn_rootdir));
1395 DEBUGADD(2, ("resolved_name=%s\n",
1396 resolved_name));
1397 TALLOC_FREE(resolved_fname);
1398 return NT_STATUS_ACCESS_DENIED;
1402 /* Extra checks if all symlinks are disallowed. */
1403 if (!allow_symlinks) {
1404 /* fname can't have changed in resolved_path. */
1405 const char *p = &resolved_name[rootdir_len];
1408 * UNIX filesystem semantics, names consisting
1409 * only of "." or ".." CANNOT be symlinks.
1411 if (ISDOT(fname) || ISDOTDOT(fname)) {
1412 goto out;
1415 if (*p != '/') {
1416 DEBUG(2, ("check_reduced_name: logic error (%c) "
1417 "in resolved_name: %s\n",
1419 fname));
1420 TALLOC_FREE(resolved_fname);
1421 return NT_STATUS_ACCESS_DENIED;
1424 p++;
1427 * If cwd_name is present and not ".",
1428 * then fname is relative to that, not
1429 * the root of the share. Make sure the
1430 * path we check is the one the client
1431 * sent (cwd_name+fname).
1433 if (cwd_name != NULL && !ISDOT(cwd_name)) {
1434 new_fname = talloc_asprintf(ctx,
1435 "%s/%s",
1436 cwd_name,
1437 fname);
1438 if (new_fname == NULL) {
1439 TALLOC_FREE(resolved_fname);
1440 return NT_STATUS_NO_MEMORY;
1442 fname = new_fname;
1445 if (strcmp(fname, p)!=0) {
1446 DEBUG(2, ("check_reduced_name: Bad access "
1447 "attempt: %s is a symlink to %s\n",
1448 fname, p));
1449 TALLOC_FREE(resolved_fname);
1450 TALLOC_FREE(new_fname);
1451 return NT_STATUS_ACCESS_DENIED;
1456 out:
1458 DBG_INFO("%s reduced to %s\n", fname, resolved_name);
1459 TALLOC_FREE(resolved_fname);
1460 TALLOC_FREE(new_fname);
1461 return NT_STATUS_OK;
1465 * XXX: This is temporary and there should be no callers of this once
1466 * smb_filename is plumbed through all path based operations.
1468 * Called when we know stream name parsing has already been done.
1470 int vfs_stat_smb_basename(struct connection_struct *conn,
1471 const struct smb_filename *smb_fname_in,
1472 SMB_STRUCT_STAT *psbuf)
1474 struct smb_filename smb_fname = {
1475 .base_name = discard_const_p(char, smb_fname_in->base_name),
1476 .flags = smb_fname_in->flags
1478 int ret;
1480 if (smb_fname.flags & SMB_FILENAME_POSIX_PATH) {
1481 ret = SMB_VFS_LSTAT(conn, &smb_fname);
1482 } else {
1483 ret = SMB_VFS_STAT(conn, &smb_fname);
1486 if (ret != -1) {
1487 *psbuf = smb_fname.st;
1489 return ret;
1493 * Ensure LSTAT is called for POSIX paths.
1496 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1498 int ret;
1500 if(fsp->fh->fd == -1) {
1501 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
1502 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1503 } else {
1504 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1506 if (ret == -1) {
1507 return map_nt_error_from_unix(errno);
1509 } else {
1510 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1511 return map_nt_error_from_unix(errno);
1514 return NT_STATUS_OK;
1518 * Initialize num_streams and streams, then call VFS op streaminfo
1520 NTSTATUS vfs_streaminfo(connection_struct *conn,
1521 struct files_struct *fsp,
1522 const struct smb_filename *smb_fname,
1523 TALLOC_CTX *mem_ctx,
1524 unsigned int *num_streams,
1525 struct stream_struct **streams)
1527 *num_streams = 0;
1528 *streams = NULL;
1529 return SMB_VFS_STREAMINFO(conn,
1530 fsp,
1531 smb_fname,
1532 mem_ctx,
1533 num_streams,
1534 streams);
1538 generate a file_id from a stat structure
1540 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1542 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1545 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1546 const char *service, const char *user)
1548 VFS_FIND(connect);
1549 return handle->fns->connect_fn(handle, service, user);
1552 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1554 VFS_FIND(disconnect);
1555 handle->fns->disconnect_fn(handle);
1558 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1559 const struct smb_filename *smb_fname,
1560 uint64_t *bsize,
1561 uint64_t *dfree,
1562 uint64_t *dsize)
1564 VFS_FIND(disk_free);
1565 return handle->fns->disk_free_fn(handle, smb_fname,
1566 bsize, dfree, dsize);
1569 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1570 const struct smb_filename *smb_fname,
1571 enum SMB_QUOTA_TYPE qtype,
1572 unid_t id,
1573 SMB_DISK_QUOTA *qt)
1575 VFS_FIND(get_quota);
1576 return handle->fns->get_quota_fn(handle, smb_fname, qtype, id, qt);
1579 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1580 enum SMB_QUOTA_TYPE qtype, unid_t id,
1581 SMB_DISK_QUOTA *qt)
1583 VFS_FIND(set_quota);
1584 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1587 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1588 struct files_struct *fsp,
1589 struct shadow_copy_data *shadow_copy_data,
1590 bool labels)
1592 VFS_FIND(get_shadow_copy_data);
1593 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1594 shadow_copy_data,
1595 labels);
1597 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle,
1598 const struct smb_filename *smb_fname,
1599 struct vfs_statvfs_struct *statbuf)
1601 VFS_FIND(statvfs);
1602 return handle->fns->statvfs_fn(handle, smb_fname, statbuf);
1605 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1606 enum timestamp_set_resolution *p_ts_res)
1608 VFS_FIND(fs_capabilities);
1609 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1612 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1613 struct dfs_GetDFSReferral *r)
1615 VFS_FIND(get_dfs_referrals);
1616 return handle->fns->get_dfs_referrals_fn(handle, r);
1619 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1620 const struct smb_filename *smb_fname,
1621 const char *mask,
1622 uint32_t attributes)
1624 VFS_FIND(opendir);
1625 return handle->fns->opendir_fn(handle, smb_fname, mask, attributes);
1628 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1629 struct files_struct *fsp,
1630 const char *mask,
1631 uint32_t attributes)
1633 VFS_FIND(fdopendir);
1634 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1637 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1638 DIR *dirp,
1639 SMB_STRUCT_STAT *sbuf)
1641 VFS_FIND(readdir);
1642 return handle->fns->readdir_fn(handle, dirp, sbuf);
1645 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1646 DIR *dirp, long offset)
1648 VFS_FIND(seekdir);
1649 handle->fns->seekdir_fn(handle, dirp, offset);
1652 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1653 DIR *dirp)
1655 VFS_FIND(telldir);
1656 return handle->fns->telldir_fn(handle, dirp);
1659 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1660 DIR *dirp)
1662 VFS_FIND(rewind_dir);
1663 handle->fns->rewind_dir_fn(handle, dirp);
1666 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle,
1667 const struct smb_filename *smb_fname,
1668 mode_t mode)
1670 VFS_FIND(mkdir);
1671 return handle->fns->mkdir_fn(handle, smb_fname, mode);
1674 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle,
1675 const struct smb_filename *smb_fname)
1677 VFS_FIND(rmdir);
1678 return handle->fns->rmdir_fn(handle, smb_fname);
1681 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1682 DIR *dir)
1684 VFS_FIND(closedir);
1685 return handle->fns->closedir_fn(handle, dir);
1688 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1689 struct smb_filename *smb_fname, struct files_struct *fsp,
1690 int flags, mode_t mode)
1692 VFS_FIND(open);
1693 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1696 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1697 struct smb_request *req,
1698 uint16_t root_dir_fid,
1699 struct smb_filename *smb_fname,
1700 uint32_t access_mask,
1701 uint32_t share_access,
1702 uint32_t create_disposition,
1703 uint32_t create_options,
1704 uint32_t file_attributes,
1705 uint32_t oplock_request,
1706 struct smb2_lease *lease,
1707 uint64_t allocation_size,
1708 uint32_t private_flags,
1709 struct security_descriptor *sd,
1710 struct ea_list *ea_list,
1711 files_struct **result,
1712 int *pinfo,
1713 const struct smb2_create_blobs *in_context_blobs,
1714 struct smb2_create_blobs *out_context_blobs)
1716 VFS_FIND(create_file);
1717 return handle->fns->create_file_fn(
1718 handle, req, root_dir_fid, smb_fname, access_mask,
1719 share_access, create_disposition, create_options,
1720 file_attributes, oplock_request, lease, allocation_size,
1721 private_flags, sd, ea_list,
1722 result, pinfo, in_context_blobs, out_context_blobs);
1725 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1726 struct files_struct *fsp)
1728 VFS_FIND(close);
1729 return handle->fns->close_fn(handle, fsp);
1732 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1733 struct files_struct *fsp, void *data, size_t n)
1735 VFS_FIND(read);
1736 return handle->fns->read_fn(handle, fsp, data, n);
1739 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1740 struct files_struct *fsp, void *data, size_t n,
1741 off_t offset)
1743 VFS_FIND(pread);
1744 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1747 struct smb_vfs_call_pread_state {
1748 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1749 ssize_t retval;
1750 struct vfs_aio_state vfs_aio_state;
1753 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1755 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1756 TALLOC_CTX *mem_ctx,
1757 struct tevent_context *ev,
1758 struct files_struct *fsp,
1759 void *data,
1760 size_t n, off_t offset)
1762 struct tevent_req *req, *subreq;
1763 struct smb_vfs_call_pread_state *state;
1765 req = tevent_req_create(mem_ctx, &state,
1766 struct smb_vfs_call_pread_state);
1767 if (req == NULL) {
1768 return NULL;
1770 VFS_FIND(pread_send);
1771 state->recv_fn = handle->fns->pread_recv_fn;
1773 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1774 offset);
1775 if (tevent_req_nomem(subreq, req)) {
1776 return tevent_req_post(req, ev);
1778 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1779 return req;
1782 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1784 struct tevent_req *req = tevent_req_callback_data(
1785 subreq, struct tevent_req);
1786 struct smb_vfs_call_pread_state *state = tevent_req_data(
1787 req, struct smb_vfs_call_pread_state);
1789 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1790 TALLOC_FREE(subreq);
1791 if (state->retval == -1) {
1792 tevent_req_error(req, state->vfs_aio_state.error);
1793 return;
1795 tevent_req_done(req);
1798 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req,
1799 struct vfs_aio_state *vfs_aio_state)
1801 struct smb_vfs_call_pread_state *state = tevent_req_data(
1802 req, struct smb_vfs_call_pread_state);
1804 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1805 return -1;
1807 *vfs_aio_state = state->vfs_aio_state;
1808 return state->retval;
1811 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1812 struct files_struct *fsp, const void *data,
1813 size_t n)
1815 VFS_FIND(write);
1816 return handle->fns->write_fn(handle, fsp, data, n);
1819 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1820 struct files_struct *fsp, const void *data,
1821 size_t n, off_t offset)
1823 VFS_FIND(pwrite);
1824 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1827 struct smb_vfs_call_pwrite_state {
1828 ssize_t (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1829 ssize_t retval;
1830 struct vfs_aio_state vfs_aio_state;
1833 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1835 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1836 TALLOC_CTX *mem_ctx,
1837 struct tevent_context *ev,
1838 struct files_struct *fsp,
1839 const void *data,
1840 size_t n, off_t offset)
1842 struct tevent_req *req, *subreq;
1843 struct smb_vfs_call_pwrite_state *state;
1845 req = tevent_req_create(mem_ctx, &state,
1846 struct smb_vfs_call_pwrite_state);
1847 if (req == NULL) {
1848 return NULL;
1850 VFS_FIND(pwrite_send);
1851 state->recv_fn = handle->fns->pwrite_recv_fn;
1853 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1854 offset);
1855 if (tevent_req_nomem(subreq, req)) {
1856 return tevent_req_post(req, ev);
1858 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1859 return req;
1862 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1864 struct tevent_req *req = tevent_req_callback_data(
1865 subreq, struct tevent_req);
1866 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1867 req, struct smb_vfs_call_pwrite_state);
1869 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1870 TALLOC_FREE(subreq);
1871 if (state->retval == -1) {
1872 tevent_req_error(req, state->vfs_aio_state.error);
1873 return;
1875 tevent_req_done(req);
1878 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req,
1879 struct vfs_aio_state *vfs_aio_state)
1881 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1882 req, struct smb_vfs_call_pwrite_state);
1884 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1885 return -1;
1887 *vfs_aio_state = state->vfs_aio_state;
1888 return state->retval;
1891 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1892 struct files_struct *fsp, off_t offset,
1893 int whence)
1895 VFS_FIND(lseek);
1896 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1899 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1900 files_struct *fromfsp, const DATA_BLOB *header,
1901 off_t offset, size_t count)
1903 VFS_FIND(sendfile);
1904 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1905 count);
1908 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1909 files_struct *tofsp, off_t offset,
1910 size_t count)
1912 VFS_FIND(recvfile);
1913 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1916 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1917 const struct smb_filename *smb_fname_src,
1918 const struct smb_filename *smb_fname_dst)
1920 VFS_FIND(rename);
1921 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1924 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1925 struct files_struct *fsp)
1927 VFS_FIND(fsync);
1928 return handle->fns->fsync_fn(handle, fsp);
1931 struct smb_vfs_call_fsync_state {
1932 int (*recv_fn)(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state);
1933 int retval;
1934 struct vfs_aio_state vfs_aio_state;
1937 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1939 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1940 TALLOC_CTX *mem_ctx,
1941 struct tevent_context *ev,
1942 struct files_struct *fsp)
1944 struct tevent_req *req, *subreq;
1945 struct smb_vfs_call_fsync_state *state;
1947 req = tevent_req_create(mem_ctx, &state,
1948 struct smb_vfs_call_fsync_state);
1949 if (req == NULL) {
1950 return NULL;
1952 VFS_FIND(fsync_send);
1953 state->recv_fn = handle->fns->fsync_recv_fn;
1955 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1956 if (tevent_req_nomem(subreq, req)) {
1957 return tevent_req_post(req, ev);
1959 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1960 return req;
1963 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1965 struct tevent_req *req = tevent_req_callback_data(
1966 subreq, struct tevent_req);
1967 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1968 req, struct smb_vfs_call_fsync_state);
1970 state->retval = state->recv_fn(subreq, &state->vfs_aio_state);
1971 TALLOC_FREE(subreq);
1972 if (state->retval == -1) {
1973 tevent_req_error(req, state->vfs_aio_state.error);
1974 return;
1976 tevent_req_done(req);
1979 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, struct vfs_aio_state *vfs_aio_state)
1981 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1982 req, struct smb_vfs_call_fsync_state);
1984 if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
1985 return -1;
1987 *vfs_aio_state = state->vfs_aio_state;
1988 return state->retval;
1992 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1993 struct smb_filename *smb_fname)
1995 VFS_FIND(stat);
1996 return handle->fns->stat_fn(handle, smb_fname);
1999 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
2000 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
2002 VFS_FIND(fstat);
2003 return handle->fns->fstat_fn(handle, fsp, sbuf);
2006 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
2007 struct smb_filename *smb_filename)
2009 VFS_FIND(lstat);
2010 return handle->fns->lstat_fn(handle, smb_filename);
2013 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
2014 struct files_struct *fsp,
2015 const SMB_STRUCT_STAT *sbuf)
2017 VFS_FIND(get_alloc_size);
2018 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
2021 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
2022 const struct smb_filename *smb_fname)
2024 VFS_FIND(unlink);
2025 return handle->fns->unlink_fn(handle, smb_fname);
2028 int smb_vfs_call_chmod(struct vfs_handle_struct *handle,
2029 const struct smb_filename *smb_fname,
2030 mode_t mode)
2032 VFS_FIND(chmod);
2033 return handle->fns->chmod_fn(handle, smb_fname, mode);
2036 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
2037 struct files_struct *fsp, mode_t mode)
2039 VFS_FIND(fchmod);
2040 return handle->fns->fchmod_fn(handle, fsp, mode);
2043 int smb_vfs_call_chown(struct vfs_handle_struct *handle,
2044 const struct smb_filename *smb_fname,
2045 uid_t uid,
2046 gid_t gid)
2048 VFS_FIND(chown);
2049 return handle->fns->chown_fn(handle, smb_fname, uid, gid);
2052 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
2053 struct files_struct *fsp, uid_t uid, gid_t gid)
2055 VFS_FIND(fchown);
2056 return handle->fns->fchown_fn(handle, fsp, uid, gid);
2059 int smb_vfs_call_lchown(struct vfs_handle_struct *handle,
2060 const struct smb_filename *smb_fname,
2061 uid_t uid,
2062 gid_t gid)
2064 VFS_FIND(lchown);
2065 return handle->fns->lchown_fn(handle, smb_fname, uid, gid);
2068 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
2070 int ret;
2071 bool as_root = false;
2072 NTSTATUS status;
2074 if (fsp->fh->fd != -1) {
2075 /* Try fchown. */
2076 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
2077 if (ret == 0) {
2078 return NT_STATUS_OK;
2080 if (ret == -1 && errno != ENOSYS) {
2081 return map_nt_error_from_unix(errno);
2085 as_root = (geteuid() == 0);
2087 if (as_root) {
2089 * We are being asked to chown as root. Make
2090 * sure we chdir() into the path to pin it,
2091 * and always act using lchown to ensure we
2092 * don't deref any symbolic links.
2094 char *parent_dir = NULL;
2095 const char *final_component = NULL;
2096 struct smb_filename *local_smb_fname = NULL;
2097 struct smb_filename parent_dir_fname = {0};
2098 struct smb_filename *saved_dir_fname = NULL;
2100 saved_dir_fname = vfs_GetWd(talloc_tos(),fsp->conn);
2101 if (!saved_dir_fname) {
2102 status = map_nt_error_from_unix(errno);
2103 DEBUG(0,("vfs_chown_fsp: failed to get "
2104 "current working directory. Error was %s\n",
2105 strerror(errno)));
2106 return status;
2109 if (!parent_dirname(talloc_tos(),
2110 fsp->fsp_name->base_name,
2111 &parent_dir,
2112 &final_component)) {
2113 return NT_STATUS_NO_MEMORY;
2116 parent_dir_fname = (struct smb_filename) {
2117 .base_name = parent_dir,
2118 .flags = fsp->fsp_name->flags
2121 /* cd into the parent dir to pin it. */
2122 ret = vfs_ChDir(fsp->conn, &parent_dir_fname);
2123 if (ret == -1) {
2124 return map_nt_error_from_unix(errno);
2127 local_smb_fname = synthetic_smb_fname(talloc_tos(),
2128 final_component,
2129 NULL,
2130 NULL,
2131 fsp->fsp_name->flags);
2132 if (local_smb_fname == NULL) {
2133 status = NT_STATUS_NO_MEMORY;
2134 goto out;
2137 /* Must use lstat here. */
2138 ret = SMB_VFS_LSTAT(fsp->conn, local_smb_fname);
2139 if (ret == -1) {
2140 status = map_nt_error_from_unix(errno);
2141 goto out;
2144 /* Ensure it matches the fsp stat. */
2145 if (!check_same_stat(&local_smb_fname->st,
2146 &fsp->fsp_name->st)) {
2147 status = NT_STATUS_ACCESS_DENIED;
2148 goto out;
2151 ret = SMB_VFS_LCHOWN(fsp->conn,
2152 local_smb_fname,
2153 uid, gid);
2155 if (ret == 0) {
2156 status = NT_STATUS_OK;
2157 } else {
2158 status = map_nt_error_from_unix(errno);
2161 out:
2163 vfs_ChDir(fsp->conn, saved_dir_fname);
2164 TALLOC_FREE(local_smb_fname);
2165 TALLOC_FREE(saved_dir_fname);
2166 TALLOC_FREE(parent_dir);
2168 return status;
2171 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
2172 ret = SMB_VFS_LCHOWN(fsp->conn,
2173 fsp->fsp_name,
2174 uid, gid);
2175 } else {
2176 ret = SMB_VFS_CHOWN(fsp->conn,
2177 fsp->fsp_name,
2178 uid, gid);
2181 if (ret == 0) {
2182 status = NT_STATUS_OK;
2183 } else {
2184 status = map_nt_error_from_unix(errno);
2186 return status;
2189 int smb_vfs_call_chdir(struct vfs_handle_struct *handle,
2190 const struct smb_filename *smb_fname)
2192 VFS_FIND(chdir);
2193 return handle->fns->chdir_fn(handle, smb_fname);
2196 struct smb_filename *smb_vfs_call_getwd(struct vfs_handle_struct *handle,
2197 TALLOC_CTX *ctx)
2199 VFS_FIND(getwd);
2200 return handle->fns->getwd_fn(handle, ctx);
2203 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
2204 const struct smb_filename *smb_fname,
2205 struct smb_file_time *ft)
2207 VFS_FIND(ntimes);
2208 return handle->fns->ntimes_fn(handle, smb_fname, ft);
2211 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2212 struct files_struct *fsp, off_t offset)
2214 VFS_FIND(ftruncate);
2215 return handle->fns->ftruncate_fn(handle, fsp, offset);
2218 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2219 struct files_struct *fsp,
2220 uint32_t mode,
2221 off_t offset,
2222 off_t len)
2224 VFS_FIND(fallocate);
2225 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2228 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2229 struct files_struct *fsp, uint32_t share_mode,
2230 uint32_t access_mask)
2232 VFS_FIND(kernel_flock);
2233 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2234 access_mask);
2237 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2238 struct files_struct *fsp, int leasetype)
2240 VFS_FIND(linux_setlease);
2241 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2244 int smb_vfs_call_symlink(struct vfs_handle_struct *handle,
2245 const char *link_target,
2246 const struct smb_filename *new_smb_fname)
2248 VFS_FIND(symlink);
2249 return handle->fns->symlink_fn(handle, link_target, new_smb_fname);
2252 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2253 const struct smb_filename *smb_fname,
2254 char *buf,
2255 size_t bufsiz)
2257 VFS_FIND(readlink);
2258 return handle->fns->readlink_fn(handle, smb_fname, buf, bufsiz);
2261 int smb_vfs_call_link(struct vfs_handle_struct *handle,
2262 const struct smb_filename *old_smb_fname,
2263 const struct smb_filename *new_smb_fname)
2265 VFS_FIND(link);
2266 return handle->fns->link_fn(handle, old_smb_fname, new_smb_fname);
2269 int smb_vfs_call_mknod(struct vfs_handle_struct *handle,
2270 const struct smb_filename *smb_fname,
2271 mode_t mode,
2272 SMB_DEV_T dev)
2274 VFS_FIND(mknod);
2275 return handle->fns->mknod_fn(handle, smb_fname, mode, dev);
2278 struct smb_filename *smb_vfs_call_realpath(struct vfs_handle_struct *handle,
2279 TALLOC_CTX *ctx,
2280 const struct smb_filename *smb_fname)
2282 VFS_FIND(realpath);
2283 return handle->fns->realpath_fn(handle, ctx, smb_fname);
2286 int smb_vfs_call_chflags(struct vfs_handle_struct *handle,
2287 const struct smb_filename *smb_fname,
2288 unsigned int flags)
2290 VFS_FIND(chflags);
2291 return handle->fns->chflags_fn(handle, smb_fname, flags);
2294 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2295 const SMB_STRUCT_STAT *sbuf)
2297 VFS_FIND(file_id_create);
2298 return handle->fns->file_id_create_fn(handle, sbuf);
2301 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2302 struct files_struct *fsp,
2303 const struct smb_filename *smb_fname,
2304 TALLOC_CTX *mem_ctx,
2305 unsigned int *num_streams,
2306 struct stream_struct **streams)
2308 VFS_FIND(streaminfo);
2309 return handle->fns->streaminfo_fn(handle, fsp, smb_fname, mem_ctx,
2310 num_streams, streams);
2313 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2314 const char *path, const char *name,
2315 TALLOC_CTX *mem_ctx, char **found_name)
2317 VFS_FIND(get_real_filename);
2318 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2319 found_name);
2322 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2323 const struct smb_filename *smb_fname)
2325 VFS_FIND(connectpath);
2326 return handle->fns->connectpath_fn(handle, smb_fname);
2329 bool smb_vfs_call_strict_lock_check(struct vfs_handle_struct *handle,
2330 struct files_struct *fsp,
2331 struct lock_struct *plock)
2333 VFS_FIND(strict_lock_check);
2334 return handle->fns->strict_lock_check_fn(handle, fsp, plock);
2337 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2338 const char *name,
2339 enum vfs_translate_direction direction,
2340 TALLOC_CTX *mem_ctx,
2341 char **mapped_name)
2343 VFS_FIND(translate_name);
2344 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2345 mapped_name);
2348 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2349 struct files_struct *fsp,
2350 TALLOC_CTX *ctx,
2351 uint32_t function,
2352 uint16_t req_flags,
2353 const uint8_t *in_data,
2354 uint32_t in_len,
2355 uint8_t **out_data,
2356 uint32_t max_out_len,
2357 uint32_t *out_len)
2359 VFS_FIND(fsctl);
2360 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2361 in_data, in_len, out_data, max_out_len,
2362 out_len);
2365 NTSTATUS smb_vfs_call_get_dos_attributes(struct vfs_handle_struct *handle,
2366 struct smb_filename *smb_fname,
2367 uint32_t *dosmode)
2369 VFS_FIND(get_dos_attributes);
2370 return handle->fns->get_dos_attributes_fn(handle, smb_fname, dosmode);
2373 NTSTATUS smb_vfs_call_fget_dos_attributes(struct vfs_handle_struct *handle,
2374 struct files_struct *fsp,
2375 uint32_t *dosmode)
2377 VFS_FIND(fget_dos_attributes);
2378 return handle->fns->fget_dos_attributes_fn(handle, fsp, dosmode);
2381 NTSTATUS smb_vfs_call_set_dos_attributes(struct vfs_handle_struct *handle,
2382 const struct smb_filename *smb_fname,
2383 uint32_t dosmode)
2385 VFS_FIND(set_dos_attributes);
2386 return handle->fns->set_dos_attributes_fn(handle, smb_fname, dosmode);
2389 NTSTATUS smb_vfs_call_fset_dos_attributes(struct vfs_handle_struct *handle,
2390 struct files_struct *fsp,
2391 uint32_t dosmode)
2393 VFS_FIND(set_dos_attributes);
2394 return handle->fns->fset_dos_attributes_fn(handle, fsp, dosmode);
2397 struct tevent_req *smb_vfs_call_offload_read_send(TALLOC_CTX *mem_ctx,
2398 struct tevent_context *ev,
2399 struct vfs_handle_struct *handle,
2400 struct files_struct *fsp,
2401 uint32_t fsctl,
2402 uint32_t ttl,
2403 off_t offset,
2404 size_t to_copy)
2406 VFS_FIND(offload_read_send);
2407 return handle->fns->offload_read_send_fn(mem_ctx, ev, handle,
2408 fsp, fsctl,
2409 ttl, offset, to_copy);
2412 NTSTATUS smb_vfs_call_offload_read_recv(struct tevent_req *req,
2413 struct vfs_handle_struct *handle,
2414 TALLOC_CTX *mem_ctx,
2415 DATA_BLOB *token_blob)
2417 VFS_FIND(offload_read_recv);
2418 return handle->fns->offload_read_recv_fn(req, handle, mem_ctx, token_blob);
2421 struct tevent_req *smb_vfs_call_offload_write_send(struct vfs_handle_struct *handle,
2422 TALLOC_CTX *mem_ctx,
2423 struct tevent_context *ev,
2424 uint32_t fsctl,
2425 DATA_BLOB *token,
2426 off_t transfer_offset,
2427 struct files_struct *dest_fsp,
2428 off_t dest_off,
2429 off_t num)
2431 VFS_FIND(offload_write_send);
2432 return handle->fns->offload_write_send_fn(handle, mem_ctx, ev, fsctl,
2433 token, transfer_offset,
2434 dest_fsp, dest_off, num);
2437 NTSTATUS smb_vfs_call_offload_write_recv(struct vfs_handle_struct *handle,
2438 struct tevent_req *req,
2439 off_t *copied)
2441 VFS_FIND(offload_write_recv);
2442 return handle->fns->offload_write_recv_fn(handle, req, copied);
2445 NTSTATUS smb_vfs_call_get_compression(vfs_handle_struct *handle,
2446 TALLOC_CTX *mem_ctx,
2447 struct files_struct *fsp,
2448 struct smb_filename *smb_fname,
2449 uint16_t *_compression_fmt)
2451 VFS_FIND(get_compression);
2452 return handle->fns->get_compression_fn(handle, mem_ctx, fsp, smb_fname,
2453 _compression_fmt);
2456 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2457 TALLOC_CTX *mem_ctx,
2458 struct files_struct *fsp,
2459 uint16_t compression_fmt)
2461 VFS_FIND(set_compression);
2462 return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2463 compression_fmt);
2466 NTSTATUS smb_vfs_call_snap_check_path(vfs_handle_struct *handle,
2467 TALLOC_CTX *mem_ctx,
2468 const char *service_path,
2469 char **base_volume)
2471 VFS_FIND(snap_check_path);
2472 return handle->fns->snap_check_path_fn(handle, mem_ctx, service_path,
2473 base_volume);
2476 NTSTATUS smb_vfs_call_snap_create(struct vfs_handle_struct *handle,
2477 TALLOC_CTX *mem_ctx,
2478 const char *base_volume,
2479 time_t *tstamp,
2480 bool rw,
2481 char **base_path,
2482 char **snap_path)
2484 VFS_FIND(snap_create);
2485 return handle->fns->snap_create_fn(handle, mem_ctx, base_volume, tstamp,
2486 rw, base_path, snap_path);
2489 NTSTATUS smb_vfs_call_snap_delete(struct vfs_handle_struct *handle,
2490 TALLOC_CTX *mem_ctx,
2491 char *base_path,
2492 char *snap_path)
2494 VFS_FIND(snap_delete);
2495 return handle->fns->snap_delete_fn(handle, mem_ctx, base_path,
2496 snap_path);
2499 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2500 struct files_struct *fsp,
2501 uint32_t security_info,
2502 TALLOC_CTX *mem_ctx,
2503 struct security_descriptor **ppdesc)
2505 VFS_FIND(fget_nt_acl);
2506 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2507 mem_ctx, ppdesc);
2510 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2511 const struct smb_filename *smb_fname,
2512 uint32_t security_info,
2513 TALLOC_CTX *mem_ctx,
2514 struct security_descriptor **ppdesc)
2516 VFS_FIND(get_nt_acl);
2517 return handle->fns->get_nt_acl_fn(handle,
2518 smb_fname,
2519 security_info,
2520 mem_ctx,
2521 ppdesc);
2524 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2525 struct files_struct *fsp,
2526 uint32_t security_info_sent,
2527 const struct security_descriptor *psd)
2529 VFS_FIND(fset_nt_acl);
2530 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2531 psd);
2534 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2535 struct smb_filename *file,
2536 struct security_acl *sacl,
2537 uint32_t access_requested,
2538 uint32_t access_denied)
2540 VFS_FIND(audit_file);
2541 return handle->fns->audit_file_fn(handle,
2542 file,
2543 sacl,
2544 access_requested,
2545 access_denied);
2548 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle,
2549 const struct smb_filename *smb_fname,
2550 mode_t mode)
2552 VFS_FIND(chmod_acl);
2553 return handle->fns->chmod_acl_fn(handle, smb_fname, mode);
2556 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2557 struct files_struct *fsp, mode_t mode)
2559 VFS_FIND(fchmod_acl);
2560 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2563 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2564 const struct smb_filename *smb_fname,
2565 SMB_ACL_TYPE_T type,
2566 TALLOC_CTX *mem_ctx)
2568 VFS_FIND(sys_acl_get_file);
2569 return handle->fns->sys_acl_get_file_fn(handle, smb_fname, type, mem_ctx);
2572 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2573 struct files_struct *fsp,
2574 TALLOC_CTX *mem_ctx)
2576 VFS_FIND(sys_acl_get_fd);
2577 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2580 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2581 const struct smb_filename *smb_fname,
2582 TALLOC_CTX *mem_ctx,
2583 char **blob_description,
2584 DATA_BLOB *blob)
2586 VFS_FIND(sys_acl_blob_get_file);
2587 return handle->fns->sys_acl_blob_get_file_fn(handle, smb_fname,
2588 mem_ctx, blob_description, blob);
2591 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2592 struct files_struct *fsp,
2593 TALLOC_CTX *mem_ctx,
2594 char **blob_description,
2595 DATA_BLOB *blob)
2597 VFS_FIND(sys_acl_blob_get_fd);
2598 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2601 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2602 const struct smb_filename *smb_fname,
2603 SMB_ACL_TYPE_T acltype,
2604 SMB_ACL_T theacl)
2606 VFS_FIND(sys_acl_set_file);
2607 return handle->fns->sys_acl_set_file_fn(handle, smb_fname,
2608 acltype, theacl);
2611 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2612 struct files_struct *fsp, SMB_ACL_T theacl)
2614 VFS_FIND(sys_acl_set_fd);
2615 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2618 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2619 const struct smb_filename *smb_fname)
2621 VFS_FIND(sys_acl_delete_def_file);
2622 return handle->fns->sys_acl_delete_def_file_fn(handle, smb_fname);
2625 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2626 const struct smb_filename *smb_fname,
2627 const char *name,
2628 void *value,
2629 size_t size)
2631 VFS_FIND(getxattr);
2632 return handle->fns->getxattr_fn(handle, smb_fname, name, value, size);
2635 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2636 struct files_struct *fsp, const char *name,
2637 void *value, size_t size)
2639 VFS_FIND(fgetxattr);
2640 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2643 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2644 const struct smb_filename *smb_fname,
2645 char *list,
2646 size_t size)
2648 VFS_FIND(listxattr);
2649 return handle->fns->listxattr_fn(handle, smb_fname, list, size);
2652 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2653 struct files_struct *fsp, char *list,
2654 size_t size)
2656 VFS_FIND(flistxattr);
2657 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2660 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2661 const struct smb_filename *smb_fname,
2662 const char *name)
2664 VFS_FIND(removexattr);
2665 return handle->fns->removexattr_fn(handle, smb_fname, name);
2668 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2669 struct files_struct *fsp, const char *name)
2671 VFS_FIND(fremovexattr);
2672 return handle->fns->fremovexattr_fn(handle, fsp, name);
2675 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle,
2676 const struct smb_filename *smb_fname,
2677 const char *name,
2678 const void *value,
2679 size_t size,
2680 int flags)
2682 VFS_FIND(setxattr);
2683 return handle->fns->setxattr_fn(handle, smb_fname,
2684 name, value, size, flags);
2687 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2688 struct files_struct *fsp, const char *name,
2689 const void *value, size_t size, int flags)
2691 VFS_FIND(fsetxattr);
2692 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2695 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2696 struct files_struct *fsp)
2698 VFS_FIND(aio_force);
2699 return handle->fns->aio_force_fn(handle, fsp);
2702 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2703 struct files_struct *fsp,
2704 TALLOC_CTX *mem_ctx,
2705 DATA_BLOB *cookie)
2707 VFS_FIND(durable_cookie);
2708 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2711 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2712 struct files_struct *fsp,
2713 const DATA_BLOB old_cookie,
2714 TALLOC_CTX *mem_ctx,
2715 DATA_BLOB *new_cookie)
2717 VFS_FIND(durable_disconnect);
2718 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2719 mem_ctx, new_cookie);
2722 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2723 struct smb_request *smb1req,
2724 struct smbXsrv_open *op,
2725 const DATA_BLOB old_cookie,
2726 TALLOC_CTX *mem_ctx,
2727 struct files_struct **fsp,
2728 DATA_BLOB *new_cookie)
2730 VFS_FIND(durable_reconnect);
2731 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2732 old_cookie, mem_ctx, fsp,
2733 new_cookie);
2736 NTSTATUS smb_vfs_call_readdir_attr(struct vfs_handle_struct *handle,
2737 const struct smb_filename *fname,
2738 TALLOC_CTX *mem_ctx,
2739 struct readdir_attr_data **attr_data)
2741 VFS_FIND(readdir_attr);
2742 return handle->fns->readdir_attr_fn(handle, fname, mem_ctx, attr_data);