Add tiniparser - tiny version of iniparser that only implements what Samba uses.
[Samba.git] / source3 / smbd / vfs.c
blob744db7ad7d9c7fe16c5fb7a96d817d54ba8cc496
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 defined(EWOULDBLOCK)
471 if (ret == 0 || (ret == -1 &&
472 (errno == EAGAIN || errno == EWOULDBLOCK))) {
473 #else /* EWOULDBLOCK */
474 if (ret == 0 || (ret == -1 && errno == EAGAIN)) {
475 #endif /* EWOULDBLOCK */
476 int old_flags;
477 /* Ensure the socket is blocking. */
478 old_flags = fcntl(sockfd, F_GETFL, 0);
479 if (set_blocking(sockfd, true) == -1) {
480 return (ssize_t)-1;
482 ret = SMB_VFS_RECVFILE(sockfd,
483 fsp,
484 offset + total,
485 N - total);
486 if (fcntl(sockfd, F_SETFL, old_flags) == -1) {
487 return (ssize_t)-1;
489 if (ret == -1) {
490 return (ssize_t)-1;
492 total += ret;
493 return (ssize_t)total;
495 /* Any other error case. */
496 if (ret == -1) {
497 return ret;
499 total += ret;
501 return (ssize_t)total;
504 while (total < N) {
505 ret = SMB_VFS_PWRITE(fsp, buffer + total, N - total,
506 offset + total);
508 if (ret == -1)
509 return -1;
510 if (ret == 0)
511 return total;
513 total += ret;
515 return (ssize_t)total;
517 /****************************************************************************
518 An allocate file space call using the vfs interface.
519 Allocates space for a file from a filedescriptor.
520 Returns 0 on success, -1 on failure.
521 ****************************************************************************/
523 int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
525 int ret;
526 connection_struct *conn = fsp->conn;
527 uint64_t space_avail;
528 uint64_t bsize,dfree,dsize;
529 NTSTATUS status;
532 * Actually try and commit the space on disk....
535 DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n",
536 fsp_str_dbg(fsp), (double)len));
538 if (((off_t)len) < 0) {
539 DEBUG(0,("vfs_allocate_file_space: %s negative len "
540 "requested.\n", fsp_str_dbg(fsp)));
541 errno = EINVAL;
542 return -1;
545 status = vfs_stat_fsp(fsp);
546 if (!NT_STATUS_IS_OK(status)) {
547 return -1;
550 if (len == (uint64_t)fsp->fsp_name->st.st_ex_size)
551 return 0;
553 if (len < (uint64_t)fsp->fsp_name->st.st_ex_size) {
554 /* Shrink - use ftruncate. */
556 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current "
557 "size %.0f\n", fsp_str_dbg(fsp),
558 (double)fsp->fsp_name->st.st_ex_size));
560 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
562 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
563 if ((ret = SMB_VFS_FTRUNCATE(fsp, (off_t)len)) != -1) {
564 set_filelen_write_cache(fsp, len);
567 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_SHRINK);
569 return ret;
572 /* Grow - we need to test if we have enough space. */
574 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
576 if (lp_strict_allocate(SNUM(fsp->conn))) {
577 /* See if we have a syscall that will allocate beyond
578 end-of-file without changing EOF. */
579 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
580 } else {
581 ret = 0;
584 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
586 if (ret == 0) {
587 /* We changed the allocation size on disk, but not
588 EOF - exactly as required. We're done ! */
589 return 0;
592 len -= fsp->fsp_name->st.st_ex_size;
593 len /= 1024; /* Len is now number of 1k blocks needed. */
594 space_avail = get_dfree_info(conn, fsp->fsp_name->base_name, false,
595 &bsize, &dfree, &dsize);
596 if (space_avail == (uint64_t)-1) {
597 return -1;
600 DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, "
601 "needed blocks = %.0f, space avail = %.0f\n",
602 fsp_str_dbg(fsp), (double)fsp->fsp_name->st.st_ex_size, (double)len,
603 (double)space_avail));
605 if (len > space_avail) {
606 errno = ENOSPC;
607 return -1;
610 return 0;
613 /****************************************************************************
614 A vfs set_filelen call.
615 set the length of a file from a filedescriptor.
616 Returns 0 on success, -1 on failure.
617 ****************************************************************************/
619 int vfs_set_filelen(files_struct *fsp, off_t len)
621 int ret;
623 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
625 DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n",
626 fsp_str_dbg(fsp), (double)len));
627 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
628 if ((ret = SMB_VFS_FTRUNCATE(fsp, len)) != -1) {
629 set_filelen_write_cache(fsp, len);
630 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
631 FILE_NOTIFY_CHANGE_SIZE
632 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
633 fsp->fsp_name->base_name);
636 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_SET_FILE_LEN);
638 return ret;
641 /****************************************************************************
642 A slow version of fallocate. Fallback code if SMB_VFS_FALLOCATE
643 fails. Needs to be outside of the default version of SMB_VFS_FALLOCATE
644 as this is also called from the default SMB_VFS_FTRUNCATE code.
645 Always extends the file size.
646 Returns 0 on success, errno on failure.
647 ****************************************************************************/
649 #define SPARSE_BUF_WRITE_SIZE (32*1024)
651 int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len)
653 ssize_t pwrite_ret;
654 size_t total = 0;
656 if (!sparse_buf) {
657 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
658 if (!sparse_buf) {
659 errno = ENOMEM;
660 return ENOMEM;
664 while (total < len) {
665 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total));
667 pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total);
668 if (pwrite_ret == -1) {
669 DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file "
670 "%s failed with error %s\n",
671 fsp_str_dbg(fsp), strerror(errno)));
672 return errno;
674 total += pwrite_ret;
677 return 0;
680 /****************************************************************************
681 A vfs fill sparse call.
682 Writes zeros from the end of file to len, if len is greater than EOF.
683 Used only by strict_sync.
684 Returns 0 on success, -1 on failure.
685 ****************************************************************************/
687 int vfs_fill_sparse(files_struct *fsp, off_t len)
689 int ret;
690 NTSTATUS status;
691 off_t offset;
692 size_t num_to_write;
694 status = vfs_stat_fsp(fsp);
695 if (!NT_STATUS_IS_OK(status)) {
696 return -1;
699 if (len <= fsp->fsp_name->st.st_ex_size) {
700 return 0;
703 #ifdef S_ISFIFO
704 if (S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
705 return 0;
707 #endif
709 DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
710 "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
711 (double)fsp->fsp_name->st.st_ex_size, (double)len,
712 (double)(len - fsp->fsp_name->st.st_ex_size)));
714 contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_FILL_SPARSE);
716 flush_write_cache(fsp, SAMBA_SIZECHANGE_FLUSH);
718 offset = fsp->fsp_name->st.st_ex_size;
719 num_to_write = len - fsp->fsp_name->st.st_ex_size;
721 /* Only do this on non-stream file handles. */
722 if (fsp->base_fsp == NULL) {
723 /* for allocation try fallocate first. This can fail on some
724 * platforms e.g. when the filesystem doesn't support it and no
725 * emulation is being done by the libc (like on AIX with JFS1). In that
726 * case we do our own emulation. fallocate implementations can
727 * return ENOTSUP or EINVAL in cases like that. */
728 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
729 offset, num_to_write);
730 if (ret == ENOSPC) {
731 errno = ENOSPC;
732 ret = -1;
733 goto out;
735 if (ret == 0) {
736 goto out;
738 DEBUG(10,("vfs_fill_sparse: SMB_VFS_FALLOCATE failed with "
739 "error %d. Falling back to slow manual allocation\n", ret));
742 ret = vfs_slow_fallocate(fsp, offset, num_to_write);
743 if (ret != 0) {
744 errno = ret;
745 ret = -1;
748 out:
750 if (ret == 0) {
751 set_filelen_write_cache(fsp, len);
754 contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE);
755 return ret;
758 /****************************************************************************
759 Transfer some data (n bytes) between two file_struct's.
760 ****************************************************************************/
762 static ssize_t vfs_read_fn(void *file, void *buf, size_t len)
764 struct files_struct *fsp = (struct files_struct *)file;
766 return SMB_VFS_READ(fsp, buf, len);
769 static ssize_t vfs_write_fn(void *file, const void *buf, size_t len)
771 struct files_struct *fsp = (struct files_struct *)file;
773 return SMB_VFS_WRITE(fsp, buf, len);
776 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
778 return transfer_file_internal((void *)in, (void *)out, n,
779 vfs_read_fn, vfs_write_fn);
782 /*******************************************************************
783 A vfs_readdir wrapper which just returns the file name.
784 ********************************************************************/
786 const char *vfs_readdirname(connection_struct *conn, void *p,
787 SMB_STRUCT_STAT *sbuf, char **talloced)
789 struct dirent *ptr= NULL;
790 const char *dname;
791 char *translated;
792 NTSTATUS status;
794 if (!p)
795 return(NULL);
797 ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
798 if (!ptr)
799 return(NULL);
801 dname = ptr->d_name;
804 #ifdef NEXT2
805 if (telldir(p) < 0)
806 return(NULL);
807 #endif
809 #ifdef HAVE_BROKEN_READDIR_NAME
810 /* using /usr/ucb/cc is BAD */
811 dname = dname - 2;
812 #endif
814 status = SMB_VFS_TRANSLATE_NAME(conn, dname, vfs_translate_to_windows,
815 talloc_tos(), &translated);
816 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
817 *talloced = NULL;
818 return dname;
820 *talloced = translated;
821 if (!NT_STATUS_IS_OK(status)) {
822 return NULL;
824 return translated;
827 /*******************************************************************
828 A wrapper for vfs_chdir().
829 ********************************************************************/
831 int vfs_ChDir(connection_struct *conn, const char *path)
833 int ret;
835 if (!LastDir) {
836 LastDir = SMB_STRDUP("");
839 if (ISDOT(path)) {
840 return 0;
843 if (*path == '/' && strcsequal(LastDir,path)) {
844 return 0;
847 DEBUG(4,("vfs_ChDir to %s\n",path));
849 ret = SMB_VFS_CHDIR(conn,path);
850 if (ret == 0) {
851 /* Global cache. */
852 SAFE_FREE(LastDir);
853 LastDir = SMB_STRDUP(path);
855 /* conn cache. */
856 TALLOC_FREE(conn->cwd);
857 conn->cwd = vfs_GetWd(conn, conn);
858 DEBUG(4,("vfs_ChDir got %s\n",conn->cwd));
860 return ret;
863 /*******************************************************************
864 Return the absolute current directory path - given a UNIX pathname.
865 Note that this path is returned in DOS format, not UNIX
866 format. Note this can be called with conn == NULL.
867 ********************************************************************/
869 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn)
871 char *current_dir = NULL;
872 char *result = NULL;
873 DATA_BLOB cache_value;
874 struct file_id key;
875 struct smb_filename *smb_fname_dot = NULL;
876 struct smb_filename *smb_fname_full = NULL;
878 if (!lp_getwd_cache()) {
879 goto nocache;
882 smb_fname_dot = synthetic_smb_fname(ctx, ".", NULL, NULL);
883 if (smb_fname_dot == NULL) {
884 errno = ENOMEM;
885 goto out;
888 if (SMB_VFS_STAT(conn, smb_fname_dot) == -1) {
890 * Known to fail for root: the directory may be NFS-mounted
891 * and exported with root_squash (so has no root access).
893 DEBUG(1,("vfs_GetWd: couldn't stat \".\" error %s "
894 "(NFS problem ?)\n", strerror(errno) ));
895 goto nocache;
898 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
900 if (!memcache_lookup(smbd_memcache(), GETWD_CACHE,
901 data_blob_const(&key, sizeof(key)),
902 &cache_value)) {
903 goto nocache;
906 SMB_ASSERT((cache_value.length > 0)
907 && (cache_value.data[cache_value.length-1] == '\0'));
909 smb_fname_full = synthetic_smb_fname(ctx, (char *)cache_value.data,
910 NULL, NULL);
911 if (smb_fname_full == NULL) {
912 errno = ENOMEM;
913 goto out;
916 if ((SMB_VFS_STAT(conn, smb_fname_full) == 0) &&
917 (smb_fname_dot->st.st_ex_dev == smb_fname_full->st.st_ex_dev) &&
918 (smb_fname_dot->st.st_ex_ino == smb_fname_full->st.st_ex_ino) &&
919 (S_ISDIR(smb_fname_dot->st.st_ex_mode))) {
921 * Ok, we're done
923 result = talloc_strdup(ctx, smb_fname_full->base_name);
924 if (result == NULL) {
925 errno = ENOMEM;
927 goto out;
930 nocache:
933 * We don't have the information to hand so rely on traditional
934 * methods. The very slow getcwd, which spawns a process on some
935 * systems, or the not quite so bad getwd.
938 current_dir = SMB_VFS_GETWD(conn);
939 if (current_dir == NULL) {
940 DEBUG(0, ("vfs_GetWd: SMB_VFS_GETWD call failed: %s\n",
941 strerror(errno)));
942 goto out;
945 if (lp_getwd_cache() && VALID_STAT(smb_fname_dot->st)) {
946 key = vfs_file_id_from_sbuf(conn, &smb_fname_dot->st);
948 memcache_add(smbd_memcache(), GETWD_CACHE,
949 data_blob_const(&key, sizeof(key)),
950 data_blob_const(current_dir,
951 strlen(current_dir)+1));
954 result = talloc_strdup(ctx, current_dir);
955 if (result == NULL) {
956 errno = ENOMEM;
959 out:
960 TALLOC_FREE(smb_fname_dot);
961 TALLOC_FREE(smb_fname_full);
962 SAFE_FREE(current_dir);
963 return result;
966 /*******************************************************************
967 Reduce a file name, removing .. elements and checking that
968 it is below dir in the heirachy. This uses realpath.
969 This function must run as root, and will return names
970 and valid stat structs that can be checked on open.
971 ********************************************************************/
973 NTSTATUS check_reduced_name_with_privilege(connection_struct *conn,
974 const char *fname,
975 struct smb_request *smbreq)
977 NTSTATUS status;
978 TALLOC_CTX *ctx = talloc_tos();
979 const char *conn_rootdir;
980 size_t rootdir_len;
981 char *dir_name = NULL;
982 const char *last_component = NULL;
983 char *resolved_name = NULL;
984 char *saved_dir = NULL;
985 struct smb_filename *smb_fname_cwd = NULL;
986 struct privilege_paths *priv_paths = NULL;
987 int ret;
989 DEBUG(3,("check_reduced_name_with_privilege [%s] [%s]\n",
990 fname,
991 conn->connectpath));
994 priv_paths = talloc_zero(smbreq, struct privilege_paths);
995 if (!priv_paths) {
996 status = NT_STATUS_NO_MEMORY;
997 goto err;
1000 if (!parent_dirname(ctx, fname, &dir_name, &last_component)) {
1001 status = NT_STATUS_NO_MEMORY;
1002 goto err;
1005 priv_paths->parent_name.base_name = talloc_strdup(priv_paths, dir_name);
1006 priv_paths->file_name.base_name = talloc_strdup(priv_paths, last_component);
1008 if (priv_paths->parent_name.base_name == NULL ||
1009 priv_paths->file_name.base_name == NULL) {
1010 status = NT_STATUS_NO_MEMORY;
1011 goto err;
1014 if (SMB_VFS_STAT(conn, &priv_paths->parent_name) != 0) {
1015 status = map_nt_error_from_unix(errno);
1016 goto err;
1018 /* Remember where we were. */
1019 saved_dir = vfs_GetWd(ctx, conn);
1020 if (!saved_dir) {
1021 status = map_nt_error_from_unix(errno);
1022 goto err;
1025 /* Go to the parent directory to lock in memory. */
1026 if (vfs_ChDir(conn, priv_paths->parent_name.base_name) == -1) {
1027 status = map_nt_error_from_unix(errno);
1028 goto err;
1031 /* Get the absolute path of the parent directory. */
1032 resolved_name = SMB_VFS_REALPATH(conn,".");
1033 if (!resolved_name) {
1034 status = map_nt_error_from_unix(errno);
1035 goto err;
1038 if (*resolved_name != '/') {
1039 DEBUG(0,("check_reduced_name_with_privilege: realpath "
1040 "doesn't return absolute paths !\n"));
1041 status = NT_STATUS_OBJECT_NAME_INVALID;
1042 goto err;
1045 DEBUG(10,("check_reduced_name_with_privilege: realpath [%s] -> [%s]\n",
1046 priv_paths->parent_name.base_name,
1047 resolved_name));
1049 /* Now check the stat value is the same. */
1050 smb_fname_cwd = synthetic_smb_fname(talloc_tos(), ".", NULL, NULL);
1051 if (smb_fname_cwd == NULL) {
1052 status = NT_STATUS_NO_MEMORY;
1053 goto err;
1056 if (SMB_VFS_LSTAT(conn, smb_fname_cwd) != 0) {
1057 status = map_nt_error_from_unix(errno);
1058 goto err;
1061 /* Ensure we're pointing at the same place. */
1062 if (!check_same_stat(&smb_fname_cwd->st, &priv_paths->parent_name.st)) {
1063 DEBUG(0,("check_reduced_name_with_privilege: "
1064 "device/inode/uid/gid on directory %s changed. "
1065 "Denying access !\n",
1066 priv_paths->parent_name.base_name));
1067 status = NT_STATUS_ACCESS_DENIED;
1068 goto err;
1071 /* Ensure we're below the connect path. */
1073 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1074 if (conn_rootdir == NULL) {
1075 DEBUG(2, ("check_reduced_name_with_privilege: Could not get "
1076 "conn_rootdir\n"));
1077 status = NT_STATUS_ACCESS_DENIED;
1078 goto err;
1081 rootdir_len = strlen(conn_rootdir);
1082 if (strncmp(conn_rootdir, resolved_name, rootdir_len) != 0) {
1083 DEBUG(2, ("check_reduced_name_with_privilege: Bad access "
1084 "attempt: %s is a symlink outside the "
1085 "share path\n",
1086 dir_name));
1087 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1088 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1089 status = NT_STATUS_ACCESS_DENIED;
1090 goto err;
1093 /* Now ensure that the last component either doesn't
1094 exist, or is *NOT* a symlink. */
1096 ret = SMB_VFS_LSTAT(conn, &priv_paths->file_name);
1097 if (ret == -1) {
1098 /* Errno must be ENOENT for this be ok. */
1099 if (errno != ENOENT) {
1100 status = map_nt_error_from_unix(errno);
1101 DEBUG(2, ("check_reduced_name_with_privilege: "
1102 "LSTAT on %s failed with %s\n",
1103 priv_paths->file_name.base_name,
1104 nt_errstr(status)));
1105 goto err;
1109 if (VALID_STAT(priv_paths->file_name.st) &&
1110 S_ISLNK(priv_paths->file_name.st.st_ex_mode)) {
1111 DEBUG(2, ("check_reduced_name_with_privilege: "
1112 "Last component %s is a symlink. Denying"
1113 "access.\n",
1114 priv_paths->file_name.base_name));
1115 status = NT_STATUS_ACCESS_DENIED;
1116 goto err;
1119 smbreq->priv_paths = priv_paths;
1120 status = NT_STATUS_OK;
1122 err:
1124 if (saved_dir) {
1125 vfs_ChDir(conn, saved_dir);
1127 SAFE_FREE(resolved_name);
1128 if (!NT_STATUS_IS_OK(status)) {
1129 TALLOC_FREE(priv_paths);
1131 TALLOC_FREE(dir_name);
1132 return status;
1135 /*******************************************************************
1136 Reduce a file name, removing .. elements and checking that
1137 it is below dir in the heirachy. This uses realpath.
1138 ********************************************************************/
1140 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname)
1142 char *resolved_name = NULL;
1143 bool allow_symlinks = true;
1144 bool allow_widelinks = false;
1146 DEBUG(3,("check_reduced_name [%s] [%s]\n", fname, conn->connectpath));
1148 resolved_name = SMB_VFS_REALPATH(conn,fname);
1150 if (!resolved_name) {
1151 switch (errno) {
1152 case ENOTDIR:
1153 DEBUG(3,("check_reduced_name: Component not a "
1154 "directory in getting realpath for "
1155 "%s\n", fname));
1156 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1157 case ENOENT:
1159 TALLOC_CTX *ctx = talloc_tos();
1160 char *dir_name = NULL;
1161 const char *last_component = NULL;
1162 char *new_name = NULL;
1163 int ret;
1165 /* Last component didn't exist.
1166 Remove it and try and canonicalise
1167 the directory name. */
1168 if (!parent_dirname(ctx, fname,
1169 &dir_name,
1170 &last_component)) {
1171 return NT_STATUS_NO_MEMORY;
1174 resolved_name = SMB_VFS_REALPATH(conn,dir_name);
1175 if (!resolved_name) {
1176 NTSTATUS status = map_nt_error_from_unix(errno);
1178 if (errno == ENOENT || errno == ENOTDIR) {
1179 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1182 DEBUG(3,("check_reduce_name: "
1183 "couldn't get realpath for "
1184 "%s (%s)\n",
1185 fname,
1186 nt_errstr(status)));
1187 return status;
1189 ret = asprintf(&new_name, "%s/%s",
1190 resolved_name, last_component);
1191 SAFE_FREE(resolved_name);
1192 if (ret == -1) {
1193 return NT_STATUS_NO_MEMORY;
1195 resolved_name = new_name;
1196 break;
1198 default:
1199 DEBUG(3,("check_reduced_name: couldn't get "
1200 "realpath for %s\n", fname));
1201 return map_nt_error_from_unix(errno);
1205 DEBUG(10,("check_reduced_name realpath [%s] -> [%s]\n", fname,
1206 resolved_name));
1208 if (*resolved_name != '/') {
1209 DEBUG(0,("check_reduced_name: realpath doesn't return "
1210 "absolute paths !\n"));
1211 SAFE_FREE(resolved_name);
1212 return NT_STATUS_OBJECT_NAME_INVALID;
1215 allow_widelinks = lp_widelinks(SNUM(conn));
1216 allow_symlinks = lp_follow_symlinks(SNUM(conn));
1218 /* Common widelinks and symlinks checks. */
1219 if (!allow_widelinks || !allow_symlinks) {
1220 const char *conn_rootdir;
1221 size_t rootdir_len;
1223 conn_rootdir = SMB_VFS_CONNECTPATH(conn, fname);
1224 if (conn_rootdir == NULL) {
1225 DEBUG(2, ("check_reduced_name: Could not get "
1226 "conn_rootdir\n"));
1227 SAFE_FREE(resolved_name);
1228 return NT_STATUS_ACCESS_DENIED;
1231 rootdir_len = strlen(conn_rootdir);
1232 if (strncmp(conn_rootdir, resolved_name,
1233 rootdir_len) != 0) {
1234 DEBUG(2, ("check_reduced_name: Bad access "
1235 "attempt: %s is a symlink outside the "
1236 "share path\n", fname));
1237 DEBUGADD(2, ("conn_rootdir =%s\n", conn_rootdir));
1238 DEBUGADD(2, ("resolved_name=%s\n", resolved_name));
1239 SAFE_FREE(resolved_name);
1240 return NT_STATUS_ACCESS_DENIED;
1243 /* Extra checks if all symlinks are disallowed. */
1244 if (!allow_symlinks) {
1245 /* fname can't have changed in resolved_path. */
1246 const char *p = &resolved_name[rootdir_len];
1248 /* *p can be '\0' if fname was "." */
1249 if (*p == '\0' && ISDOT(fname)) {
1250 goto out;
1253 if (*p != '/') {
1254 DEBUG(2, ("check_reduced_name: logic error (%c) "
1255 "in resolved_name: %s\n",
1257 fname));
1258 SAFE_FREE(resolved_name);
1259 return NT_STATUS_ACCESS_DENIED;
1262 p++;
1263 if (strcmp(fname, p)!=0) {
1264 DEBUG(2, ("check_reduced_name: Bad access "
1265 "attempt: %s is a symlink to %s\n",
1266 fname, p));
1267 SAFE_FREE(resolved_name);
1268 return NT_STATUS_ACCESS_DENIED;
1273 out:
1275 DEBUG(3,("check_reduced_name: %s reduced to %s\n", fname,
1276 resolved_name));
1277 SAFE_FREE(resolved_name);
1278 return NT_STATUS_OK;
1282 * XXX: This is temporary and there should be no callers of this once
1283 * smb_filename is plumbed through all path based operations.
1285 int vfs_stat_smb_fname(struct connection_struct *conn, const char *fname,
1286 SMB_STRUCT_STAT *psbuf)
1288 struct smb_filename *smb_fname;
1289 int ret;
1291 smb_fname = synthetic_smb_fname_split(talloc_tos(), fname, NULL);
1292 if (smb_fname == NULL) {
1293 errno = ENOMEM;
1294 return -1;
1297 if (lp_posix_pathnames()) {
1298 ret = SMB_VFS_LSTAT(conn, smb_fname);
1299 } else {
1300 ret = SMB_VFS_STAT(conn, smb_fname);
1303 if (ret != -1) {
1304 *psbuf = smb_fname->st;
1307 TALLOC_FREE(smb_fname);
1308 return ret;
1312 * XXX: This is temporary and there should be no callers of this once
1313 * smb_filename is plumbed through all path based operations.
1315 int vfs_lstat_smb_fname(struct connection_struct *conn, const char *fname,
1316 SMB_STRUCT_STAT *psbuf)
1318 struct smb_filename *smb_fname;
1319 int ret;
1321 smb_fname = synthetic_smb_fname_split(talloc_tos(), fname, NULL);
1322 if (smb_fname == NULL) {
1323 errno = ENOMEM;
1324 return -1;
1327 ret = SMB_VFS_LSTAT(conn, smb_fname);
1328 if (ret != -1) {
1329 *psbuf = smb_fname->st;
1332 TALLOC_FREE(smb_fname);
1333 return ret;
1337 * Ensure LSTAT is called for POSIX paths.
1340 NTSTATUS vfs_stat_fsp(files_struct *fsp)
1342 int ret;
1344 if(fsp->fh->fd == -1) {
1345 if (fsp->posix_open) {
1346 ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
1347 } else {
1348 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
1350 if (ret == -1) {
1351 return map_nt_error_from_unix(errno);
1353 } else {
1354 if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) {
1355 return map_nt_error_from_unix(errno);
1358 return NT_STATUS_OK;
1362 * Initialize num_streams and streams, then call VFS op streaminfo
1364 NTSTATUS vfs_streaminfo(connection_struct *conn,
1365 struct files_struct *fsp,
1366 const char *fname,
1367 TALLOC_CTX *mem_ctx,
1368 unsigned int *num_streams,
1369 struct stream_struct **streams)
1371 *num_streams = 0;
1372 *streams = NULL;
1373 return SMB_VFS_STREAMINFO(conn, fsp, fname, mem_ctx, num_streams, streams);
1377 generate a file_id from a stat structure
1379 struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
1381 return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
1384 int smb_vfs_call_connect(struct vfs_handle_struct *handle,
1385 const char *service, const char *user)
1387 VFS_FIND(connect);
1388 return handle->fns->connect_fn(handle, service, user);
1391 void smb_vfs_call_disconnect(struct vfs_handle_struct *handle)
1393 VFS_FIND(disconnect);
1394 handle->fns->disconnect_fn(handle);
1397 uint64_t smb_vfs_call_disk_free(struct vfs_handle_struct *handle,
1398 const char *path, bool small_query,
1399 uint64_t *bsize, uint64_t *dfree,
1400 uint64_t *dsize)
1402 VFS_FIND(disk_free);
1403 return handle->fns->disk_free_fn(handle, path, small_query, bsize,
1404 dfree, dsize);
1407 int smb_vfs_call_get_quota(struct vfs_handle_struct *handle,
1408 enum SMB_QUOTA_TYPE qtype, unid_t id,
1409 SMB_DISK_QUOTA *qt)
1411 VFS_FIND(get_quota);
1412 return handle->fns->get_quota_fn(handle, qtype, id, qt);
1415 int smb_vfs_call_set_quota(struct vfs_handle_struct *handle,
1416 enum SMB_QUOTA_TYPE qtype, unid_t id,
1417 SMB_DISK_QUOTA *qt)
1419 VFS_FIND(set_quota);
1420 return handle->fns->set_quota_fn(handle, qtype, id, qt);
1423 int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle,
1424 struct files_struct *fsp,
1425 struct shadow_copy_data *shadow_copy_data,
1426 bool labels)
1428 VFS_FIND(get_shadow_copy_data);
1429 return handle->fns->get_shadow_copy_data_fn(handle, fsp,
1430 shadow_copy_data,
1431 labels);
1433 int smb_vfs_call_statvfs(struct vfs_handle_struct *handle, const char *path,
1434 struct vfs_statvfs_struct *statbuf)
1436 VFS_FIND(statvfs);
1437 return handle->fns->statvfs_fn(handle, path, statbuf);
1440 uint32_t smb_vfs_call_fs_capabilities(struct vfs_handle_struct *handle,
1441 enum timestamp_set_resolution *p_ts_res)
1443 VFS_FIND(fs_capabilities);
1444 return handle->fns->fs_capabilities_fn(handle, p_ts_res);
1447 NTSTATUS smb_vfs_call_get_dfs_referrals(struct vfs_handle_struct *handle,
1448 struct dfs_GetDFSReferral *r)
1450 VFS_FIND(get_dfs_referrals);
1451 return handle->fns->get_dfs_referrals_fn(handle, r);
1454 DIR *smb_vfs_call_opendir(struct vfs_handle_struct *handle,
1455 const char *fname, const char *mask,
1456 uint32 attributes)
1458 VFS_FIND(opendir);
1459 return handle->fns->opendir_fn(handle, fname, mask, attributes);
1462 DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
1463 struct files_struct *fsp,
1464 const char *mask,
1465 uint32 attributes)
1467 VFS_FIND(fdopendir);
1468 return handle->fns->fdopendir_fn(handle, fsp, mask, attributes);
1471 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
1472 DIR *dirp,
1473 SMB_STRUCT_STAT *sbuf)
1475 VFS_FIND(readdir);
1476 return handle->fns->readdir_fn(handle, dirp, sbuf);
1479 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
1480 DIR *dirp, long offset)
1482 VFS_FIND(seekdir);
1483 handle->fns->seekdir_fn(handle, dirp, offset);
1486 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
1487 DIR *dirp)
1489 VFS_FIND(telldir);
1490 return handle->fns->telldir_fn(handle, dirp);
1493 void smb_vfs_call_rewind_dir(struct vfs_handle_struct *handle,
1494 DIR *dirp)
1496 VFS_FIND(rewind_dir);
1497 handle->fns->rewind_dir_fn(handle, dirp);
1500 int smb_vfs_call_mkdir(struct vfs_handle_struct *handle, const char *path,
1501 mode_t mode)
1503 VFS_FIND(mkdir);
1504 return handle->fns->mkdir_fn(handle, path, mode);
1507 int smb_vfs_call_rmdir(struct vfs_handle_struct *handle, const char *path)
1509 VFS_FIND(rmdir);
1510 return handle->fns->rmdir_fn(handle, path);
1513 int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
1514 DIR *dir)
1516 VFS_FIND(closedir);
1517 return handle->fns->closedir_fn(handle, dir);
1520 void smb_vfs_call_init_search_op(struct vfs_handle_struct *handle,
1521 DIR *dirp)
1523 VFS_FIND(init_search_op);
1524 handle->fns->init_search_op_fn(handle, dirp);
1527 int smb_vfs_call_open(struct vfs_handle_struct *handle,
1528 struct smb_filename *smb_fname, struct files_struct *fsp,
1529 int flags, mode_t mode)
1531 VFS_FIND(open);
1532 return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
1535 NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle,
1536 struct smb_request *req,
1537 uint16_t root_dir_fid,
1538 struct smb_filename *smb_fname,
1539 uint32_t access_mask,
1540 uint32_t share_access,
1541 uint32_t create_disposition,
1542 uint32_t create_options,
1543 uint32_t file_attributes,
1544 uint32_t oplock_request,
1545 struct smb2_lease *lease,
1546 uint64_t allocation_size,
1547 uint32_t private_flags,
1548 struct security_descriptor *sd,
1549 struct ea_list *ea_list,
1550 files_struct **result,
1551 int *pinfo)
1553 VFS_FIND(create_file);
1554 return handle->fns->create_file_fn(
1555 handle, req, root_dir_fid, smb_fname, access_mask,
1556 share_access, create_disposition, create_options,
1557 file_attributes, oplock_request, lease, allocation_size,
1558 private_flags, sd, ea_list,
1559 result, pinfo);
1562 int smb_vfs_call_close(struct vfs_handle_struct *handle,
1563 struct files_struct *fsp)
1565 VFS_FIND(close);
1566 return handle->fns->close_fn(handle, fsp);
1569 ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle,
1570 struct files_struct *fsp, void *data, size_t n)
1572 VFS_FIND(read);
1573 return handle->fns->read_fn(handle, fsp, data, n);
1576 ssize_t smb_vfs_call_pread(struct vfs_handle_struct *handle,
1577 struct files_struct *fsp, void *data, size_t n,
1578 off_t offset)
1580 VFS_FIND(pread);
1581 return handle->fns->pread_fn(handle, fsp, data, n, offset);
1584 struct smb_vfs_call_pread_state {
1585 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1586 ssize_t retval;
1589 static void smb_vfs_call_pread_done(struct tevent_req *subreq);
1591 struct tevent_req *smb_vfs_call_pread_send(struct vfs_handle_struct *handle,
1592 TALLOC_CTX *mem_ctx,
1593 struct tevent_context *ev,
1594 struct files_struct *fsp,
1595 void *data,
1596 size_t n, off_t offset)
1598 struct tevent_req *req, *subreq;
1599 struct smb_vfs_call_pread_state *state;
1601 req = tevent_req_create(mem_ctx, &state,
1602 struct smb_vfs_call_pread_state);
1603 if (req == NULL) {
1604 return NULL;
1606 VFS_FIND(pread_send);
1607 state->recv_fn = handle->fns->pread_recv_fn;
1609 subreq = handle->fns->pread_send_fn(handle, state, ev, fsp, data, n,
1610 offset);
1611 if (tevent_req_nomem(subreq, req)) {
1612 return tevent_req_post(req, ev);
1614 tevent_req_set_callback(subreq, smb_vfs_call_pread_done, req);
1615 return req;
1618 static void smb_vfs_call_pread_done(struct tevent_req *subreq)
1620 struct tevent_req *req = tevent_req_callback_data(
1621 subreq, struct tevent_req);
1622 struct smb_vfs_call_pread_state *state = tevent_req_data(
1623 req, struct smb_vfs_call_pread_state);
1624 int err;
1626 state->retval = state->recv_fn(subreq, &err);
1627 TALLOC_FREE(subreq);
1628 if (state->retval == -1) {
1629 tevent_req_error(req, err);
1630 return;
1632 tevent_req_done(req);
1635 ssize_t SMB_VFS_PREAD_RECV(struct tevent_req *req, int *perrno)
1637 struct smb_vfs_call_pread_state *state = tevent_req_data(
1638 req, struct smb_vfs_call_pread_state);
1639 int err;
1641 if (tevent_req_is_unix_error(req, &err)) {
1642 *perrno = err;
1643 return -1;
1645 return state->retval;
1648 ssize_t smb_vfs_call_write(struct vfs_handle_struct *handle,
1649 struct files_struct *fsp, const void *data,
1650 size_t n)
1652 VFS_FIND(write);
1653 return handle->fns->write_fn(handle, fsp, data, n);
1656 ssize_t smb_vfs_call_pwrite(struct vfs_handle_struct *handle,
1657 struct files_struct *fsp, const void *data,
1658 size_t n, off_t offset)
1660 VFS_FIND(pwrite);
1661 return handle->fns->pwrite_fn(handle, fsp, data, n, offset);
1664 struct smb_vfs_call_pwrite_state {
1665 ssize_t (*recv_fn)(struct tevent_req *req, int *err);
1666 ssize_t retval;
1669 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq);
1671 struct tevent_req *smb_vfs_call_pwrite_send(struct vfs_handle_struct *handle,
1672 TALLOC_CTX *mem_ctx,
1673 struct tevent_context *ev,
1674 struct files_struct *fsp,
1675 const void *data,
1676 size_t n, off_t offset)
1678 struct tevent_req *req, *subreq;
1679 struct smb_vfs_call_pwrite_state *state;
1681 req = tevent_req_create(mem_ctx, &state,
1682 struct smb_vfs_call_pwrite_state);
1683 if (req == NULL) {
1684 return NULL;
1686 VFS_FIND(pwrite_send);
1687 state->recv_fn = handle->fns->pwrite_recv_fn;
1689 subreq = handle->fns->pwrite_send_fn(handle, state, ev, fsp, data, n,
1690 offset);
1691 if (tevent_req_nomem(subreq, req)) {
1692 return tevent_req_post(req, ev);
1694 tevent_req_set_callback(subreq, smb_vfs_call_pwrite_done, req);
1695 return req;
1698 static void smb_vfs_call_pwrite_done(struct tevent_req *subreq)
1700 struct tevent_req *req = tevent_req_callback_data(
1701 subreq, struct tevent_req);
1702 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1703 req, struct smb_vfs_call_pwrite_state);
1704 int err;
1706 state->retval = state->recv_fn(subreq, &err);
1707 TALLOC_FREE(subreq);
1708 if (state->retval == -1) {
1709 tevent_req_error(req, err);
1710 return;
1712 tevent_req_done(req);
1715 ssize_t SMB_VFS_PWRITE_RECV(struct tevent_req *req, int *perrno)
1717 struct smb_vfs_call_pwrite_state *state = tevent_req_data(
1718 req, struct smb_vfs_call_pwrite_state);
1719 int err;
1721 if (tevent_req_is_unix_error(req, &err)) {
1722 *perrno = err;
1723 return -1;
1725 return state->retval;
1728 off_t smb_vfs_call_lseek(struct vfs_handle_struct *handle,
1729 struct files_struct *fsp, off_t offset,
1730 int whence)
1732 VFS_FIND(lseek);
1733 return handle->fns->lseek_fn(handle, fsp, offset, whence);
1736 ssize_t smb_vfs_call_sendfile(struct vfs_handle_struct *handle, int tofd,
1737 files_struct *fromfsp, const DATA_BLOB *header,
1738 off_t offset, size_t count)
1740 VFS_FIND(sendfile);
1741 return handle->fns->sendfile_fn(handle, tofd, fromfsp, header, offset,
1742 count);
1745 ssize_t smb_vfs_call_recvfile(struct vfs_handle_struct *handle, int fromfd,
1746 files_struct *tofsp, off_t offset,
1747 size_t count)
1749 VFS_FIND(recvfile);
1750 return handle->fns->recvfile_fn(handle, fromfd, tofsp, offset, count);
1753 int smb_vfs_call_rename(struct vfs_handle_struct *handle,
1754 const struct smb_filename *smb_fname_src,
1755 const struct smb_filename *smb_fname_dst)
1757 VFS_FIND(rename);
1758 return handle->fns->rename_fn(handle, smb_fname_src, smb_fname_dst);
1761 int smb_vfs_call_fsync(struct vfs_handle_struct *handle,
1762 struct files_struct *fsp)
1764 VFS_FIND(fsync);
1765 return handle->fns->fsync_fn(handle, fsp);
1768 struct smb_vfs_call_fsync_state {
1769 int (*recv_fn)(struct tevent_req *req, int *err);
1770 int retval;
1773 static void smb_vfs_call_fsync_done(struct tevent_req *subreq);
1775 struct tevent_req *smb_vfs_call_fsync_send(struct vfs_handle_struct *handle,
1776 TALLOC_CTX *mem_ctx,
1777 struct tevent_context *ev,
1778 struct files_struct *fsp)
1780 struct tevent_req *req, *subreq;
1781 struct smb_vfs_call_fsync_state *state;
1783 req = tevent_req_create(mem_ctx, &state,
1784 struct smb_vfs_call_fsync_state);
1785 if (req == NULL) {
1786 return NULL;
1788 VFS_FIND(fsync_send);
1789 state->recv_fn = handle->fns->fsync_recv_fn;
1791 subreq = handle->fns->fsync_send_fn(handle, state, ev, fsp);
1792 if (tevent_req_nomem(subreq, req)) {
1793 return tevent_req_post(req, ev);
1795 tevent_req_set_callback(subreq, smb_vfs_call_fsync_done, req);
1796 return req;
1799 static void smb_vfs_call_fsync_done(struct tevent_req *subreq)
1801 struct tevent_req *req = tevent_req_callback_data(
1802 subreq, struct tevent_req);
1803 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1804 req, struct smb_vfs_call_fsync_state);
1805 int err;
1807 state->retval = state->recv_fn(subreq, &err);
1808 TALLOC_FREE(subreq);
1809 if (state->retval == -1) {
1810 tevent_req_error(req, err);
1811 return;
1813 tevent_req_done(req);
1816 int SMB_VFS_FSYNC_RECV(struct tevent_req *req, int *perrno)
1818 struct smb_vfs_call_fsync_state *state = tevent_req_data(
1819 req, struct smb_vfs_call_fsync_state);
1820 int err;
1822 if (tevent_req_is_unix_error(req, &err)) {
1823 *perrno = err;
1824 return -1;
1826 return state->retval;
1830 int smb_vfs_call_stat(struct vfs_handle_struct *handle,
1831 struct smb_filename *smb_fname)
1833 VFS_FIND(stat);
1834 return handle->fns->stat_fn(handle, smb_fname);
1837 int smb_vfs_call_fstat(struct vfs_handle_struct *handle,
1838 struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
1840 VFS_FIND(fstat);
1841 return handle->fns->fstat_fn(handle, fsp, sbuf);
1844 int smb_vfs_call_lstat(struct vfs_handle_struct *handle,
1845 struct smb_filename *smb_filename)
1847 VFS_FIND(lstat);
1848 return handle->fns->lstat_fn(handle, smb_filename);
1851 uint64_t smb_vfs_call_get_alloc_size(struct vfs_handle_struct *handle,
1852 struct files_struct *fsp,
1853 const SMB_STRUCT_STAT *sbuf)
1855 VFS_FIND(get_alloc_size);
1856 return handle->fns->get_alloc_size_fn(handle, fsp, sbuf);
1859 int smb_vfs_call_unlink(struct vfs_handle_struct *handle,
1860 const struct smb_filename *smb_fname)
1862 VFS_FIND(unlink);
1863 return handle->fns->unlink_fn(handle, smb_fname);
1866 int smb_vfs_call_chmod(struct vfs_handle_struct *handle, const char *path,
1867 mode_t mode)
1869 VFS_FIND(chmod);
1870 return handle->fns->chmod_fn(handle, path, mode);
1873 int smb_vfs_call_fchmod(struct vfs_handle_struct *handle,
1874 struct files_struct *fsp, mode_t mode)
1876 VFS_FIND(fchmod);
1877 return handle->fns->fchmod_fn(handle, fsp, mode);
1880 int smb_vfs_call_chown(struct vfs_handle_struct *handle, const char *path,
1881 uid_t uid, gid_t gid)
1883 VFS_FIND(chown);
1884 return handle->fns->chown_fn(handle, path, uid, gid);
1887 int smb_vfs_call_fchown(struct vfs_handle_struct *handle,
1888 struct files_struct *fsp, uid_t uid, gid_t gid)
1890 VFS_FIND(fchown);
1891 return handle->fns->fchown_fn(handle, fsp, uid, gid);
1894 int smb_vfs_call_lchown(struct vfs_handle_struct *handle, const char *path,
1895 uid_t uid, gid_t gid)
1897 VFS_FIND(lchown);
1898 return handle->fns->lchown_fn(handle, path, uid, gid);
1901 NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid)
1903 int ret;
1904 bool as_root = false;
1905 const char *path;
1906 char *saved_dir = NULL;
1907 char *parent_dir = NULL;
1908 NTSTATUS status;
1910 if (fsp->fh->fd != -1) {
1911 /* Try fchown. */
1912 ret = SMB_VFS_FCHOWN(fsp, uid, gid);
1913 if (ret == 0) {
1914 return NT_STATUS_OK;
1916 if (ret == -1 && errno != ENOSYS) {
1917 return map_nt_error_from_unix(errno);
1921 as_root = (geteuid() == 0);
1923 if (as_root) {
1925 * We are being asked to chown as root. Make
1926 * sure we chdir() into the path to pin it,
1927 * and always act using lchown to ensure we
1928 * don't deref any symbolic links.
1930 const char *final_component = NULL;
1931 struct smb_filename local_fname;
1933 saved_dir = vfs_GetWd(talloc_tos(),fsp->conn);
1934 if (!saved_dir) {
1935 status = map_nt_error_from_unix(errno);
1936 DEBUG(0,("vfs_chown_fsp: failed to get "
1937 "current working directory. Error was %s\n",
1938 strerror(errno)));
1939 return status;
1942 if (!parent_dirname(talloc_tos(),
1943 fsp->fsp_name->base_name,
1944 &parent_dir,
1945 &final_component)) {
1946 return NT_STATUS_NO_MEMORY;
1949 /* cd into the parent dir to pin it. */
1950 ret = vfs_ChDir(fsp->conn, parent_dir);
1951 if (ret == -1) {
1952 return map_nt_error_from_unix(errno);
1955 ZERO_STRUCT(local_fname);
1956 local_fname.base_name = discard_const_p(char, final_component);
1958 /* Must use lstat here. */
1959 ret = SMB_VFS_LSTAT(fsp->conn, &local_fname);
1960 if (ret == -1) {
1961 status = map_nt_error_from_unix(errno);
1962 goto out;
1965 /* Ensure it matches the fsp stat. */
1966 if (!check_same_stat(&local_fname.st, &fsp->fsp_name->st)) {
1967 status = NT_STATUS_ACCESS_DENIED;
1968 goto out;
1970 path = final_component;
1971 } else {
1972 path = fsp->fsp_name->base_name;
1975 if (fsp->posix_open || as_root) {
1976 ret = SMB_VFS_LCHOWN(fsp->conn,
1977 path,
1978 uid, gid);
1979 } else {
1980 ret = SMB_VFS_CHOWN(fsp->conn,
1981 path,
1982 uid, gid);
1985 if (ret == 0) {
1986 status = NT_STATUS_OK;
1987 } else {
1988 status = map_nt_error_from_unix(errno);
1991 out:
1993 if (as_root) {
1994 vfs_ChDir(fsp->conn,saved_dir);
1995 TALLOC_FREE(saved_dir);
1996 TALLOC_FREE(parent_dir);
1998 return status;
2001 int smb_vfs_call_chdir(struct vfs_handle_struct *handle, const char *path)
2003 VFS_FIND(chdir);
2004 return handle->fns->chdir_fn(handle, path);
2007 char *smb_vfs_call_getwd(struct vfs_handle_struct *handle)
2009 VFS_FIND(getwd);
2010 return handle->fns->getwd_fn(handle);
2013 int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
2014 const struct smb_filename *smb_fname,
2015 struct smb_file_time *ft)
2017 VFS_FIND(ntimes);
2018 return handle->fns->ntimes_fn(handle, smb_fname, ft);
2021 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
2022 struct files_struct *fsp, off_t offset)
2024 VFS_FIND(ftruncate);
2025 return handle->fns->ftruncate_fn(handle, fsp, offset);
2028 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
2029 struct files_struct *fsp,
2030 enum vfs_fallocate_mode mode,
2031 off_t offset,
2032 off_t len)
2034 VFS_FIND(fallocate);
2035 return handle->fns->fallocate_fn(handle, fsp, mode, offset, len);
2038 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
2039 struct files_struct *fsp, uint32 share_mode,
2040 uint32_t access_mask)
2042 VFS_FIND(kernel_flock);
2043 return handle->fns->kernel_flock_fn(handle, fsp, share_mode,
2044 access_mask);
2047 int smb_vfs_call_linux_setlease(struct vfs_handle_struct *handle,
2048 struct files_struct *fsp, int leasetype)
2050 VFS_FIND(linux_setlease);
2051 return handle->fns->linux_setlease_fn(handle, fsp, leasetype);
2054 int smb_vfs_call_symlink(struct vfs_handle_struct *handle, const char *oldpath,
2055 const char *newpath)
2057 VFS_FIND(symlink);
2058 return handle->fns->symlink_fn(handle, oldpath, newpath);
2061 int smb_vfs_call_readlink(struct vfs_handle_struct *handle,
2062 const char *path, char *buf, size_t bufsiz)
2064 VFS_FIND(readlink);
2065 return handle->fns->readlink_fn(handle, path, buf, bufsiz);
2068 int smb_vfs_call_link(struct vfs_handle_struct *handle, const char *oldpath,
2069 const char *newpath)
2071 VFS_FIND(link);
2072 return handle->fns->link_fn(handle, oldpath, newpath);
2075 int smb_vfs_call_mknod(struct vfs_handle_struct *handle, const char *path,
2076 mode_t mode, SMB_DEV_T dev)
2078 VFS_FIND(mknod);
2079 return handle->fns->mknod_fn(handle, path, mode, dev);
2082 char *smb_vfs_call_realpath(struct vfs_handle_struct *handle, const char *path)
2084 VFS_FIND(realpath);
2085 return handle->fns->realpath_fn(handle, path);
2088 NTSTATUS smb_vfs_call_notify_watch(struct vfs_handle_struct *handle,
2089 struct sys_notify_context *ctx,
2090 const char *path,
2091 uint32_t *filter,
2092 uint32_t *subdir_filter,
2093 void (*callback)(struct sys_notify_context *ctx,
2094 void *private_data,
2095 struct notify_event *ev),
2096 void *private_data, void *handle_p)
2098 VFS_FIND(notify_watch);
2099 return handle->fns->notify_watch_fn(handle, ctx, path,
2100 filter, subdir_filter, callback,
2101 private_data, handle_p);
2104 int smb_vfs_call_chflags(struct vfs_handle_struct *handle, const char *path,
2105 unsigned int flags)
2107 VFS_FIND(chflags);
2108 return handle->fns->chflags_fn(handle, path, flags);
2111 struct file_id smb_vfs_call_file_id_create(struct vfs_handle_struct *handle,
2112 const SMB_STRUCT_STAT *sbuf)
2114 VFS_FIND(file_id_create);
2115 return handle->fns->file_id_create_fn(handle, sbuf);
2118 NTSTATUS smb_vfs_call_streaminfo(struct vfs_handle_struct *handle,
2119 struct files_struct *fsp,
2120 const char *fname,
2121 TALLOC_CTX *mem_ctx,
2122 unsigned int *num_streams,
2123 struct stream_struct **streams)
2125 VFS_FIND(streaminfo);
2126 return handle->fns->streaminfo_fn(handle, fsp, fname, mem_ctx,
2127 num_streams, streams);
2130 int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
2131 const char *path, const char *name,
2132 TALLOC_CTX *mem_ctx, char **found_name)
2134 VFS_FIND(get_real_filename);
2135 return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,
2136 found_name);
2139 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
2140 const char *filename)
2142 VFS_FIND(connectpath);
2143 return handle->fns->connectpath_fn(handle, filename);
2146 bool smb_vfs_call_strict_lock(struct vfs_handle_struct *handle,
2147 struct files_struct *fsp,
2148 struct lock_struct *plock)
2150 VFS_FIND(strict_lock);
2151 return handle->fns->strict_lock_fn(handle, fsp, plock);
2154 void smb_vfs_call_strict_unlock(struct vfs_handle_struct *handle,
2155 struct files_struct *fsp,
2156 struct lock_struct *plock)
2158 VFS_FIND(strict_unlock);
2159 handle->fns->strict_unlock_fn(handle, fsp, plock);
2162 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
2163 const char *name,
2164 enum vfs_translate_direction direction,
2165 TALLOC_CTX *mem_ctx,
2166 char **mapped_name)
2168 VFS_FIND(translate_name);
2169 return handle->fns->translate_name_fn(handle, name, direction, mem_ctx,
2170 mapped_name);
2173 NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
2174 struct files_struct *fsp,
2175 TALLOC_CTX *ctx,
2176 uint32_t function,
2177 uint16_t req_flags,
2178 const uint8_t *in_data,
2179 uint32_t in_len,
2180 uint8_t **out_data,
2181 uint32_t max_out_len,
2182 uint32_t *out_len)
2184 VFS_FIND(fsctl);
2185 return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
2186 in_data, in_len, out_data, max_out_len,
2187 out_len);
2190 struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle,
2191 TALLOC_CTX *mem_ctx,
2192 struct tevent_context *ev,
2193 struct files_struct *src_fsp,
2194 off_t src_off,
2195 struct files_struct *dest_fsp,
2196 off_t dest_off,
2197 off_t num)
2199 VFS_FIND(copy_chunk_send);
2200 return handle->fns->copy_chunk_send_fn(handle, mem_ctx, ev, src_fsp,
2201 src_off, dest_fsp, dest_off, num);
2204 NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,
2205 struct tevent_req *req,
2206 off_t *copied)
2208 VFS_FIND(copy_chunk_recv);
2209 return handle->fns->copy_chunk_recv_fn(handle, req, copied);
2212 NTSTATUS smb_vfs_call_get_compression(vfs_handle_struct *handle,
2213 TALLOC_CTX *mem_ctx,
2214 struct files_struct *fsp,
2215 struct smb_filename *smb_fname,
2216 uint16_t *_compression_fmt)
2218 VFS_FIND(get_compression);
2219 return handle->fns->get_compression_fn(handle, mem_ctx, fsp, smb_fname,
2220 _compression_fmt);
2223 NTSTATUS smb_vfs_call_set_compression(vfs_handle_struct *handle,
2224 TALLOC_CTX *mem_ctx,
2225 struct files_struct *fsp,
2226 uint16_t compression_fmt)
2228 VFS_FIND(set_compression);
2229 return handle->fns->set_compression_fn(handle, mem_ctx, fsp,
2230 compression_fmt);
2233 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
2234 struct files_struct *fsp,
2235 uint32 security_info,
2236 TALLOC_CTX *mem_ctx,
2237 struct security_descriptor **ppdesc)
2239 VFS_FIND(fget_nt_acl);
2240 return handle->fns->fget_nt_acl_fn(handle, fsp, security_info,
2241 mem_ctx, ppdesc);
2244 NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle,
2245 const char *name,
2246 uint32 security_info,
2247 TALLOC_CTX *mem_ctx,
2248 struct security_descriptor **ppdesc)
2250 VFS_FIND(get_nt_acl);
2251 return handle->fns->get_nt_acl_fn(handle, name, security_info, mem_ctx, ppdesc);
2254 NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle,
2255 struct files_struct *fsp,
2256 uint32 security_info_sent,
2257 const struct security_descriptor *psd)
2259 VFS_FIND(fset_nt_acl);
2260 return handle->fns->fset_nt_acl_fn(handle, fsp, security_info_sent,
2261 psd);
2264 NTSTATUS smb_vfs_call_audit_file(struct vfs_handle_struct *handle,
2265 struct smb_filename *file,
2266 struct security_acl *sacl,
2267 uint32_t access_requested,
2268 uint32_t access_denied)
2270 VFS_FIND(audit_file);
2271 return handle->fns->audit_file_fn(handle,
2272 file,
2273 sacl,
2274 access_requested,
2275 access_denied);
2278 int smb_vfs_call_chmod_acl(struct vfs_handle_struct *handle, const char *name,
2279 mode_t mode)
2281 VFS_FIND(chmod_acl);
2282 return handle->fns->chmod_acl_fn(handle, name, mode);
2285 int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle,
2286 struct files_struct *fsp, mode_t mode)
2288 VFS_FIND(fchmod_acl);
2289 return handle->fns->fchmod_acl_fn(handle, fsp, mode);
2292 SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle,
2293 const char *path_p,
2294 SMB_ACL_TYPE_T type,
2295 TALLOC_CTX *mem_ctx)
2297 VFS_FIND(sys_acl_get_file);
2298 return handle->fns->sys_acl_get_file_fn(handle, path_p, type, mem_ctx);
2301 SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle,
2302 struct files_struct *fsp,
2303 TALLOC_CTX *mem_ctx)
2305 VFS_FIND(sys_acl_get_fd);
2306 return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx);
2309 int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle,
2310 const char *path_p,
2311 TALLOC_CTX *mem_ctx,
2312 char **blob_description,
2313 DATA_BLOB *blob)
2315 VFS_FIND(sys_acl_blob_get_file);
2316 return handle->fns->sys_acl_blob_get_file_fn(handle, path_p, mem_ctx, blob_description, blob);
2319 int smb_vfs_call_sys_acl_blob_get_fd(struct vfs_handle_struct *handle,
2320 struct files_struct *fsp,
2321 TALLOC_CTX *mem_ctx,
2322 char **blob_description,
2323 DATA_BLOB *blob)
2325 VFS_FIND(sys_acl_blob_get_fd);
2326 return handle->fns->sys_acl_blob_get_fd_fn(handle, fsp, mem_ctx, blob_description, blob);
2329 int smb_vfs_call_sys_acl_set_file(struct vfs_handle_struct *handle,
2330 const char *name, SMB_ACL_TYPE_T acltype,
2331 SMB_ACL_T theacl)
2333 VFS_FIND(sys_acl_set_file);
2334 return handle->fns->sys_acl_set_file_fn(handle, name, acltype, theacl);
2337 int smb_vfs_call_sys_acl_set_fd(struct vfs_handle_struct *handle,
2338 struct files_struct *fsp, SMB_ACL_T theacl)
2340 VFS_FIND(sys_acl_set_fd);
2341 return handle->fns->sys_acl_set_fd_fn(handle, fsp, theacl);
2344 int smb_vfs_call_sys_acl_delete_def_file(struct vfs_handle_struct *handle,
2345 const char *path)
2347 VFS_FIND(sys_acl_delete_def_file);
2348 return handle->fns->sys_acl_delete_def_file_fn(handle, path);
2351 ssize_t smb_vfs_call_getxattr(struct vfs_handle_struct *handle,
2352 const char *path, const char *name, void *value,
2353 size_t size)
2355 VFS_FIND(getxattr);
2356 return handle->fns->getxattr_fn(handle, path, name, value, size);
2359 ssize_t smb_vfs_call_fgetxattr(struct vfs_handle_struct *handle,
2360 struct files_struct *fsp, const char *name,
2361 void *value, size_t size)
2363 VFS_FIND(fgetxattr);
2364 return handle->fns->fgetxattr_fn(handle, fsp, name, value, size);
2367 ssize_t smb_vfs_call_listxattr(struct vfs_handle_struct *handle,
2368 const char *path, char *list, size_t size)
2370 VFS_FIND(listxattr);
2371 return handle->fns->listxattr_fn(handle, path, list, size);
2374 ssize_t smb_vfs_call_flistxattr(struct vfs_handle_struct *handle,
2375 struct files_struct *fsp, char *list,
2376 size_t size)
2378 VFS_FIND(flistxattr);
2379 return handle->fns->flistxattr_fn(handle, fsp, list, size);
2382 int smb_vfs_call_removexattr(struct vfs_handle_struct *handle,
2383 const char *path, const char *name)
2385 VFS_FIND(removexattr);
2386 return handle->fns->removexattr_fn(handle, path, name);
2389 int smb_vfs_call_fremovexattr(struct vfs_handle_struct *handle,
2390 struct files_struct *fsp, const char *name)
2392 VFS_FIND(fremovexattr);
2393 return handle->fns->fremovexattr_fn(handle, fsp, name);
2396 int smb_vfs_call_setxattr(struct vfs_handle_struct *handle, const char *path,
2397 const char *name, const void *value, size_t size,
2398 int flags)
2400 VFS_FIND(setxattr);
2401 return handle->fns->setxattr_fn(handle, path, name, value, size, flags);
2404 int smb_vfs_call_fsetxattr(struct vfs_handle_struct *handle,
2405 struct files_struct *fsp, const char *name,
2406 const void *value, size_t size, int flags)
2408 VFS_FIND(fsetxattr);
2409 return handle->fns->fsetxattr_fn(handle, fsp, name, value, size, flags);
2412 bool smb_vfs_call_aio_force(struct vfs_handle_struct *handle,
2413 struct files_struct *fsp)
2415 VFS_FIND(aio_force);
2416 return handle->fns->aio_force_fn(handle, fsp);
2419 bool smb_vfs_call_is_offline(struct vfs_handle_struct *handle,
2420 const struct smb_filename *fname,
2421 SMB_STRUCT_STAT *sbuf)
2423 VFS_FIND(is_offline);
2424 return handle->fns->is_offline_fn(handle, fname, sbuf);
2427 int smb_vfs_call_set_offline(struct vfs_handle_struct *handle,
2428 const struct smb_filename *fname)
2430 VFS_FIND(set_offline);
2431 return handle->fns->set_offline_fn(handle, fname);
2434 NTSTATUS smb_vfs_call_durable_cookie(struct vfs_handle_struct *handle,
2435 struct files_struct *fsp,
2436 TALLOC_CTX *mem_ctx,
2437 DATA_BLOB *cookie)
2439 VFS_FIND(durable_cookie);
2440 return handle->fns->durable_cookie_fn(handle, fsp, mem_ctx, cookie);
2443 NTSTATUS smb_vfs_call_durable_disconnect(struct vfs_handle_struct *handle,
2444 struct files_struct *fsp,
2445 const DATA_BLOB old_cookie,
2446 TALLOC_CTX *mem_ctx,
2447 DATA_BLOB *new_cookie)
2449 VFS_FIND(durable_disconnect);
2450 return handle->fns->durable_disconnect_fn(handle, fsp, old_cookie,
2451 mem_ctx, new_cookie);
2454 NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
2455 struct smb_request *smb1req,
2456 struct smbXsrv_open *op,
2457 const DATA_BLOB old_cookie,
2458 TALLOC_CTX *mem_ctx,
2459 struct files_struct **fsp,
2460 DATA_BLOB *new_cookie)
2462 VFS_FIND(durable_reconnect);
2463 return handle->fns->durable_reconnect_fn(handle, smb1req, op,
2464 old_cookie, mem_ctx, fsp,
2465 new_cookie);