s3: smbd: Fix *allocate* calls to follow POSIX error return convention.
[Samba.git] / source3 / smbd / vfs.c
blobd10e0d67e905f7bd4a611e1ba8f04594a7b41e10
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 *)(e) + sizeof(struct vfs_fsp_data))
227 void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle,
228 files_struct *fsp, size_t ext_size,
229 void (*destroy_fn)(void *p_data))
231 struct vfs_fsp_data *ext;
232 void * ext_data;
234 /* Prevent VFS modules adding multiple extensions. */
235 if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
236 return ext_data;
239 ext = (struct vfs_fsp_data *)TALLOC_ZERO(
240 handle->conn, sizeof(struct vfs_fsp_data) + ext_size);
241 if (ext == NULL) {
242 return NULL;
245 ext->owner = handle;
246 ext->next = fsp->vfs_extension;
247 ext->destroy = destroy_fn;
248 fsp->vfs_extension = ext;
249 return EXT_DATA_AREA(ext);
252 void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
254 struct vfs_fsp_data *curr;
255 struct vfs_fsp_data *prev;
257 for (curr = fsp->vfs_extension, prev = NULL;
258 curr;
259 prev = curr, curr = curr->next) {
260 if (curr->owner == handle) {
261 if (prev) {
262 prev->next = curr->next;
263 } else {
264 fsp->vfs_extension = curr->next;
266 if (curr->destroy) {
267 curr->destroy(EXT_DATA_AREA(curr));
269 TALLOC_FREE(curr);
270 return;
275 void vfs_remove_all_fsp_extensions(files_struct *fsp)
277 struct vfs_fsp_data *curr;
278 struct vfs_fsp_data *next;
280 for (curr = fsp->vfs_extension; curr; curr = next) {
282 next = curr->next;
283 fsp->vfs_extension = next;
285 if (curr->destroy) {
286 curr->destroy(EXT_DATA_AREA(curr));
288 TALLOC_FREE(curr);
292 void *vfs_memctx_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
294 struct vfs_fsp_data *head;
296 for (head = fsp->vfs_extension; head; head = head->next) {
297 if (head->owner == handle) {
298 return head;
302 return NULL;
305 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp)
307 struct vfs_fsp_data *head;
309 head = (struct vfs_fsp_data *)vfs_memctx_fsp_extension(handle, fsp);
310 if (head != NULL) {
311 return EXT_DATA_AREA(head);
314 return NULL;
317 #undef EXT_DATA_AREA
319 /*****************************************************************
320 Generic VFS init.
321 ******************************************************************/
323 bool smbd_vfs_init(connection_struct *conn)
325 const char **vfs_objects;
326 unsigned int i = 0;
327 int j = 0;
329 /* Normal share - initialise with disk access functions */
330 vfs_init_default(conn);
332 /* No need to load vfs modules for printer connections */
333 if (conn->printer) {
334 return True;
337 vfs_objects = lp_vfs_objects(SNUM(conn));
339 /* Override VFS functions if 'vfs object' was not specified*/
340 if (!vfs_objects || !vfs_objects[0])
341 return True;
343 for (i=0; vfs_objects[i] ;) {
344 i++;
347 for (j=i-1; j >= 0; j--) {
348 if (!vfs_init_custom(conn, vfs_objects[j])) {
349 DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
350 return False;
353 return True;
356 /*******************************************************************
357 Check if a file exists in the vfs.
358 ********************************************************************/
360 NTSTATUS vfs_file_exist(connection_struct *conn, struct smb_filename *smb_fname)
362 /* Only return OK if stat was successful and S_ISREG */
363 if ((SMB_VFS_STAT(conn, smb_fname) != -1) &&
364 S_ISREG(smb_fname->st.st_ex_mode)) {
365 return NT_STATUS_OK;
368 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
371 /****************************************************************************
372 Read data from fsp on the vfs. (note: EINTR re-read differs from vfs_write_data)
373 ****************************************************************************/
375 ssize_t vfs_read_data(files_struct *fsp, char *buf, size_t byte_count)
377 size_t total=0;
379 while (total < byte_count)
381 ssize_t ret = SMB_VFS_READ(fsp, buf + total,
382 byte_count - total);
384 if (ret == 0) return total;
385 if (ret == -1) {
386 if (errno == EINTR)
387 continue;
388 else
389 return -1;
391 total += ret;
393 return (ssize_t)total;
396 /****************************************************************************
397 Write data to a fd on the vfs.
398 ****************************************************************************/
400 ssize_t vfs_write_data(struct smb_request *req,
401 files_struct *fsp,
402 const char *buffer,
403 size_t N)
405 size_t total=0;
406 ssize_t ret;
408 if (req && req->unread_bytes) {
409 int sockfd = req->xconn->transport.sock;
410 int old_flags;
411 SMB_ASSERT(req->unread_bytes == N);
412 /* VFS_RECVFILE must drain the socket
413 * before returning. */
414 req->unread_bytes = 0;
415 /* Ensure the socket is blocking. */
416 old_flags = fcntl(sockfd, F_GETFL, 0);
417 if (set_blocking(sockfd, true) == -1) {
418 return (ssize_t)-1;
420 ret = SMB_VFS_RECVFILE(sockfd,
421 fsp,
422 (off_t)-1,
424 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
425 return (ssize_t)-1;
427 return ret;
430 while (total < N) {
431 ret = SMB_VFS_WRITE(fsp, buffer + total, N - total);
433 if (ret == -1)
434 return -1;
435 if (ret == 0)
436 return total;
438 total += ret;
440 return (ssize_t)total;
443 ssize_t vfs_pwrite_data(struct smb_request *req,
444 files_struct *fsp,
445 const char *buffer,
446 size_t N,
447 off_t offset)
449 size_t total=0;
450 ssize_t ret;
452 if (req && req->unread_bytes) {
453 int sockfd = req->xconn->transport.sock;
454 SMB_ASSERT(req->unread_bytes == N);
455 /* VFS_RECVFILE must drain the socket
456 * before returning. */
457 req->unread_bytes = 0;
459 * Leave the socket non-blocking and
460 * use SMB_VFS_RECVFILE. If it returns
461 * EAGAIN || EWOULDBLOCK temporarily set
462 * the socket blocking and retry
463 * the RECVFILE.
465 while (total < N) {
466 ret = SMB_VFS_RECVFILE(sockfd,
467 fsp,
468 offset + total,
469 N - total);
470 if (ret == 0 || (ret == -1 &&
471 (errno == EAGAIN ||
472 errno == EWOULDBLOCK))) {
473 int old_flags;
474 /* Ensure the socket is blocking. */
475 old_flags = fcntl(sockfd, F_GETFL, 0);
476 if (set_blocking(sockfd, true) == -1) {
477 return (ssize_t)-1;
479 ret = SMB_VFS_RECVFILE(sockfd,
480 fsp,
481 offset + total,
482 N - total);
483 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
484 return (ssize_t)-1;
486 if (ret == -1) {
487 return (ssize_t)-1;
489 total += ret;
490 return (ssize_t)total;
492 /* Any other error case. */
493 if (ret == -1) {
494 return ret;
496 total += ret;
498 return (ssize_t)total;
501 while (total < N) {
502 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
503 offset + total);
505 if (ret == -1)
506 return -1;
507 if (ret == 0)
508 return total;
510 total += ret;
512 return (ssize_t)total;
514 /****************************************************************************
515 An allocate file space call using the vfs interface.
516 Allocates space for a file from a filedescriptor.
517 Returns 0 on success, -1 on failure.
518 ****************************************************************************/
520 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
522 int ret;
523 connection_struct *conn = fsp->conn;
524 uint64_t space_avail;
525 uint64_t bsize,dfree,dsize;
526 NTSTATUS status;
529 * Actually try and commit the space on disk....
532 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
533 fsp_str_dbg(fsp), (double)len));
535 if (((off_t)len) < 0) {
536 DEBUG(0,("vfs_allocate_file_space: %s negative len "
537 "requested.\n", fsp_str_dbg(fsp)));
538 errno = EINVAL;
539 return -1;
542 status = vfs_stat_fsp(fsp);
543 if (!NT_STATUS_IS_OK(status)) {
544 return -1;
547 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
548 return 0;
550 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
551 /* Shrink - use ftruncate. */
553 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
554 "size %.0f\n", fsp_str_dbg(fsp),
555 (double)fsp->fsp_name->st.st_ex_size));
557 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
559 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
560 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
561 set_filelen_write_cache(fsp, len);
564 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
566 return ret;
569 /* Grow - we need to test if we have enough space. */
571 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
573 if (lp_strict_allocate(SNUM(fsp->conn))) {
574 /* See if we have a syscall that will allocate beyond
575 end-of-file without changing EOF. */
576 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
577 } else {
578 ret = 0;
581 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
583 if (ret == 0) {
584 /* We changed the allocation size on disk, but not
585 EOF - exactly as required. We're done ! */
586 return 0;
589 if (ret == -1 && errno == ENOSPC) {
590 return -1;
593 len -= fsp->fsp_name->st.st_ex_size;
594 len /= 1024; /* Len is now number of 1k blocks needed. */
595 space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
596 &bsize, &dfree, &dsize);
597 if (space_avail == (uint64_t)-1) {
598 return -1;
601 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
602 "needed blocks = %.0f, space avail = %.0f\n",
603 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
604 (double)space_avail));
606 if (len > space_avail) {
607 errno = ENOSPC;
608 return -1;
611 return 0;
614 /****************************************************************************
615 A vfs set_filelen call.
616 set the length of a file from a filedescriptor.
617 Returns 0 on success, -1 on failure.
618 ****************************************************************************/
620 int vfs_set_filelen(files_struct *fsp, off_t len)
622 int ret;
624 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
626 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
627 fsp_str_dbg(fsp), (double)len));
628 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
629 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
630 set_filelen_write_cache(fsp, len);
631 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
632 FILE_NOTIFY_CHANGE_SIZE
633 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
634 fsp->fsp_name->base_name);
637 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
639 return ret;
642 /****************************************************************************
643 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
644 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
645 as this is also called from the default SMB_VFS_FTRUNCATE code.
646 Always extends the file size.
647 Returns 0 on success, -1 on failure.
648 ****************************************************************************/
650 #define SPARSE_BUF_WRITE_SIZE (32*1024)
652 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
654 ssize_t pwrite_ret;
655 size_t total = 0;
657 if (!sparse_buf) {
658 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
659 if (!sparse_buf) {
660 errno = ENOMEM;
661 return -1;
665 while (total < len) {
666 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
668 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
669 if (pwrite_ret == -1) {
670 int saved_errno = errno;
671 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
672 "%s failed with error %s\n",
673 fsp_str_dbg(fsp), strerror(saved_errno)));
674 errno = saved_errno;
675 return -1;
677 total += pwrite_ret;
680 return 0;
683 /****************************************************************************
684 A vfs fill sparse call.
685 Writes zeros from the end of file to len, if len is greater than EOF.
686 Used only by strict_sync.
687 Returns 0 on success, -1 on failure.
688 ****************************************************************************/
690 int vfs_fill_sparse(files_struct *fsp, off_t len)
692 int ret;
693 NTSTATUS status;
694 off_t offset;
695 size_t num_to_write;
697 status = vfs_stat_fsp(fsp);
698 if (!NT_STATUS_IS_OK(status)) {
699 return -1;
702 if (len <= fsp->fsp_name->st.st_ex_size) {
703 return 0;
706 #ifdef S_ISFIFO
707 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
708 return 0;
710 #endif
712 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
713 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
714 (double)fsp->fsp_name->st.st_ex_size, (double)len,
715 (double)(len - fsp->fsp_name->st.st_ex_size)));
717 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
719 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
721 offset = fsp->fsp_name->st.st_ex_size;
722 num_to_write = len - fsp->fsp_name->st.st_ex_size;
724 /* Only do this on non-stream file handles. */
725 if (fsp->base_fsp == NULL) {
726 /* for allocation try fallocate first. This can fail on some
727 * platforms e.g. when the filesystem doesn't support it and no
728 * emulation is being done by the libc (like on AIX with JFS1). In that
729 * case we do our own emulation. fallocate implementations can
730 * return ENOTSUP or EINVAL in cases like that. */
731 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
732 offset, num_to_write);
733 if (ret == -1 && errno == ENOSPC) {
734 goto out;
736 if (ret == 0) {
737 goto out;
739 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
740 "error %d. Falling back to slow manual allocation\n", ret));
743 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
745 out:
747 if (ret == 0) {
748 set_filelen_write_cache(fsp, len);
751 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
752 return ret;
755 /****************************************************************************
756 Transfer some data (n bytes) between two file_struct's.
757 ****************************************************************************/
759 static ssize_t vfs_read_fn(void *file, void *buf, size_t len)
761 struct files_struct *fsp = (struct files_struct *)file;
763 return SMB_VFS_READ(fsp, buf, len);
766 static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
768 struct files_struct *fsp = (struct files_struct *)file;
770 return SMB_VFS_WRITE(fsp, buf, len);
773 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
775 return transfer_file_internal((void *)in, (void *)out, n,
776 vfs_read_fn, vfs_write_fn);
779 /*******************************************************************
780 A vfs_readdir wrapper which just returns the file name.
781 ********************************************************************/
783 const char *vfs_readdirname(connection_struct *conn, void *p,
784 SMB_STRUCT_STAT *sbuf, char **talloced)
786 struct dirent *ptr= NULL;
787 const char *dname;
788 char *translated;
789 NTSTATUS status;
791 if (!p)
792 return(NULL);
794 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
795 if (!ptr)
796 return(NULL);
798 dname = ptr->d_name;
801 #ifdef NEXT2
802 if (telldir(p) < 0)
803 return(NULL);
804 #endif
806 #ifdef HAVE_BROKEN_READDIR_NAME
807 /* using /usr/ucb/cc is BAD */
808 dname = dname - 2;
809 #endif
811 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
812 talloc_tos(), &translated);
813 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
814 *talloced = NULL;
815 return dname;
817 *talloced = translated;
818 if (!NT_STATUS_IS_OK(status)) {
819 return NULL;
821 return translated;
824 /*******************************************************************
825 A wrapper for vfs_chdir().
826 ********************************************************************/
828 int vfs_ChDir(connection_struct *conn, const char *path)
830 int ret;
832 if (!LastDir) {
833 LastDir = SMB_STRDUP("");
836 if (ISDOT(path)) {
837 return 0;
840 if (*path == '/' && strcsequal(LastDir,path)) {
841 return 0;
844 DEBUG(4,("vfs_ChDir to %s\n",path));
846 ret = SMB_VFS_CHDIR(conn,path);
847 if (ret == 0) {
848 /* Global cache. */
849 SAFE_FREE(LastDir);
850 LastDir = SMB_STRDUP(path);
852 /* conn cache. */
853 TALLOC_FREE(conn->cwd);
854 conn->cwd = vfs_GetWd(conn, conn);
855 DEBUG(4,("vfs_ChDir got %s\n",conn->cwd));
857 return ret;
860 /*******************************************************************
861 Return the absolute current directory path - given a UNIX pathname.
862 Note that this path is returned in DOS format, not UNIX
863 format. Note this can be called with conn == NULL.
864 ********************************************************************/
866 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
868 char *current_dir = NULL;
869 char *result = NULL;
870 DATA_BLOB cache_value;
871 struct file_id key;
872 struct smb_filename *smb_fname_dot = NULL;
873 struct smb_filename *smb_fname_full = NULL;
875 if (!lp_getwd_cache()) {
876 goto nocache;
879 smb_fname_dot = synthetic_smb_fname(ctx, ".", NULL, NULL);
880 if (smb_fname_dot == NULL) {
881 errno = ENOMEM;
882 goto out;
885 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
887 * Known to fail for root: the directory may be NFS-mounted
888 * and exported with root_squash (so has no root access).
890 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
891 "(NFS problem ?)\n", strerror(errno) ));
892 goto nocache;
895 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
897 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
898 data_blob_const(&key, sizeof(key)),
899 &cache_value)) {
900 goto nocache;
903 SMB_ASSERT((cache_value.length > 0)
904 && (cache_value.data[cache_value.length-1] == '\0'));
906 smb_fname_full = synthetic_smb_fname(ctx, (char *)cache_value.data,
907 NULL, NULL);
908 if (smb_fname_full == NULL) {
909 errno = ENOMEM;
910 goto out;
913 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
914 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
915 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
916 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
918 * Ok, we're done
920 result = talloc_strdup(ctx, smb_fname_full->base_name);
921 if (result == NULL) {
922 errno = ENOMEM;
924 goto out;
927 nocache:
930 * We don't have the information to hand so rely on traditional
931 * methods. The very slow getcwd, which spawns a process on some
932 * systems, or the not quite so bad getwd.
935 current_dir = SMB_VFS_GETWD(conn);
936 if (current_dir == NULL) {
937 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
938 strerror(errno)));
939 goto out;
942 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
943 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
945 memcache_add(smbd_memcache(), GETWD_CACHE,
946 data_blob_const(&key, sizeof(key)),
947 data_blob_const(current_dir,
948 strlen(current_dir)+1));
951 result = talloc_strdup(ctx, current_dir);
952 if (result == NULL) {
953 errno = ENOMEM;
956 out:
957 TALLOC_FREE(smb_fname_dot);
958 TALLOC_FREE(smb_fname_full);
959 SAFE_FREE(current_dir);
960 return result;
963 /*******************************************************************
964 Reduce a file name, removing .. elements and checking that
965 it is below dir in the heirachy. This uses realpath.
966 This function must run as root, and will return names
967 and valid stat structs that can be checked on open.
968 ********************************************************************/
970 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
971 const char *fname,
972 struct smb_request *smbreq)
974 NTSTATUS status;
975 TALLOC_CTX *ctx = talloc_tos();
976 const char *conn_rootdir;
977 size_t rootdir_len;
978 char *dir_name = NULL;
979 const char *last_component = NULL;
980 char *resolved_name = NULL;
981 char *saved_dir = NULL;
982 struct smb_filename *smb_fname_cwd = NULL;
983 struct privilege_paths *priv_paths = NULL;
984 int ret;
986 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
987 fname,
988 conn->connectpath));
991 priv_paths = talloc_zero(smbreq, struct privilege_paths);
992 if (!priv_paths) {
993 status = NT_STATUS_NO_MEMORY;
994 goto err;
997 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
998 status = NT_STATUS_NO_MEMORY;
999 goto err;
1002 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
1003 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
1005 if (priv_paths->parent_name.base_name == NULL ||
1006 priv_paths->file_name.base_name == NULL) {
1007 status = NT_STATUS_NO_MEMORY;
1008 goto err;
1011 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
1012 status = map_nt_error_from_unix(errno);
1013 goto err;
1015 /* Remember where we were. */
1016 saved_dir = vfs_GetWd(ctx, conn);
1017 if (!saved_dir) {
1018 status = map_nt_error_from_unix(errno);
1019 goto err;
1022 /* Go to the parent directory to lock in memory. */
1023 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
1024 status = map_nt_error_from_unix(errno);
1025 goto err;
1028 /* Get the absolute path of the parent directory. */
1029 resolved_name = SMB_VFS_REALPATH(conn,".");
1030 if (!resolved_name) {
1031 status = map_nt_error_from_unix(errno);
1032 goto err;
1035 if (*resolved_name != '/') {
1036 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1037 "doesn't return absolute paths !\n"));
1038 status = NT_STATUS_OBJECT_NAME_INVALID;
1039 goto err;
1042 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1043 priv_paths->parent_name.base_name,
1044 resolved_name));
1046 /* Now check the stat value is the same. */
1047 smb_fname_cwd = synthetic_smb_fname(talloc_tos(), ".", NULL, NULL);
1048 if (smb_fname_cwd == NULL) {
1049 status = NT_STATUS_NO_MEMORY;
1050 goto err;
1053 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1054 status = map_nt_error_from_unix(errno);
1055 goto err;
1058 /* Ensure we're pointing at the same place. */
1059 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1060 DEBUG(0,("check_reduced_name_with_privilege: "
1061 "device/inode/uid/gid on directory %s changed. "
1062 "Denying access !\n",
1063 priv_paths->parent_name.base_name));
1064 status = NT_STATUS_ACCESS_DENIED;
1065 goto err;
1068 /* Ensure we're below the connect path. */
1070 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1071 if (conn_rootdir == NULL) {
1072 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1073 "conn_rootdir\n"));
1074 status = NT_STATUS_ACCESS_DENIED;
1075 goto err;
1078 rootdir_len = strlen(conn_rootdir);
1079 if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1080 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1081 "attempt: %s is a symlink outside the "
1082 "share path\n",
1083 dir_name));
1084 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1085 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1086 status = NT_STATUS_ACCESS_DENIED;
1087 goto err;
1090 /* Now ensure that the last component either doesn't
1091 exist, or is *NOT* a symlink. */
1093 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1094 if (ret == -1) {
1095 /* Errno must be ENOENT for this be ok. */
1096 if (errno != ENOENT) {
1097 status = map_nt_error_from_unix(errno);
1098 DEBUG(2, ("check_reduced_name_with_privilege: "
1099 "LSTAT on %s failed with %s\n",
1100 priv_paths->file_name.base_name,
1101 nt_errstr(status)));
1102 goto err;
1106 if (VALID_STAT(priv_paths->file_name.st) &&
1107 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1108 DEBUG(2, ("check_reduced_name_with_privilege: "
1109 "Last component %s is a symlink. Denying"
1110 "access.\n",
1111 priv_paths->file_name.base_name));
1112 status = NT_STATUS_ACCESS_DENIED;
1113 goto err;
1116 smbreq->priv_paths = priv_paths;
1117 status = NT_STATUS_OK;
1119 err:
1121 if (saved_dir) {
1122 vfs_ChDir(conn, saved_dir);
1124 SAFE_FREE(resolved_name);
1125 if (!NT_STATUS_IS_OK(status)) {
1126 TALLOC_FREE(priv_paths);
1128 TALLOC_FREE(dir_name);
1129 return status;
1132 /*******************************************************************
1133 Reduce a file name, removing .. elements and checking that
1134 it is below dir in the heirachy. This uses realpath.
1135 ********************************************************************/
1137 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1139 char *resolved_name = NULL;
1140 bool allow_symlinks = true;
1141 bool allow_widelinks = false;
1143 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1145 resolved_name = SMB_VFS_REALPATH(conn,fname);
1147 if (!resolved_name) {
1148 switch (errno) {
1149 case ENOTDIR:
1150 DEBUG(3,("check_reduced_name: Component not a "
1151 "directory in getting realpath for "
1152 "%s\n", fname));
1153 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1154 case ENOENT:
1156 TALLOC_CTX *ctx = talloc_tos();
1157 char *dir_name = NULL;
1158 const char *last_component = NULL;
1159 char *new_name = NULL;
1160 int ret;
1162 /* Last component didn't exist.
1163 Remove it and try and canonicalise
1164 the directory name. */
1165 if (!parent_dirname(ctx, fname,
1166 &dir_name,
1167 &last_component)) {
1168 return NT_STATUS_NO_MEMORY;
1171 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1172 if (!resolved_name) {
1173 NTSTATUS status = map_nt_error_from_unix(errno);
1175 if (errno == ENOENT || errno == ENOTDIR) {
1176 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1179 DEBUG(3,("check_reduce_name: "
1180 "couldn't get realpath for "
1181 "%s (%s)\n",
1182 fname,
1183 nt_errstr(status)));
1184 return status;
1186 ret = asprintf(&new_name, "%s/%s",
1187 resolved_name, last_component);
1188 SAFE_FREE(resolved_name);
1189 if (ret == -1) {
1190 return NT_STATUS_NO_MEMORY;
1192 resolved_name = new_name;
1193 break;
1195 default:
1196 DEBUG(3,("check_reduced_name: couldn't get "
1197 "realpath for %s\n", fname));
1198 return map_nt_error_from_unix(errno);
1202 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1203 resolved_name));
1205 if (*resolved_name != '/') {
1206 DEBUG(0,("check_reduced_name: realpath doesn't return "
1207 "absolute paths !\n"));
1208 SAFE_FREE(resolved_name);
1209 return NT_STATUS_OBJECT_NAME_INVALID;
1212 allow_widelinks = lp_widelinks(SNUM(conn));
1213 allow_symlinks = lp_follow_symlinks(SNUM(conn));
1215 /* Common widelinks and symlinks checks. */
1216 if (!allow_widelinks || !allow_symlinks) {
1217 const char *conn_rootdir;
1218 size_t rootdir_len;
1220 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1221 if (conn_rootdir == NULL) {
1222 DEBUG(2, ("check_reduced_name: Could not get "
1223 "conn_rootdir\n"));
1224 SAFE_FREE(resolved_name);
1225 return NT_STATUS_ACCESS_DENIED;
1228 rootdir_len = strlen(conn_rootdir);
1229 if (strncmp(conn_rootdir, resolved_name,
1230 rootdir_len) != 0) {
1231 DEBUG(2, ("check_reduced_name: Bad access "
1232 "attempt: %s is a symlink outside the "
1233 "share path\n", fname));
1234 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1235 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1236 SAFE_FREE(resolved_name);
1237 return NT_STATUS_ACCESS_DENIED;
1240 /* Extra checks if all symlinks are disallowed. */
1241 if (!allow_symlinks) {
1242 /* fname can't have changed in resolved_path. */
1243 const char *p = &resolved_name[rootdir_len];
1245 /* *p can be '\0' if fname was "." */
1246 if (*p == '\0' && ISDOT(fname)) {
1247 goto out;
1250 if (*p != '/') {
1251 DEBUG(2, ("check_reduced_name: logic error (%c) "
1252 "in resolved_name: %s\n",
1254 fname));
1255 SAFE_FREE(resolved_name);
1256 return NT_STATUS_ACCESS_DENIED;
1259 p++;
1260 if (strcmp(fname, p)!=0) {
1261 DEBUG(2, ("check_reduced_name: Bad access "
1262 "attempt: %s is a symlink to %s\n",
1263 fname, p));
1264 SAFE_FREE(resolved_name);
1265 return NT_STATUS_ACCESS_DENIED;
1270 out:
1272 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1273 resolved_name));
1274 SAFE_FREE(resolved_name);
1275 return NT_STATUS_OK;
1279 * XXX: This is temporary and there should be no callers of this once
1280 * smb_filename is plumbed through all path based operations.
1282 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1283 SMB_STRUCT_STAT *psbuf)
1285 struct smb_filename *smb_fname;
1286 int ret;
1288 smb_fname = synthetic_smb_fname_split(talloc_tos(), fname, NULL);
1289 if (smb_fname == NULL) {
1290 errno = ENOMEM;
1291 return -1;
1294 if (lp_posix_pathnames()) {
1295 ret = SMB_VFS_LSTAT(conn, smb_fname);
1296 } else {
1297 ret = SMB_VFS_STAT(conn, smb_fname);
1300 if (ret != -1) {
1301 *psbuf = smb_fname->st;
1304 TALLOC_FREE(smb_fname);
1305 return ret;
1309 * XXX: This is temporary and there should be no callers of this once
1310 * smb_filename is plumbed through all path based operations.
1312 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1313 SMB_STRUCT_STAT *psbuf)
1315 struct smb_filename *smb_fname;
1316 int ret;
1318 smb_fname = synthetic_smb_fname_split(talloc_tos(), fname, NULL);
1319 if (smb_fname == NULL) {
1320 errno = ENOMEM;
1321 return -1;
1324 ret = SMB_VFS_LSTAT(conn, smb_fname);
1325 if (ret != -1) {
1326 *psbuf = smb_fname->st;
1329 TALLOC_FREE(smb_fname);
1330 return ret;
1334 * Ensure LSTAT is called for POSIX paths.
1337 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1339 int ret;
1341 if(fsp->fh->fd == -1) {
1342 if (fsp->posix_open) {
1343 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1344 } else {
1345 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1347 if (ret == -1) {
1348 return map_nt_error_from_unix(errno);
1350 } else {
1351 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1352 return map_nt_error_from_unix(errno);
1355 return NT_STATUS_OK;
1359 * Initialize num_streams and streams, then call VFS op streaminfo
1361 NTSTATUS vfs_streaminfo(connection_struct *conn,
1362 struct files_struct *fsp,
1363 const char *fname,
1364 TALLOC_CTX *mem_ctx,
1365 unsigned int *num_streams,
1366 struct stream_struct **streams)
1368 *num_streams = 0;
1369 *streams = NULL;
1370 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1374 generate a file_id from a stat structure
1376 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1378 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1381 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1382 const char *service, const char *user)
1384 VFS_FIND(connect);
1385 return handle->fns->connect_fn(handle, service, user);
1388 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1390 VFS_FIND(disconnect);
1391 handle->fns->disconnect_fn(handle);
1394 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1395 const char *path, bool small_query,
1396 uint64_t *bsize, uint64_t *dfree,
1397 uint64_t *dsize)
1399 VFS_FIND(disk_free);
1400 return handle->fns->disk_free_fn(handle, path, small_query, bsize,
1401 dfree, dsize);
1404 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1405 enum SMB_QUOTA_TYPE qtype, unid_t id,
1406 SMB_DISK_QUOTA *qt)
1408 VFS_FIND(get_quota);
1409 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1412 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1413 enum SMB_QUOTA_TYPE qtype, unid_t id,
1414 SMB_DISK_QUOTA *qt)
1416 VFS_FIND(set_quota);
1417 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1420 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1421 struct files_struct *fsp,
1422 struct shadow_copy_data *shadow_copy_data,
1423 bool labels)
1425 VFS_FIND(get_shadow_copy_data);
1426 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1427 shadow_copy_data,
1428 labels);
1430 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1431 struct vfs_statvfs_struct *statbuf)
1433 VFS_FIND(statvfs);
1434 return handle->fns->statvfs_fn(handle, path, statbuf);
1437 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1438 enum timestamp_set_resolution *p_ts_res)
1440 VFS_FIND(fs_capabilities);
1441 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1444 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1445 struct dfs_GetDFSReferral *r)
1447 VFS_FIND(get_dfs_referrals);
1448 return handle->fns->get_dfs_referrals_fn(handle, r);
1451 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1452 const char *fname, const char *mask,
1453 uint32 attributes)
1455 VFS_FIND(opendir);
1456 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1459 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1460 struct files_struct *fsp,
1461 const char *mask,
1462 uint32 attributes)
1464 VFS_FIND(fdopendir);
1465 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1468 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1469 DIR *dirp,
1470 SMB_STRUCT_STAT *sbuf)
1472 VFS_FIND(readdir);
1473 return handle->fns->readdir_fn(handle, dirp, sbuf);
1476 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1477 DIR *dirp, long offset)
1479 VFS_FIND(seekdir);
1480 handle->fns->seekdir_fn(handle, dirp, offset);
1483 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1484 DIR *dirp)
1486 VFS_FIND(telldir);
1487 return handle->fns->telldir_fn(handle, dirp);
1490 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1491 DIR *dirp)
1493 VFS_FIND(rewind_dir);
1494 handle->fns->rewind_dir_fn(handle, dirp);
1497 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1498 mode_t mode)
1500 VFS_FIND(mkdir);
1501 return handle->fns->mkdir_fn(handle, path, mode);
1504 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1506 VFS_FIND(rmdir);
1507 return handle->fns->rmdir_fn(handle, path);
1510 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1511 DIR *dir)
1513 VFS_FIND(closedir);
1514 return handle->fns->closedir_fn(handle, dir);
1517 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1518 DIR *dirp)
1520 VFS_FIND(init_search_op);
1521 handle->fns->init_search_op_fn(handle, dirp);
1524 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1525 struct smb_filename *smb_fname, struct files_struct *fsp,
1526 int flags, mode_t mode)
1528 VFS_FIND(open);
1529 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1532 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1533 struct smb_request *req,
1534 uint16_t root_dir_fid,
1535 struct smb_filename *smb_fname,
1536 uint32_t access_mask,
1537 uint32_t share_access,
1538 uint32_t create_disposition,
1539 uint32_t create_options,
1540 uint32_t file_attributes,
1541 uint32_t oplock_request,
1542 struct smb2_lease *lease,
1543 uint64_t allocation_size,
1544 uint32_t private_flags,
1545 struct security_descriptor *sd,
1546 struct ea_list *ea_list,
1547 files_struct **result,
1548 int *pinfo,
1549 const struct smb2_create_blobs *in_context_blobs,
1550 struct smb2_create_blobs *out_context_blobs)
1552 VFS_FIND(create_file);
1553 return handle->fns->create_file_fn(
1554 handle, req, root_dir_fid, smb_fname, access_mask,
1555 share_access, create_disposition, create_options,
1556 file_attributes, oplock_request, lease, allocation_size,
1557 private_flags, sd, ea_list,
1558 result, pinfo, in_context_blobs, out_context_blobs);
1561 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1562 struct files_struct *fsp)
1564 VFS_FIND(close);
1565 return handle->fns->close_fn(handle, fsp);
1568 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1569 struct files_struct *fsp, void *data, size_t n)
1571 VFS_FIND(read);
1572 return handle->fns->read_fn(handle, fsp, data, n);
1575 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1576 struct files_struct *fsp, void *data, size_t n,
1577 off_t offset)
1579 VFS_FIND(pread);
1580 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1583 struct smb_vfs_call_pread_state {
1584 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1585 ssize_t retval;
1588 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1590 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1591 TALLOC_CTX *mem_ctx,
1592 struct tevent_context *ev,
1593 struct files_struct *fsp,
1594 void *data,
1595 size_t n, off_t offset)
1597 struct tevent_req *req, *subreq;
1598 struct smb_vfs_call_pread_state *state;
1600 req = tevent_req_create(mem_ctx, &state,
1601 struct smb_vfs_call_pread_state);
1602 if (req == NULL) {
1603 return NULL;
1605 VFS_FIND(pread_send);
1606 state->recv_fn = handle->fns->pread_recv_fn;
1608 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1609 offset);
1610 if (tevent_req_nomem(subreq, req)) {
1611 return tevent_req_post(req, ev);
1613 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1614 return req;
1617 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1619 struct tevent_req *req = tevent_req_callback_data(
1620 subreq, struct tevent_req);
1621 struct smb_vfs_call_pread_state *state = tevent_req_data(
1622 req, struct smb_vfs_call_pread_state);
1623 int err;
1625 state->retval = state->recv_fn(subreq, &err);
1626 TALLOC_FREE(subreq);
1627 if (state->retval == -1) {
1628 tevent_req_error(req, err);
1629 return;
1631 tevent_req_done(req);
1634 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req, int *perrno)
1636 struct smb_vfs_call_pread_state *state = tevent_req_data(
1637 req, struct smb_vfs_call_pread_state);
1638 int err;
1640 if (tevent_req_is_unix_error(req, &err)) {
1641 *perrno = err;
1642 return -1;
1644 return state->retval;
1647 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1648 struct files_struct *fsp, const void *data,
1649 size_t n)
1651 VFS_FIND(write);
1652 return handle->fns->write_fn(handle, fsp, data, n);
1655 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1656 struct files_struct *fsp, const void *data,
1657 size_t n, off_t offset)
1659 VFS_FIND(pwrite);
1660 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1663 struct smb_vfs_call_pwrite_state {
1664 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1665 ssize_t retval;
1668 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1670 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1671 TALLOC_CTX *mem_ctx,
1672 struct tevent_context *ev,
1673 struct files_struct *fsp,
1674 const void *data,
1675 size_t n, off_t offset)
1677 struct tevent_req *req, *subreq;
1678 struct smb_vfs_call_pwrite_state *state;
1680 req = tevent_req_create(mem_ctx, &state,
1681 struct smb_vfs_call_pwrite_state);
1682 if (req == NULL) {
1683 return NULL;
1685 VFS_FIND(pwrite_send);
1686 state->recv_fn = handle->fns->pwrite_recv_fn;
1688 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1689 offset);
1690 if (tevent_req_nomem(subreq, req)) {
1691 return tevent_req_post(req, ev);
1693 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1694 return req;
1697 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1699 struct tevent_req *req = tevent_req_callback_data(
1700 subreq, struct tevent_req);
1701 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1702 req, struct smb_vfs_call_pwrite_state);
1703 int err;
1705 state->retval = state->recv_fn(subreq, &err);
1706 TALLOC_FREE(subreq);
1707 if (state->retval == -1) {
1708 tevent_req_error(req, err);
1709 return;
1711 tevent_req_done(req);
1714 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req, int *perrno)
1716 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1717 req, struct smb_vfs_call_pwrite_state);
1718 int err;
1720 if (tevent_req_is_unix_error(req, &err)) {
1721 *perrno = err;
1722 return -1;
1724 return state->retval;
1727 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1728 struct files_struct *fsp, off_t offset,
1729 int whence)
1731 VFS_FIND(lseek);
1732 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1735 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1736 files_struct *fromfsp, const DATA_BLOB *header,
1737 off_t offset, size_t count)
1739 VFS_FIND(sendfile);
1740 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1741 count);
1744 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1745 files_struct *tofsp, off_t offset,
1746 size_t count)
1748 VFS_FIND(recvfile);
1749 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1752 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1753 const struct smb_filename *smb_fname_src,
1754 const struct smb_filename *smb_fname_dst)
1756 VFS_FIND(rename);
1757 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1760 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1761 struct files_struct *fsp)
1763 VFS_FIND(fsync);
1764 return handle->fns->fsync_fn(handle, fsp);
1767 struct smb_vfs_call_fsync_state {
1768 int (*recv_fn)(struct tevent_req *req, int *err);
1769 int retval;
1772 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1774 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1775 TALLOC_CTX *mem_ctx,
1776 struct tevent_context *ev,
1777 struct files_struct *fsp)
1779 struct tevent_req *req, *subreq;
1780 struct smb_vfs_call_fsync_state *state;
1782 req = tevent_req_create(mem_ctx, &state,
1783 struct smb_vfs_call_fsync_state);
1784 if (req == NULL) {
1785 return NULL;
1787 VFS_FIND(fsync_send);
1788 state->recv_fn = handle->fns->fsync_recv_fn;
1790 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1791 if (tevent_req_nomem(subreq, req)) {
1792 return tevent_req_post(req, ev);
1794 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1795 return req;
1798 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1800 struct tevent_req *req = tevent_req_callback_data(
1801 subreq, struct tevent_req);
1802 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1803 req, struct smb_vfs_call_fsync_state);
1804 int err;
1806 state->retval = state->recv_fn(subreq, &err);
1807 TALLOC_FREE(subreq);
1808 if (state->retval == -1) {
1809 tevent_req_error(req, err);
1810 return;
1812 tevent_req_done(req);
1815 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, int *perrno)
1817 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1818 req, struct smb_vfs_call_fsync_state);
1819 int err;
1821 if (tevent_req_is_unix_error(req, &err)) {
1822 *perrno = err;
1823 return -1;
1825 return state->retval;
1829 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1830 struct smb_filename *smb_fname)
1832 VFS_FIND(stat);
1833 return handle->fns->stat_fn(handle, smb_fname);
1836 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1837 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1839 VFS_FIND(fstat);
1840 return handle->fns->fstat_fn(handle, fsp, sbuf);
1843 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1844 struct smb_filename *smb_filename)
1846 VFS_FIND(lstat);
1847 return handle->fns->lstat_fn(handle, smb_filename);
1850 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1851 struct files_struct *fsp,
1852 const SMB_STRUCT_STAT *sbuf)
1854 VFS_FIND(get_alloc_size);
1855 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1858 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1859 const struct smb_filename *smb_fname)
1861 VFS_FIND(unlink);
1862 return handle->fns->unlink_fn(handle, smb_fname);
1865 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1866 mode_t mode)
1868 VFS_FIND(chmod);
1869 return handle->fns->chmod_fn(handle, path, mode);
1872 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1873 struct files_struct *fsp, mode_t mode)
1875 VFS_FIND(fchmod);
1876 return handle->fns->fchmod_fn(handle, fsp, mode);
1879 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1880 uid_t uid, gid_t gid)
1882 VFS_FIND(chown);
1883 return handle->fns->chown_fn(handle, path, uid, gid);
1886 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1887 struct files_struct *fsp, uid_t uid, gid_t gid)
1889 VFS_FIND(fchown);
1890 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1893 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1894 uid_t uid, gid_t gid)
1896 VFS_FIND(lchown);
1897 return handle->fns->lchown_fn(handle, path, uid, gid);
1900 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1902 int ret;
1903 bool as_root = false;
1904 const char *path;
1905 char *saved_dir = NULL;
1906 char *parent_dir = NULL;
1907 NTSTATUS status;
1909 if (fsp->fh->fd != -1) {
1910 /* Try fchown. */
1911 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1912 if (ret == 0) {
1913 return NT_STATUS_OK;
1915 if (ret == -1 && errno != ENOSYS) {
1916 return map_nt_error_from_unix(errno);
1920 as_root = (geteuid() == 0);
1922 if (as_root) {
1924 * We are being asked to chown as root. Make
1925 * sure we chdir() into the path to pin it,
1926 * and always act using lchown to ensure we
1927 * don't deref any symbolic links.
1929 const char *final_component = NULL;
1930 struct smb_filename local_fname;
1932 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1933 if (!saved_dir) {
1934 status = map_nt_error_from_unix(errno);
1935 DEBUG(0,("vfs_chown_fsp: failed to get "
1936 "current working directory. Error was %s\n",
1937 strerror(errno)));
1938 return status;
1941 if (!parent_dirname(talloc_tos(),
1942 fsp->fsp_name->base_name,
1943 &parent_dir,
1944 &final_component)) {
1945 return NT_STATUS_NO_MEMORY;
1948 /* cd into the parent dir to pin it. */
1949 ret = vfs_ChDir(fsp->conn, parent_dir);
1950 if (ret == -1) {
1951 return map_nt_error_from_unix(errno);
1954 ZERO_STRUCT(local_fname);
1955 local_fname.base_name = discard_const_p(char, final_component);
1957 /* Must use lstat here. */
1958 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1959 if (ret == -1) {
1960 status = map_nt_error_from_unix(errno);
1961 goto out;
1964 /* Ensure it matches the fsp stat. */
1965 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1966 status = NT_STATUS_ACCESS_DENIED;
1967 goto out;
1969 path = final_component;
1970 } else {
1971 path = fsp->fsp_name->base_name;
1974 if (fsp->posix_open || as_root) {
1975 ret = SMB_VFS_LCHOWN(fsp->conn,
1976 path,
1977 uid, gid);
1978 } else {
1979 ret = SMB_VFS_CHOWN(fsp->conn,
1980 path,
1981 uid, gid);
1984 if (ret == 0) {
1985 status = NT_STATUS_OK;
1986 } else {
1987 status = map_nt_error_from_unix(errno);
1990 out:
1992 if (as_root) {
1993 vfs_ChDir(fsp->conn,saved_dir);
1994 TALLOC_FREE(saved_dir);
1995 TALLOC_FREE(parent_dir);
1997 return status;
2000 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
2002 VFS_FIND(chdir);
2003 return handle->fns->chdir_fn(handle, path);
2006 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
2008 VFS_FIND(getwd);
2009 return handle->fns->getwd_fn(handle);
2012 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
2013 const struct smb_filename *smb_fname,
2014 struct smb_file_time *ft)
2016 VFS_FIND(ntimes);
2017 return handle->fns->ntimes_fn(handle, smb_fname, ft);
2020 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2021 struct files_struct *fsp, off_t offset)
2023 VFS_FIND(ftruncate);
2024 return handle->fns->ftruncate_fn(handle, fsp, offset);
2027 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2028 struct files_struct *fsp,
2029 enum vfs_fallocate_mode mode,
2030 off_t offset,
2031 off_t len)
2033 VFS_FIND(fallocate);
2034 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2037 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2038 struct files_struct *fsp, uint32 share_mode,
2039 uint32_t access_mask)
2041 VFS_FIND(kernel_flock);
2042 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2043 access_mask);
2046 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2047 struct files_struct *fsp, int leasetype)
2049 VFS_FIND(linux_setlease);
2050 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2053 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
2054 const char *newpath)
2056 VFS_FIND(symlink);
2057 return handle->fns->symlink_fn(handle, oldpath, newpath);
2060 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2061 const char *path, char *buf, size_t bufsiz)
2063 VFS_FIND(readlink);
2064 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
2067 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
2068 const char *newpath)
2070 VFS_FIND(link);
2071 return handle->fns->link_fn(handle, oldpath, newpath);
2074 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
2075 mode_t mode, SMB_DEV_T dev)
2077 VFS_FIND(mknod);
2078 return handle->fns->mknod_fn(handle, path, mode, dev);
2081 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
2083 VFS_FIND(realpath);
2084 return handle->fns->realpath_fn(handle, path);
2087 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
2088 struct sys_notify_context *ctx,
2089 const char *path,
2090 uint32_t *filter,
2091 uint32_t *subdir_filter,
2092 void (*callback)(struct sys_notify_context *ctx,
2093 void *private_data,
2094 struct notify_event *ev),
2095 void *private_data, void *handle_p)
2097 VFS_FIND(notify_watch);
2098 return handle->fns->notify_watch_fn(handle, ctx, path,
2099 filter, subdir_filter, callback,
2100 private_data, handle_p);
2103 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
2104 unsigned int flags)
2106 VFS_FIND(chflags);
2107 return handle->fns->chflags_fn(handle, path, flags);
2110 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2111 const SMB_STRUCT_STAT *sbuf)
2113 VFS_FIND(file_id_create);
2114 return handle->fns->file_id_create_fn(handle, sbuf);
2117 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2118 struct files_struct *fsp,
2119 const char *fname,
2120 TALLOC_CTX *mem_ctx,
2121 unsigned int *num_streams,
2122 struct stream_struct **streams)
2124 VFS_FIND(streaminfo);
2125 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
2126 num_streams, streams);
2129 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2130 const char *path, const char *name,
2131 TALLOC_CTX *mem_ctx, char **found_name)
2133 VFS_FIND(get_real_filename);
2134 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2135 found_name);
2138 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2139 const char *filename)
2141 VFS_FIND(connectpath);
2142 return handle->fns->connectpath_fn(handle, filename);
2145 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2146 struct files_struct *fsp,
2147 struct lock_struct *plock)
2149 VFS_FIND(strict_lock);
2150 return handle->fns->strict_lock_fn(handle, fsp, plock);
2153 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2154 struct files_struct *fsp,
2155 struct lock_struct *plock)
2157 VFS_FIND(strict_unlock);
2158 handle->fns->strict_unlock_fn(handle, fsp, plock);
2161 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2162 const char *name,
2163 enum vfs_translate_direction direction,
2164 TALLOC_CTX *mem_ctx,
2165 char **mapped_name)
2167 VFS_FIND(translate_name);
2168 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2169 mapped_name);
2172 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2173 struct files_struct *fsp,
2174 TALLOC_CTX *ctx,
2175 uint32_t function,
2176 uint16_t req_flags,
2177 const uint8_t *in_data,
2178 uint32_t in_len,
2179 uint8_t **out_data,
2180 uint32_t max_out_len,
2181 uint32_t *out_len)
2183 VFS_FIND(fsctl);
2184 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2185 in_data, in_len, out_data, max_out_len,
2186 out_len);
2189 struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle,
2190 TALLOC_CTX *mem_ctx,
2191 struct tevent_context *ev,
2192 struct files_struct *src_fsp,
2193 off_t src_off,
2194 struct files_struct *dest_fsp,
2195 off_t dest_off,
2196 off_t num)
2198 VFS_FIND(copy_chunk_send);
2199 return handle->fns->copy_chunk_send_fn(handle, mem_ctx, ev, src_fsp,
2200 src_off, dest_fsp, dest_off, num);
2203 NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,
2204 struct tevent_req *req,
2205 off_t *copied)
2207 VFS_FIND(copy_chunk_recv);
2208 return handle->fns->copy_chunk_recv_fn(handle, req, copied);
2211 NTSTATUS smb_vfs_call_get_compression(vfs_handle_struct *handle,
2212 TALLOC_CTX *mem_ctx,
2213 struct files_struct *fsp,
2214 struct smb_filename *smb_fname,
2215 uint16_t *_compression_fmt)
2217 VFS_FIND(get_compression);
2218 return handle->fns->get_compression_fn(handle, mem_ctx, fsp, smb_fname,
2219 _compression_fmt);
2222 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2223 TALLOC_CTX *mem_ctx,
2224 struct files_struct *fsp,
2225 uint16_t compression_fmt)
2227 VFS_FIND(set_compression);
2228 return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2229 compression_fmt);
2232 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2233 struct files_struct *fsp,
2234 uint32 security_info,
2235 TALLOC_CTX *mem_ctx,
2236 struct security_descriptor **ppdesc)
2238 VFS_FIND(fget_nt_acl);
2239 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2240 mem_ctx, ppdesc);
2243 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2244 const char *name,
2245 uint32 security_info,
2246 TALLOC_CTX *mem_ctx,
2247 struct security_descriptor **ppdesc)
2249 VFS_FIND(get_nt_acl);
2250 return handle->fns->get_nt_acl_fn(handle, name, security_info, mem_ctx, ppdesc);
2253 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2254 struct files_struct *fsp,
2255 uint32 security_info_sent,
2256 const struct security_descriptor *psd)
2258 VFS_FIND(fset_nt_acl);
2259 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2260 psd);
2263 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2264 struct smb_filename *file,
2265 struct security_acl *sacl,
2266 uint32_t access_requested,
2267 uint32_t access_denied)
2269 VFS_FIND(audit_file);
2270 return handle->fns->audit_file_fn(handle,
2271 file,
2272 sacl,
2273 access_requested,
2274 access_denied);
2277 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2278 mode_t mode)
2280 VFS_FIND(chmod_acl);
2281 return handle->fns->chmod_acl_fn(handle, name, mode);
2284 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2285 struct files_struct *fsp, mode_t mode)
2287 VFS_FIND(fchmod_acl);
2288 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2291 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2292 const char *path_p,
2293 SMB_ACL_TYPE_T type,
2294 TALLOC_CTX *mem_ctx)
2296 VFS_FIND(sys_acl_get_file);
2297 return handle->fns->sys_acl_get_file_fn(handle, path_p, type, mem_ctx);
2300 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2301 struct files_struct *fsp,
2302 TALLOC_CTX *mem_ctx)
2304 VFS_FIND(sys_acl_get_fd);
2305 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2308 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2309 const char *path_p,
2310 TALLOC_CTX *mem_ctx,
2311 char **blob_description,
2312 DATA_BLOB *blob)
2314 VFS_FIND(sys_acl_blob_get_file);
2315 return handle->fns->sys_acl_blob_get_file_fn(handle, path_p, mem_ctx, blob_description, blob);
2318 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2319 struct files_struct *fsp,
2320 TALLOC_CTX *mem_ctx,
2321 char **blob_description,
2322 DATA_BLOB *blob)
2324 VFS_FIND(sys_acl_blob_get_fd);
2325 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2328 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2329 const char *name, SMB_ACL_TYPE_T acltype,
2330 SMB_ACL_T theacl)
2332 VFS_FIND(sys_acl_set_file);
2333 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2336 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2337 struct files_struct *fsp, SMB_ACL_T theacl)
2339 VFS_FIND(sys_acl_set_fd);
2340 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2343 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2344 const char *path)
2346 VFS_FIND(sys_acl_delete_def_file);
2347 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2350 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2351 const char *path, const char *name, void *value,
2352 size_t size)
2354 VFS_FIND(getxattr);
2355 return handle->fns->getxattr_fn(handle, path, name, value, size);
2358 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2359 struct files_struct *fsp, const char *name,
2360 void *value, size_t size)
2362 VFS_FIND(fgetxattr);
2363 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2366 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2367 const char *path, char *list, size_t size)
2369 VFS_FIND(listxattr);
2370 return handle->fns->listxattr_fn(handle, path, list, size);
2373 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2374 struct files_struct *fsp, char *list,
2375 size_t size)
2377 VFS_FIND(flistxattr);
2378 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2381 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2382 const char *path, const char *name)
2384 VFS_FIND(removexattr);
2385 return handle->fns->removexattr_fn(handle, path, name);
2388 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2389 struct files_struct *fsp, const char *name)
2391 VFS_FIND(fremovexattr);
2392 return handle->fns->fremovexattr_fn(handle, fsp, name);
2395 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2396 const char *name, const void *value, size_t size,
2397 int flags)
2399 VFS_FIND(setxattr);
2400 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2403 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2404 struct files_struct *fsp, const char *name,
2405 const void *value, size_t size, int flags)
2407 VFS_FIND(fsetxattr);
2408 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2411 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2412 struct files_struct *fsp)
2414 VFS_FIND(aio_force);
2415 return handle->fns->aio_force_fn(handle, fsp);
2418 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2419 const struct smb_filename *fname,
2420 SMB_STRUCT_STAT *sbuf)
2422 VFS_FIND(is_offline);
2423 return handle->fns->is_offline_fn(handle, fname, sbuf);
2426 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2427 const struct smb_filename *fname)
2429 VFS_FIND(set_offline);
2430 return handle->fns->set_offline_fn(handle, fname);
2433 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2434 struct files_struct *fsp,
2435 TALLOC_CTX *mem_ctx,
2436 DATA_BLOB *cookie)
2438 VFS_FIND(durable_cookie);
2439 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2442 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2443 struct files_struct *fsp,
2444 const DATA_BLOB old_cookie,
2445 TALLOC_CTX *mem_ctx,
2446 DATA_BLOB *new_cookie)
2448 VFS_FIND(durable_disconnect);
2449 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2450 mem_ctx, new_cookie);
2453 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2454 struct smb_request *smb1req,
2455 struct smbXsrv_open *op,
2456 const DATA_BLOB old_cookie,
2457 TALLOC_CTX *mem_ctx,
2458 struct files_struct **fsp,
2459 DATA_BLOB *new_cookie)
2461 VFS_FIND(durable_reconnect);
2462 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2463 old_cookie, mem_ctx, fsp,
2464 new_cookie);
2467 NTSTATUS smb_vfs_call_readdir_attr(struct vfs_handle_struct *handle,
2468 const struct smb_filename *fname,
2469 TALLOC_CTX *mem_ctx,
2470 struct readdir_attr_data **attr_data)
2472 VFS_FIND(readdir_attr);
2473 return handle->fns->readdir_attr_fn(handle, fname, mem_ctx, attr_data);