2 Unix SMB/CIFS implementation.
3 Wrap disk only vfs functions to sidestep dodgy compilers.
4 Copyright (C) Tim Potter 1998
5 Copyright (C) Jeremy Allison 2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "system/time.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
27 #include "smbprofile.h"
28 #include "../libcli/security/security.h"
29 #include "passdb/lookup_sid.h"
30 #include "source3/include/msdfs.h"
31 #include "librpc/gen_ndr/ndr_dfsblobs.h"
32 #include "lib/util/tevent_unix.h"
33 #include "lib/asys/asys.h"
34 #include "lib/util/tevent_ntstatus.h"
37 #define DBGC_CLASS DBGC_VFS
39 /* Check for NULL pointer parameters in vfswrap_* functions */
41 /* We don't want to have NULL function pointers lying around. Someone
42 is sure to try and execute them. These stubs are used to prevent
45 static int vfswrap_connect(vfs_handle_struct
*handle
, const char *service
, const char *user
)
47 return 0; /* Return >= 0 for success */
50 static void vfswrap_disconnect(vfs_handle_struct
*handle
)
56 static uint64_t vfswrap_disk_free(vfs_handle_struct
*handle
, const char *path
, bool small_query
, uint64_t *bsize
,
57 uint64_t *dfree
, uint64_t *dsize
)
61 result
= sys_disk_free(handle
->conn
, path
, small_query
, bsize
, dfree
, dsize
);
65 static int vfswrap_get_quota(struct vfs_handle_struct
*handle
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*qt
)
67 #ifdef HAVE_SYS_QUOTAS
70 START_PROFILE(syscall_get_quota
);
71 result
= sys_get_quota(handle
->conn
->connectpath
, qtype
, id
, qt
);
72 END_PROFILE(syscall_get_quota
);
80 static int vfswrap_set_quota(struct vfs_handle_struct
*handle
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*qt
)
82 #ifdef HAVE_SYS_QUOTAS
85 START_PROFILE(syscall_set_quota
);
86 result
= sys_set_quota(handle
->conn
->connectpath
, qtype
, id
, qt
);
87 END_PROFILE(syscall_set_quota
);
95 static int vfswrap_get_shadow_copy_data(struct vfs_handle_struct
*handle
,
96 struct files_struct
*fsp
,
97 struct shadow_copy_data
*shadow_copy_data
,
101 return -1; /* Not implemented. */
104 static int vfswrap_statvfs(struct vfs_handle_struct
*handle
, const char *path
, vfs_statvfs_struct
*statbuf
)
106 return sys_statvfs(path
, statbuf
);
109 static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct
*handle
,
110 enum timestamp_set_resolution
*p_ts_res
)
112 connection_struct
*conn
= handle
->conn
;
113 uint32_t caps
= FILE_CASE_SENSITIVE_SEARCH
| FILE_CASE_PRESERVED_NAMES
;
114 struct smb_filename
*smb_fname_cpath
= NULL
;
115 struct vfs_statvfs_struct statbuf
;
118 ZERO_STRUCT(statbuf
);
119 ret
= sys_statvfs(conn
->connectpath
, &statbuf
);
121 caps
= statbuf
.FsCapabilities
;
124 *p_ts_res
= TIMESTAMP_SET_SECONDS
;
126 /* Work out what timestamp resolution we can
127 * use when setting a timestamp. */
129 smb_fname_cpath
= synthetic_smb_fname(talloc_tos(), conn
->connectpath
,
131 if (smb_fname_cpath
== NULL
) {
135 ret
= SMB_VFS_STAT(conn
, smb_fname_cpath
);
137 TALLOC_FREE(smb_fname_cpath
);
141 if (smb_fname_cpath
->st
.st_ex_mtime
.tv_nsec
||
142 smb_fname_cpath
->st
.st_ex_atime
.tv_nsec
||
143 smb_fname_cpath
->st
.st_ex_ctime
.tv_nsec
) {
144 /* If any of the normal UNIX directory timestamps
145 * have a non-zero tv_nsec component assume
146 * we might be able to set sub-second timestamps.
147 * See what filetime set primitives we have.
149 #if defined(HAVE_UTIMENSAT)
150 *p_ts_res
= TIMESTAMP_SET_NT_OR_BETTER
;
151 #elif defined(HAVE_UTIMES)
152 /* utimes allows msec timestamps to be set. */
153 *p_ts_res
= TIMESTAMP_SET_MSEC
;
154 #elif defined(HAVE_UTIME)
155 /* utime only allows sec timestamps to be set. */
156 *p_ts_res
= TIMESTAMP_SET_SECONDS
;
159 DEBUG(10,("vfswrap_fs_capabilities: timestamp "
161 "available on share %s, directory %s\n",
162 *p_ts_res
== TIMESTAMP_SET_MSEC
? "msec" : "sec",
163 lp_servicename(talloc_tos(), conn
->params
->service
),
164 conn
->connectpath
));
166 TALLOC_FREE(smb_fname_cpath
);
170 static NTSTATUS
vfswrap_get_dfs_referrals(struct vfs_handle_struct
*handle
,
171 struct dfs_GetDFSReferral
*r
)
173 struct junction_map
*junction
= NULL
;
175 bool self_referral
= false;
176 char *pathnamep
= NULL
;
177 char *local_dfs_path
= NULL
;
180 uint16_t max_referral_level
= r
->in
.req
.max_referral_level
;
183 NDR_PRINT_IN_DEBUG(dfs_GetDFSReferral
, r
);
186 /* get the junction entry */
187 if (r
->in
.req
.servername
== NULL
) {
188 return NT_STATUS_NOT_FOUND
;
192 * Trim pathname sent by client so it begins with only one backslash.
193 * Two backslashes confuse some dfs clients
196 local_dfs_path
= talloc_strdup(r
, r
->in
.req
.servername
);
197 if (local_dfs_path
== NULL
) {
198 return NT_STATUS_NO_MEMORY
;
200 pathnamep
= local_dfs_path
;
201 while (IS_DIRECTORY_SEP(pathnamep
[0]) &&
202 IS_DIRECTORY_SEP(pathnamep
[1])) {
206 junction
= talloc_zero(r
, struct junction_map
);
207 if (junction
== NULL
) {
208 return NT_STATUS_NO_MEMORY
;
211 /* The following call can change cwd. */
212 status
= get_referred_path(r
, pathnamep
,
213 !handle
->conn
->sconn
->using_smb2
,
214 junction
, &consumedcnt
, &self_referral
);
215 if (!NT_STATUS_IS_OK(status
)) {
216 vfs_ChDir(handle
->conn
, handle
->conn
->connectpath
);
219 vfs_ChDir(handle
->conn
, handle
->conn
->connectpath
);
221 if (!self_referral
) {
222 pathnamep
[consumedcnt
] = '\0';
225 dbgtext("setup_dfs_referral: Path %s to "
226 "alternate path(s):",
228 for (i
=0; i
< junction
->referral_count
; i
++) {
230 junction
->referral_list
[i
].alternate_path
);
236 if (r
->in
.req
.max_referral_level
<= 2) {
237 max_referral_level
= 2;
239 if (r
->in
.req
.max_referral_level
>= 3) {
240 max_referral_level
= 3;
243 r
->out
.resp
= talloc_zero(r
, struct dfs_referral_resp
);
244 if (r
->out
.resp
== NULL
) {
245 return NT_STATUS_NO_MEMORY
;
248 r
->out
.resp
->path_consumed
= strlen_m(pathnamep
) * 2;
249 r
->out
.resp
->nb_referrals
= junction
->referral_count
;
251 r
->out
.resp
->header_flags
= DFS_HEADER_FLAG_STORAGE_SVR
;
253 r
->out
.resp
->header_flags
|= DFS_HEADER_FLAG_REFERAL_SVR
;
256 r
->out
.resp
->referral_entries
= talloc_zero_array(r
,
257 struct dfs_referral_type
,
258 r
->out
.resp
->nb_referrals
);
259 if (r
->out
.resp
->referral_entries
== NULL
) {
260 return NT_STATUS_NO_MEMORY
;
263 switch (max_referral_level
) {
265 for(i
=0; i
< junction
->referral_count
; i
++) {
266 struct referral
*ref
= &junction
->referral_list
[i
];
267 TALLOC_CTX
*mem_ctx
= r
->out
.resp
->referral_entries
;
268 struct dfs_referral_type
*t
=
269 &r
->out
.resp
->referral_entries
[i
];
270 struct dfs_referral_v2
*v2
= &t
->referral
.v2
;
273 v2
->size
= VERSION2_REFERRAL_SIZE
;
275 v2
->server_type
= DFS_SERVER_ROOT
;
277 v2
->server_type
= DFS_SERVER_NON_ROOT
;
280 v2
->proximity
= ref
->proximity
;
282 v2
->DFS_path
= talloc_strdup(mem_ctx
, pathnamep
);
283 if (v2
->DFS_path
== NULL
) {
284 return NT_STATUS_NO_MEMORY
;
286 v2
->DFS_alt_path
= talloc_strdup(mem_ctx
, pathnamep
);
287 if (v2
->DFS_alt_path
== NULL
) {
288 return NT_STATUS_NO_MEMORY
;
290 v2
->netw_address
= talloc_strdup(mem_ctx
,
291 ref
->alternate_path
);
292 if (v2
->netw_address
== NULL
) {
293 return NT_STATUS_NO_MEMORY
;
299 for(i
=0; i
< junction
->referral_count
; i
++) {
300 struct referral
*ref
= &junction
->referral_list
[i
];
301 TALLOC_CTX
*mem_ctx
= r
->out
.resp
->referral_entries
;
302 struct dfs_referral_type
*t
=
303 &r
->out
.resp
->referral_entries
[i
];
304 struct dfs_referral_v3
*v3
= &t
->referral
.v3
;
305 struct dfs_normal_referral
*r1
= &v3
->referrals
.r1
;
308 v3
->size
= VERSION3_REFERRAL_SIZE
;
310 v3
->server_type
= DFS_SERVER_ROOT
;
312 v3
->server_type
= DFS_SERVER_NON_ROOT
;
316 r1
->DFS_path
= talloc_strdup(mem_ctx
, pathnamep
);
317 if (r1
->DFS_path
== NULL
) {
318 return NT_STATUS_NO_MEMORY
;
320 r1
->DFS_alt_path
= talloc_strdup(mem_ctx
, pathnamep
);
321 if (r1
->DFS_alt_path
== NULL
) {
322 return NT_STATUS_NO_MEMORY
;
324 r1
->netw_address
= talloc_strdup(mem_ctx
,
325 ref
->alternate_path
);
326 if (r1
->netw_address
== NULL
) {
327 return NT_STATUS_NO_MEMORY
;
332 DEBUG(0,("setup_dfs_referral: Invalid dfs referral "
334 max_referral_level
));
335 return NT_STATUS_INVALID_LEVEL
;
339 NDR_PRINT_OUT_DEBUG(dfs_GetDFSReferral
, r
);
345 /* Directory operations */
347 static DIR *vfswrap_opendir(vfs_handle_struct
*handle
, const char *fname
, const char *mask
, uint32 attr
)
351 START_PROFILE(syscall_opendir
);
352 result
= opendir(fname
);
353 END_PROFILE(syscall_opendir
);
357 static DIR *vfswrap_fdopendir(vfs_handle_struct
*handle
,
364 START_PROFILE(syscall_fdopendir
);
365 result
= sys_fdopendir(fsp
->fh
->fd
);
366 END_PROFILE(syscall_fdopendir
);
371 static struct dirent
*vfswrap_readdir(vfs_handle_struct
*handle
,
373 SMB_STRUCT_STAT
*sbuf
)
375 struct dirent
*result
;
377 START_PROFILE(syscall_readdir
);
378 result
= readdir(dirp
);
379 END_PROFILE(syscall_readdir
);
381 /* Default Posix readdir() does not give us stat info.
382 * Set to invalid to indicate we didn't return this info. */
383 SET_STAT_INVALID(*sbuf
);
384 #if defined(HAVE_DIRFD) && defined(HAVE_FSTATAT)
385 if (result
!= NULL
) {
386 /* See if we can efficiently return this. */
388 int flags
= (lp_posix_pathnames() ?
389 AT_SYMLINK_NOFOLLOW
: 0);
390 int ret
= fstatat(dirfd(dirp
),
395 init_stat_ex_from_stat(sbuf
,
397 lp_fake_directory_create_times(
398 SNUM(handle
->conn
)));
406 static void vfswrap_seekdir(vfs_handle_struct
*handle
, DIR *dirp
, long offset
)
408 START_PROFILE(syscall_seekdir
);
409 seekdir(dirp
, offset
);
410 END_PROFILE(syscall_seekdir
);
413 static long vfswrap_telldir(vfs_handle_struct
*handle
, DIR *dirp
)
416 START_PROFILE(syscall_telldir
);
417 result
= telldir(dirp
);
418 END_PROFILE(syscall_telldir
);
422 static void vfswrap_rewinddir(vfs_handle_struct
*handle
, DIR *dirp
)
424 START_PROFILE(syscall_rewinddir
);
426 END_PROFILE(syscall_rewinddir
);
429 static int vfswrap_mkdir(vfs_handle_struct
*handle
, const char *path
, mode_t mode
)
432 bool has_dacl
= False
;
435 START_PROFILE(syscall_mkdir
);
437 if (lp_inherit_acls(SNUM(handle
->conn
))
438 && parent_dirname(talloc_tos(), path
, &parent
, NULL
)
439 && (has_dacl
= directory_has_default_acl(handle
->conn
, parent
)))
440 mode
= (0777 & lp_directory_mask(SNUM(handle
->conn
)));
444 result
= mkdir(path
, mode
);
446 if (result
== 0 && !has_dacl
) {
448 * We need to do this as the default behavior of POSIX ACLs
449 * is to set the mask to be the requested group permission
450 * bits, not the group permission bits to be the requested
451 * group permission bits. This is not what we want, as it will
452 * mess up any inherited ACL bits that were set. JRA.
454 int saved_errno
= errno
; /* We may get ENOSYS */
455 if ((SMB_VFS_CHMOD_ACL(handle
->conn
, path
, mode
) == -1) && (errno
== ENOSYS
))
459 END_PROFILE(syscall_mkdir
);
463 static int vfswrap_rmdir(vfs_handle_struct
*handle
, const char *path
)
467 START_PROFILE(syscall_rmdir
);
468 result
= rmdir(path
);
469 END_PROFILE(syscall_rmdir
);
473 static int vfswrap_closedir(vfs_handle_struct
*handle
, DIR *dirp
)
477 START_PROFILE(syscall_closedir
);
478 result
= closedir(dirp
);
479 END_PROFILE(syscall_closedir
);
483 static void vfswrap_init_search_op(vfs_handle_struct
*handle
,
486 /* Default behavior is a NOOP */
489 /* File operations */
491 static int vfswrap_open(vfs_handle_struct
*handle
,
492 struct smb_filename
*smb_fname
,
493 files_struct
*fsp
, int flags
, mode_t mode
)
497 START_PROFILE(syscall_open
);
499 if (smb_fname
->stream_name
) {
504 result
= open(smb_fname
->base_name
, flags
, mode
);
506 END_PROFILE(syscall_open
);
510 static NTSTATUS
vfswrap_create_file(vfs_handle_struct
*handle
,
511 struct smb_request
*req
,
512 uint16_t root_dir_fid
,
513 struct smb_filename
*smb_fname
,
514 uint32_t access_mask
,
515 uint32_t share_access
,
516 uint32_t create_disposition
,
517 uint32_t create_options
,
518 uint32_t file_attributes
,
519 uint32_t oplock_request
,
520 uint64_t allocation_size
,
521 uint32_t private_flags
,
522 struct security_descriptor
*sd
,
523 struct ea_list
*ea_list
,
524 files_struct
**result
,
527 return create_file_default(handle
->conn
, req
, root_dir_fid
, smb_fname
,
528 access_mask
, share_access
,
529 create_disposition
, create_options
,
530 file_attributes
, oplock_request
,
531 allocation_size
, private_flags
,
536 static int vfswrap_close(vfs_handle_struct
*handle
, files_struct
*fsp
)
540 START_PROFILE(syscall_close
);
541 result
= fd_close_posix(fsp
);
542 END_PROFILE(syscall_close
);
546 static ssize_t
vfswrap_read(vfs_handle_struct
*handle
, files_struct
*fsp
, void *data
, size_t n
)
550 START_PROFILE_BYTES(syscall_read
, n
);
551 result
= sys_read(fsp
->fh
->fd
, data
, n
);
552 END_PROFILE(syscall_read
);
556 static ssize_t
vfswrap_pread(vfs_handle_struct
*handle
, files_struct
*fsp
, void *data
,
557 size_t n
, off_t offset
)
561 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
562 START_PROFILE_BYTES(syscall_pread
, n
);
563 result
= sys_pread(fsp
->fh
->fd
, data
, n
, offset
);
564 END_PROFILE(syscall_pread
);
566 if (result
== -1 && errno
== ESPIPE
) {
567 /* Maintain the fiction that pipes can be seeked (sought?) on. */
568 result
= SMB_VFS_READ(fsp
, data
, n
);
572 #else /* HAVE_PREAD */
576 curr
= SMB_VFS_LSEEK(fsp
, 0, SEEK_CUR
);
577 if (curr
== -1 && errno
== ESPIPE
) {
578 /* Maintain the fiction that pipes can be seeked (sought?) on. */
579 result
= SMB_VFS_READ(fsp
, data
, n
);
584 if (SMB_VFS_LSEEK(fsp
, offset
, SEEK_SET
) == -1) {
589 result
= SMB_VFS_READ(fsp
, data
, n
);
592 SMB_VFS_LSEEK(fsp
, curr
, SEEK_SET
);
595 #endif /* HAVE_PREAD */
600 static ssize_t
vfswrap_write(vfs_handle_struct
*handle
, files_struct
*fsp
, const void *data
, size_t n
)
604 START_PROFILE_BYTES(syscall_write
, n
);
605 result
= sys_write(fsp
->fh
->fd
, data
, n
);
606 END_PROFILE(syscall_write
);
610 static ssize_t
vfswrap_pwrite(vfs_handle_struct
*handle
, files_struct
*fsp
, const void *data
,
611 size_t n
, off_t offset
)
615 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
616 START_PROFILE_BYTES(syscall_pwrite
, n
);
617 result
= sys_pwrite(fsp
->fh
->fd
, data
, n
, offset
);
618 END_PROFILE(syscall_pwrite
);
620 if (result
== -1 && errno
== ESPIPE
) {
621 /* Maintain the fiction that pipes can be sought on. */
622 result
= SMB_VFS_WRITE(fsp
, data
, n
);
625 #else /* HAVE_PWRITE */
629 curr
= SMB_VFS_LSEEK(fsp
, 0, SEEK_CUR
);
634 if (SMB_VFS_LSEEK(fsp
, offset
, SEEK_SET
) == -1) {
638 result
= SMB_VFS_WRITE(fsp
, data
, n
);
641 SMB_VFS_LSEEK(fsp
, curr
, SEEK_SET
);
644 #endif /* HAVE_PWRITE */
649 static void vfswrap_asys_finished(struct tevent_context
*ev
,
650 struct tevent_fd
*fde
,
651 uint16_t flags
, void *p
);
653 static bool vfswrap_init_asys_ctx(struct smbXsrv_connection
*conn
)
658 if (conn
->asys_ctx
!= NULL
) {
661 ret
= asys_context_init(&conn
->asys_ctx
, aio_pending_size
);
663 DEBUG(1, ("asys_context_init failed: %s\n", strerror(ret
)));
667 fd
= asys_signalfd(conn
->asys_ctx
);
669 set_blocking(fd
, false);
671 conn
->asys_fde
= tevent_add_fd(conn
->ev_ctx
, conn
, fd
,
673 vfswrap_asys_finished
,
675 if (conn
->asys_fde
== NULL
) {
676 DEBUG(1, ("tevent_add_fd failed\n"));
677 asys_context_destroy(conn
->asys_ctx
);
678 conn
->asys_ctx
= NULL
;
684 struct vfswrap_asys_state
{
685 struct asys_context
*asys_ctx
;
686 struct tevent_req
*req
;
691 static int vfswrap_asys_state_destructor(struct vfswrap_asys_state
*s
)
693 asys_cancel(s
->asys_ctx
, s
->req
);
697 static struct tevent_req
*vfswrap_pread_send(struct vfs_handle_struct
*handle
,
699 struct tevent_context
*ev
,
700 struct files_struct
*fsp
,
702 size_t n
, off_t offset
)
704 struct tevent_req
*req
;
705 struct vfswrap_asys_state
*state
;
708 req
= tevent_req_create(mem_ctx
, &state
, struct vfswrap_asys_state
);
712 if (!vfswrap_init_asys_ctx(handle
->conn
->sconn
->conn
)) {
714 return tevent_req_post(req
, ev
);
716 state
->asys_ctx
= handle
->conn
->sconn
->conn
->asys_ctx
;
719 ret
= asys_pread(state
->asys_ctx
, fsp
->fh
->fd
, data
, n
, offset
, req
);
721 tevent_req_error(req
, ret
);
722 return tevent_req_post(req
, ev
);
724 talloc_set_destructor(state
, vfswrap_asys_state_destructor
);
729 static struct tevent_req
*vfswrap_pwrite_send(struct vfs_handle_struct
*handle
,
731 struct tevent_context
*ev
,
732 struct files_struct
*fsp
,
734 size_t n
, off_t offset
)
736 struct tevent_req
*req
;
737 struct vfswrap_asys_state
*state
;
740 req
= tevent_req_create(mem_ctx
, &state
, struct vfswrap_asys_state
);
744 if (!vfswrap_init_asys_ctx(handle
->conn
->sconn
->conn
)) {
746 return tevent_req_post(req
, ev
);
748 state
->asys_ctx
= handle
->conn
->sconn
->conn
->asys_ctx
;
751 ret
= asys_pwrite(state
->asys_ctx
, fsp
->fh
->fd
, data
, n
, offset
, req
);
753 tevent_req_error(req
, ret
);
754 return tevent_req_post(req
, ev
);
756 talloc_set_destructor(state
, vfswrap_asys_state_destructor
);
761 static struct tevent_req
*vfswrap_fsync_send(struct vfs_handle_struct
*handle
,
763 struct tevent_context
*ev
,
764 struct files_struct
*fsp
)
766 struct tevent_req
*req
;
767 struct vfswrap_asys_state
*state
;
770 req
= tevent_req_create(mem_ctx
, &state
, struct vfswrap_asys_state
);
774 if (!vfswrap_init_asys_ctx(handle
->conn
->sconn
->conn
)) {
776 return tevent_req_post(req
, ev
);
778 state
->asys_ctx
= handle
->conn
->sconn
->conn
->asys_ctx
;
781 ret
= asys_fsync(state
->asys_ctx
, fsp
->fh
->fd
, req
);
783 tevent_req_error(req
, ret
);
784 return tevent_req_post(req
, ev
);
786 talloc_set_destructor(state
, vfswrap_asys_state_destructor
);
791 static void vfswrap_asys_finished(struct tevent_context
*ev
,
792 struct tevent_fd
*fde
,
793 uint16_t flags
, void *p
)
795 struct asys_context
*asys_ctx
= (struct asys_context
*)p
;
796 struct asys_result results
[outstanding_aio_calls
];
799 if ((flags
& TEVENT_FD_READ
) == 0) {
803 ret
= asys_results(asys_ctx
, results
, outstanding_aio_calls
);
805 DEBUG(1, ("asys_results returned %s\n", strerror(-ret
)));
809 for (i
=0; i
<ret
; i
++) {
810 struct asys_result
*result
= &results
[i
];
811 struct tevent_req
*req
;
812 struct vfswrap_asys_state
*state
;
814 if ((result
->ret
== -1) && (result
->err
== ECANCELED
)) {
818 req
= talloc_get_type_abort(result
->private_data
,
820 state
= tevent_req_data(req
, struct vfswrap_asys_state
);
822 talloc_set_destructor(state
, NULL
);
824 state
->ret
= result
->ret
;
825 state
->err
= result
->err
;
826 tevent_req_defer_callback(req
, ev
);
827 tevent_req_done(req
);
831 static ssize_t
vfswrap_asys_ssize_t_recv(struct tevent_req
*req
, int *err
)
833 struct vfswrap_asys_state
*state
= tevent_req_data(
834 req
, struct vfswrap_asys_state
);
836 if (tevent_req_is_unix_error(req
, err
)) {
843 static int vfswrap_asys_int_recv(struct tevent_req
*req
, int *err
)
845 struct vfswrap_asys_state
*state
= tevent_req_data(
846 req
, struct vfswrap_asys_state
);
848 if (tevent_req_is_unix_error(req
, err
)) {
855 static off_t
vfswrap_lseek(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t offset
, int whence
)
859 START_PROFILE(syscall_lseek
);
861 /* Cope with 'stat' file opens. */
862 if (fsp
->fh
->fd
!= -1)
863 result
= lseek(fsp
->fh
->fd
, offset
, whence
);
866 * We want to maintain the fiction that we can seek
867 * on a fifo for file system purposes. This allows
868 * people to set up UNIX fifo's that feed data to Windows
872 if((result
== -1) && (errno
== ESPIPE
)) {
877 END_PROFILE(syscall_lseek
);
881 static ssize_t
vfswrap_sendfile(vfs_handle_struct
*handle
, int tofd
, files_struct
*fromfsp
, const DATA_BLOB
*hdr
,
882 off_t offset
, size_t n
)
886 START_PROFILE_BYTES(syscall_sendfile
, n
);
887 result
= sys_sendfile(tofd
, fromfsp
->fh
->fd
, hdr
, offset
, n
);
888 END_PROFILE(syscall_sendfile
);
892 static ssize_t
vfswrap_recvfile(vfs_handle_struct
*handle
,
900 START_PROFILE_BYTES(syscall_recvfile
, n
);
901 result
= sys_recvfile(fromfd
, tofsp
->fh
->fd
, offset
, n
);
902 END_PROFILE(syscall_recvfile
);
906 static int vfswrap_rename(vfs_handle_struct
*handle
,
907 const struct smb_filename
*smb_fname_src
,
908 const struct smb_filename
*smb_fname_dst
)
912 START_PROFILE(syscall_rename
);
914 if (smb_fname_src
->stream_name
|| smb_fname_dst
->stream_name
) {
919 result
= rename(smb_fname_src
->base_name
, smb_fname_dst
->base_name
);
922 END_PROFILE(syscall_rename
);
926 static int vfswrap_fsync(vfs_handle_struct
*handle
, files_struct
*fsp
)
931 START_PROFILE(syscall_fsync
);
932 result
= fsync(fsp
->fh
->fd
);
933 END_PROFILE(syscall_fsync
);
940 static int vfswrap_stat(vfs_handle_struct
*handle
,
941 struct smb_filename
*smb_fname
)
945 START_PROFILE(syscall_stat
);
947 if (smb_fname
->stream_name
) {
952 result
= sys_stat(smb_fname
->base_name
, &smb_fname
->st
,
953 lp_fake_directory_create_times(SNUM(handle
->conn
)));
955 END_PROFILE(syscall_stat
);
959 static int vfswrap_fstat(vfs_handle_struct
*handle
, files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
963 START_PROFILE(syscall_fstat
);
964 result
= sys_fstat(fsp
->fh
->fd
,
965 sbuf
, lp_fake_directory_create_times(SNUM(handle
->conn
)));
966 END_PROFILE(syscall_fstat
);
970 static int vfswrap_lstat(vfs_handle_struct
*handle
,
971 struct smb_filename
*smb_fname
)
975 START_PROFILE(syscall_lstat
);
977 if (smb_fname
->stream_name
) {
982 result
= sys_lstat(smb_fname
->base_name
, &smb_fname
->st
,
983 lp_fake_directory_create_times(SNUM(handle
->conn
)));
985 END_PROFILE(syscall_lstat
);
989 static NTSTATUS
vfswrap_translate_name(struct vfs_handle_struct
*handle
,
991 enum vfs_translate_direction direction
,
995 return NT_STATUS_NONE_MAPPED
;
999 * Implement the default fsctl operation.
1001 static bool vfswrap_logged_ioctl_message
= false;
1003 static NTSTATUS
vfswrap_fsctl(struct vfs_handle_struct
*handle
,
1004 struct files_struct
*fsp
,
1007 uint16_t req_flags
, /* Needed for UNICODE ... */
1008 const uint8_t *_in_data
,
1010 uint8_t **_out_data
,
1011 uint32_t max_out_len
,
1014 const char *in_data
= (const char *)_in_data
;
1015 char **out_data
= (char **)_out_data
;
1019 case FSCTL_SET_SPARSE
:
1021 bool set_sparse
= true;
1023 if (in_len
>= 1 && in_data
[0] == 0) {
1027 status
= file_set_sparse(handle
->conn
, fsp
, set_sparse
);
1029 DEBUG(NT_STATUS_IS_OK(status
) ? 10 : 9,
1030 ("FSCTL_SET_SPARSE: fname[%s] set[%u] - %s\n",
1031 smb_fname_str_dbg(fsp
->fsp_name
), set_sparse
,
1032 nt_errstr(status
)));
1037 case FSCTL_CREATE_OR_GET_OBJECT_ID
:
1039 unsigned char objid
[16];
1040 char *return_data
= NULL
;
1042 /* This should return the object-id on this file.
1043 * I think I'll make this be the inode+dev. JRA.
1046 DEBUG(10,("FSCTL_CREATE_OR_GET_OBJECT_ID: called on %s\n",
1047 fsp_fnum_dbg(fsp
)));
1049 *out_len
= MIN(max_out_len
, 64);
1051 /* Hmmm, will this cause problems if less data asked for? */
1052 return_data
= talloc_array(ctx
, char, 64);
1053 if (return_data
== NULL
) {
1054 return NT_STATUS_NO_MEMORY
;
1057 /* For backwards compatibility only store the dev/inode. */
1058 push_file_id_16(return_data
, &fsp
->file_id
);
1059 memcpy(return_data
+16,create_volume_objectid(fsp
->conn
,objid
),16);
1060 push_file_id_16(return_data
+32, &fsp
->file_id
);
1061 memset(return_data
+48, 0, 16);
1062 *out_data
= return_data
;
1063 return NT_STATUS_OK
;
1066 case FSCTL_GET_REPARSE_POINT
:
1068 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
1069 DEBUG(10, ("FSCTL_GET_REPARSE_POINT: called on %s. "
1070 "Status: NOT_IMPLEMENTED\n", fsp_fnum_dbg(fsp
)));
1071 return NT_STATUS_NOT_A_REPARSE_POINT
;
1074 case FSCTL_SET_REPARSE_POINT
:
1076 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
1077 DEBUG(10, ("FSCTL_SET_REPARSE_POINT: called on %s. "
1078 "Status: NOT_IMPLEMENTED\n", fsp_fnum_dbg(fsp
)));
1079 return NT_STATUS_NOT_A_REPARSE_POINT
;
1082 case FSCTL_GET_SHADOW_COPY_DATA
:
1085 * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
1086 * and return their volume names. If max_data_count is 16, then it is just
1087 * asking for the number of volumes and length of the combined names.
1089 * pdata is the data allocated by our caller, but that uses
1090 * total_data_count (which is 0 in our case) rather than max_data_count.
1091 * Allocate the correct amount and return the pointer to let
1092 * it be deallocated when we return.
1094 struct shadow_copy_data
*shadow_data
= NULL
;
1095 bool labels
= False
;
1096 uint32 labels_data_count
= 0;
1098 char *cur_pdata
= NULL
;
1100 if (max_out_len
< 16) {
1101 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
1103 return NT_STATUS_INVALID_PARAMETER
;
1106 if (max_out_len
> 16) {
1110 shadow_data
= talloc_zero(ctx
, struct shadow_copy_data
);
1111 if (shadow_data
== NULL
) {
1112 DEBUG(0,("TALLOC_ZERO() failed!\n"));
1113 return NT_STATUS_NO_MEMORY
;
1117 * Call the VFS routine to actually do the work.
1119 if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp
, shadow_data
, labels
)!=0) {
1122 /* broken module didn't set errno on error */
1123 status
= NT_STATUS_UNSUCCESSFUL
;
1125 status
= map_nt_error_from_unix(errno
);
1126 if (NT_STATUS_EQUAL(status
,
1127 NT_STATUS_NOT_SUPPORTED
)) {
1131 DEBUG(log_lev
, ("FSCTL_GET_SHADOW_COPY_DATA: "
1132 "connectpath %s, failed - %s.\n",
1133 fsp
->conn
->connectpath
,
1134 nt_errstr(status
)));
1135 TALLOC_FREE(shadow_data
);
1139 labels_data_count
= (shadow_data
->num_volumes
* 2 *
1140 sizeof(SHADOW_COPY_LABEL
)) + 2;
1145 *out_len
= 12 + labels_data_count
;
1148 if (max_out_len
< *out_len
) {
1149 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
1150 max_out_len
, *out_len
));
1151 TALLOC_FREE(shadow_data
);
1152 return NT_STATUS_BUFFER_TOO_SMALL
;
1155 cur_pdata
= talloc_zero_array(ctx
, char, *out_len
);
1156 if (cur_pdata
== NULL
) {
1157 TALLOC_FREE(shadow_data
);
1158 return NT_STATUS_NO_MEMORY
;
1161 *out_data
= cur_pdata
;
1163 /* num_volumes 4 bytes */
1164 SIVAL(cur_pdata
, 0, shadow_data
->num_volumes
);
1167 /* num_labels 4 bytes */
1168 SIVAL(cur_pdata
, 4, shadow_data
->num_volumes
);
1171 /* needed_data_count 4 bytes */
1172 SIVAL(cur_pdata
, 8, labels_data_count
);
1176 DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
1177 shadow_data
->num_volumes
, fsp_str_dbg(fsp
)));
1178 if (labels
&& shadow_data
->labels
) {
1179 for (i
=0; i
<shadow_data
->num_volumes
; i
++) {
1180 srvstr_push(cur_pdata
, req_flags
,
1181 cur_pdata
, shadow_data
->labels
[i
],
1182 2 * sizeof(SHADOW_COPY_LABEL
),
1183 STR_UNICODE
|STR_TERMINATE
);
1184 cur_pdata
+= 2 * sizeof(SHADOW_COPY_LABEL
);
1185 DEBUGADD(10,("Label[%u]: '%s'\n",i
,shadow_data
->labels
[i
]));
1189 TALLOC_FREE(shadow_data
);
1191 return NT_STATUS_OK
;
1194 case FSCTL_FIND_FILES_BY_SID
:
1196 /* pretend this succeeded -
1198 * we have to send back a list with all files owned by this SID
1200 * but I have to check that --metze
1206 DEBUG(10, ("FSCTL_FIND_FILES_BY_SID: called on %s\n",
1207 fsp_fnum_dbg(fsp
)));
1210 /* NT_STATUS_BUFFER_TOO_SMALL maybe? */
1211 return NT_STATUS_INVALID_PARAMETER
;
1214 sid_len
= MIN(in_len
- 4,SID_MAX_SIZE
);
1216 /* unknown 4 bytes: this is not the length of the sid :-( */
1217 /*unknown = IVAL(pdata,0);*/
1219 if (!sid_parse(in_data
+ 4, sid_len
, &sid
)) {
1220 return NT_STATUS_INVALID_PARAMETER
;
1222 DEBUGADD(10, ("for SID: %s\n", sid_string_dbg(&sid
)));
1224 if (!sid_to_uid(&sid
, &uid
)) {
1225 DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
1226 sid_string_dbg(&sid
),
1227 (unsigned long)sid_len
));
1231 /* we can take a look at the find source :-)
1233 * find ./ -uid $uid -name '*' is what we need here
1236 * and send 4bytes len and then NULL terminated unicode strings
1239 * but I don't know how to deal with the paged results
1240 * (maybe we can hang the result anywhere in the fsp struct)
1242 * but I don't know how to deal with the paged results
1243 * (maybe we can hang the result anywhere in the fsp struct)
1245 * we don't send all files at once
1246 * and at the next we should *not* start from the beginning,
1247 * so we have to cache the result
1252 /* this works for now... */
1253 return NT_STATUS_OK
;
1256 case FSCTL_QUERY_ALLOCATED_RANGES
:
1258 /* FIXME: This is just a dummy reply, telling that all of the
1259 * file is allocated. MKS cp needs that.
1260 * Adding the real allocated ranges via FIEMAP on Linux
1261 * and SEEK_DATA/SEEK_HOLE on Solaris is needed to make
1262 * this FSCTL correct for sparse files.
1264 uint64_t offset
, length
;
1265 char *out_data_tmp
= NULL
;
1268 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: data_count(%u) != 16 is invalid!\n",
1270 return NT_STATUS_INVALID_PARAMETER
;
1273 if (max_out_len
< 16) {
1274 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: max_out_len (%u) < 16 is invalid!\n",
1276 return NT_STATUS_INVALID_PARAMETER
;
1279 offset
= BVAL(in_data
,0);
1280 length
= BVAL(in_data
,8);
1282 if (offset
+ length
< offset
) {
1283 /* No 64-bit integer wrap. */
1284 return NT_STATUS_INVALID_PARAMETER
;
1287 /* Shouldn't this be SMB_VFS_STAT ... ? */
1288 status
= vfs_stat_fsp(fsp
);
1289 if (!NT_STATUS_IS_OK(status
)) {
1294 out_data_tmp
= talloc_array(ctx
, char, *out_len
);
1295 if (out_data_tmp
== NULL
) {
1296 DEBUG(10, ("unable to allocate memory for response\n"));
1297 return NT_STATUS_NO_MEMORY
;
1300 if (offset
> fsp
->fsp_name
->st
.st_ex_size
||
1301 fsp
->fsp_name
->st
.st_ex_size
== 0 ||
1303 memset(out_data_tmp
, 0, *out_len
);
1305 uint64_t end
= offset
+ length
;
1306 end
= MIN(end
, fsp
->fsp_name
->st
.st_ex_size
);
1307 SBVAL(out_data_tmp
, 0, 0);
1308 SBVAL(out_data_tmp
, 8, end
);
1311 *out_data
= out_data_tmp
;
1313 return NT_STATUS_OK
;
1316 case FSCTL_IS_VOLUME_DIRTY
:
1318 DEBUG(10,("FSCTL_IS_VOLUME_DIRTY: called on %s "
1319 "(but remotely not supported)\n", fsp_fnum_dbg(fsp
)));
1321 * http://msdn.microsoft.com/en-us/library/cc232128%28PROT.10%29.aspx
1322 * says we have to respond with NT_STATUS_INVALID_PARAMETER
1324 return NT_STATUS_INVALID_PARAMETER
;
1329 * Only print once ... unfortunately there could be lots of
1330 * different FSCTLs that are called.
1332 if (!vfswrap_logged_ioctl_message
) {
1333 vfswrap_logged_ioctl_message
= true;
1334 DEBUG(2, ("%s (0x%x): Currently not implemented.\n",
1335 __func__
, function
));
1339 return NT_STATUS_NOT_SUPPORTED
;
1342 struct vfs_cc_state
{
1347 static struct tevent_req
*vfswrap_copy_chunk_send(struct vfs_handle_struct
*handle
,
1348 TALLOC_CTX
*mem_ctx
,
1349 struct tevent_context
*ev
,
1350 struct files_struct
*src_fsp
,
1352 struct files_struct
*dest_fsp
,
1356 struct tevent_req
*req
;
1357 struct vfs_cc_state
*vfs_cc_state
;
1360 DEBUG(10, ("performing server side copy chunk of length %lu\n",
1361 (unsigned long)num
));
1363 req
= tevent_req_create(mem_ctx
, &vfs_cc_state
, struct vfs_cc_state
);
1368 status
= vfs_stat_fsp(src_fsp
);
1369 if (tevent_req_nterror(req
, status
)) {
1370 return tevent_req_post(req
, ev
);
1373 if (src_fsp
->fsp_name
->st
.st_ex_size
< src_off
+ num
) {
1375 * [MS-SMB2] 3.3.5.15.6 Handling a Server-Side Data Copy Request
1376 * If the SourceOffset or SourceOffset + Length extends beyond
1377 * the end of file, the server SHOULD<240> treat this as a
1378 * STATUS_END_OF_FILE error.
1380 * <240> Section 3.3.5.15.6: Windows servers will return
1381 * STATUS_INVALID_VIEW_SIZE instead of STATUS_END_OF_FILE.
1383 tevent_req_nterror(req
, NT_STATUS_INVALID_VIEW_SIZE
);
1384 return tevent_req_post(req
, ev
);
1387 /* could use 2.6.33+ sendfile here to do this in kernel */
1388 while (vfs_cc_state
->copied
< num
) {
1390 struct lock_struct lck
;
1393 off_t this_num
= MIN(sizeof(vfs_cc_state
->buf
),
1394 num
- vfs_cc_state
->copied
);
1396 if (src_fsp
->op
== NULL
) {
1397 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
1398 return tevent_req_post(req
, ev
);
1400 init_strict_lock_struct(src_fsp
,
1401 src_fsp
->op
->global
->open_persistent_id
,
1407 if (!SMB_VFS_STRICT_LOCK(src_fsp
->conn
, src_fsp
, &lck
)) {
1408 tevent_req_nterror(req
, NT_STATUS_FILE_LOCK_CONFLICT
);
1409 return tevent_req_post(req
, ev
);
1412 ret
= SMB_VFS_PREAD(src_fsp
, vfs_cc_state
->buf
,
1415 saved_errno
= errno
;
1418 SMB_VFS_STRICT_UNLOCK(src_fsp
->conn
, src_fsp
, &lck
);
1421 errno
= saved_errno
;
1422 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
1423 return tevent_req_post(req
, ev
);
1425 if (ret
!= this_num
) {
1426 /* zero tolerance for short reads */
1427 tevent_req_nterror(req
, NT_STATUS_IO_DEVICE_ERROR
);
1428 return tevent_req_post(req
, ev
);
1433 if (dest_fsp
->op
== NULL
) {
1434 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
1435 return tevent_req_post(req
, ev
);
1438 init_strict_lock_struct(dest_fsp
,
1439 dest_fsp
->op
->global
->open_persistent_id
,
1445 if (!SMB_VFS_STRICT_LOCK(dest_fsp
->conn
, dest_fsp
, &lck
)) {
1446 tevent_req_nterror(req
, NT_STATUS_FILE_LOCK_CONFLICT
);
1447 return tevent_req_post(req
, ev
);
1450 ret
= SMB_VFS_PWRITE(dest_fsp
, vfs_cc_state
->buf
,
1451 this_num
, dest_off
);
1453 saved_errno
= errno
;
1456 SMB_VFS_STRICT_UNLOCK(src_fsp
->conn
, src_fsp
, &lck
);
1459 errno
= saved_errno
;
1460 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
1461 return tevent_req_post(req
, ev
);
1463 if (ret
!= this_num
) {
1464 /* zero tolerance for short writes */
1465 tevent_req_nterror(req
, NT_STATUS_IO_DEVICE_ERROR
);
1466 return tevent_req_post(req
, ev
);
1470 vfs_cc_state
->copied
+= this_num
;
1473 tevent_req_done(req
);
1474 return tevent_req_post(req
, ev
);
1477 static NTSTATUS
vfswrap_copy_chunk_recv(struct vfs_handle_struct
*handle
,
1478 struct tevent_req
*req
,
1481 struct vfs_cc_state
*vfs_cc_state
= tevent_req_data(req
,
1482 struct vfs_cc_state
);
1485 if (tevent_req_is_nterror(req
, &status
)) {
1486 DEBUG(2, ("server side copy chunk failed: %s\n",
1487 nt_errstr(status
)));
1489 tevent_req_received(req
);
1493 *copied
= vfs_cc_state
->copied
;
1494 DEBUG(10, ("server side copy chunk copied %lu\n",
1495 (unsigned long)*copied
));
1496 tevent_req_received(req
);
1498 return NT_STATUS_OK
;
1501 static NTSTATUS
vfswrap_get_compression(struct vfs_handle_struct
*handle
,
1502 TALLOC_CTX
*mem_ctx
,
1503 struct files_struct
*fsp
,
1504 struct smb_filename
*smb_fname
,
1505 uint16_t *_compression_fmt
)
1507 return NT_STATUS_INVALID_DEVICE_REQUEST
;
1510 static NTSTATUS
vfswrap_set_compression(struct vfs_handle_struct
*handle
,
1511 TALLOC_CTX
*mem_ctx
,
1512 struct files_struct
*fsp
,
1513 uint16_t compression_fmt
)
1515 return NT_STATUS_INVALID_DEVICE_REQUEST
;
1518 /********************************************************************
1519 Given a stat buffer return the allocated size on disk, taking into
1520 account sparse files.
1521 ********************************************************************/
1522 static uint64_t vfswrap_get_alloc_size(vfs_handle_struct
*handle
,
1523 struct files_struct
*fsp
,
1524 const SMB_STRUCT_STAT
*sbuf
)
1528 START_PROFILE(syscall_get_alloc_size
);
1530 if(S_ISDIR(sbuf
->st_ex_mode
)) {
1535 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
1536 /* The type of st_blocksize is blkcnt_t which *MUST* be
1537 signed (according to POSIX) and can be less than 64-bits.
1538 Ensure when we're converting to 64 bits wide we don't
1540 #if defined(SIZEOF_BLKCNT_T_8)
1541 result
= (uint64_t)STAT_ST_BLOCKSIZE
* (uint64_t)sbuf
->st_ex_blocks
;
1542 #elif defined(SIZEOF_BLKCNT_T_4)
1544 uint64_t bs
= ((uint64_t)sbuf
->st_ex_blocks
) & 0xFFFFFFFFLL
;
1545 result
= (uint64_t)STAT_ST_BLOCKSIZE
* bs
;
1548 #error SIZEOF_BLKCNT_T_NOT_A_SUPPORTED_VALUE
1552 * Some file systems do not allocate a block for very
1553 * small files. But for non-empty file should report a
1557 uint64_t filesize
= get_file_size_stat(sbuf
);
1559 result
= MIN((uint64_t)STAT_ST_BLOCKSIZE
, filesize
);
1563 result
= get_file_size_stat(sbuf
);
1566 if (fsp
&& fsp
->initial_allocation_size
)
1567 result
= MAX(result
,fsp
->initial_allocation_size
);
1569 result
= smb_roundup(handle
->conn
, result
);
1572 END_PROFILE(syscall_get_alloc_size
);
1576 static int vfswrap_unlink(vfs_handle_struct
*handle
,
1577 const struct smb_filename
*smb_fname
)
1581 START_PROFILE(syscall_unlink
);
1583 if (smb_fname
->stream_name
) {
1587 result
= unlink(smb_fname
->base_name
);
1590 END_PROFILE(syscall_unlink
);
1594 static int vfswrap_chmod(vfs_handle_struct
*handle
, const char *path
, mode_t mode
)
1598 START_PROFILE(syscall_chmod
);
1601 * We need to do this due to the fact that the default POSIX ACL
1602 * chmod modifies the ACL *mask* for the group owner, not the
1603 * group owner bits directly. JRA.
1608 int saved_errno
= errno
; /* We might get ENOSYS */
1609 if ((result
= SMB_VFS_CHMOD_ACL(handle
->conn
, path
, mode
)) == 0) {
1610 END_PROFILE(syscall_chmod
);
1613 /* Error - return the old errno. */
1614 errno
= saved_errno
;
1617 result
= chmod(path
, mode
);
1618 END_PROFILE(syscall_chmod
);
1622 static int vfswrap_fchmod(vfs_handle_struct
*handle
, files_struct
*fsp
, mode_t mode
)
1626 START_PROFILE(syscall_fchmod
);
1629 * We need to do this due to the fact that the default POSIX ACL
1630 * chmod modifies the ACL *mask* for the group owner, not the
1631 * group owner bits directly. JRA.
1635 int saved_errno
= errno
; /* We might get ENOSYS */
1636 if ((result
= SMB_VFS_FCHMOD_ACL(fsp
, mode
)) == 0) {
1637 END_PROFILE(syscall_fchmod
);
1640 /* Error - return the old errno. */
1641 errno
= saved_errno
;
1644 #if defined(HAVE_FCHMOD)
1645 result
= fchmod(fsp
->fh
->fd
, mode
);
1651 END_PROFILE(syscall_fchmod
);
1655 static int vfswrap_chown(vfs_handle_struct
*handle
, const char *path
, uid_t uid
, gid_t gid
)
1659 START_PROFILE(syscall_chown
);
1660 result
= chown(path
, uid
, gid
);
1661 END_PROFILE(syscall_chown
);
1665 static int vfswrap_fchown(vfs_handle_struct
*handle
, files_struct
*fsp
, uid_t uid
, gid_t gid
)
1670 START_PROFILE(syscall_fchown
);
1671 result
= fchown(fsp
->fh
->fd
, uid
, gid
);
1672 END_PROFILE(syscall_fchown
);
1680 static int vfswrap_lchown(vfs_handle_struct
*handle
, const char *path
, uid_t uid
, gid_t gid
)
1684 START_PROFILE(syscall_lchown
);
1685 result
= lchown(path
, uid
, gid
);
1686 END_PROFILE(syscall_lchown
);
1690 static int vfswrap_chdir(vfs_handle_struct
*handle
, const char *path
)
1694 START_PROFILE(syscall_chdir
);
1695 result
= chdir(path
);
1696 END_PROFILE(syscall_chdir
);
1700 static char *vfswrap_getwd(vfs_handle_struct
*handle
)
1704 START_PROFILE(syscall_getwd
);
1705 result
= sys_getwd();
1706 END_PROFILE(syscall_getwd
);
1710 /*********************************************************************
1711 nsec timestamp resolution call. Convert down to whatever the underlying
1712 system will support.
1713 **********************************************************************/
1715 static int vfswrap_ntimes(vfs_handle_struct
*handle
,
1716 const struct smb_filename
*smb_fname
,
1717 struct smb_file_time
*ft
)
1721 START_PROFILE(syscall_ntimes
);
1723 if (smb_fname
->stream_name
) {
1729 if (null_timespec(ft
->atime
)) {
1730 ft
->atime
= smb_fname
->st
.st_ex_atime
;
1733 if (null_timespec(ft
->mtime
)) {
1734 ft
->mtime
= smb_fname
->st
.st_ex_mtime
;
1737 if (!null_timespec(ft
->create_time
)) {
1738 set_create_timespec_ea(handle
->conn
,
1743 if ((timespec_compare(&ft
->atime
,
1744 &smb_fname
->st
.st_ex_atime
) == 0) &&
1745 (timespec_compare(&ft
->mtime
,
1746 &smb_fname
->st
.st_ex_mtime
) == 0)) {
1751 #if defined(HAVE_UTIMENSAT)
1753 struct timespec ts
[2];
1756 result
= utimensat(AT_FDCWD
, smb_fname
->base_name
, ts
, 0);
1758 result
= utimensat(AT_FDCWD
, smb_fname
->base_name
, NULL
, 0);
1760 if (!((result
== -1) && (errno
== ENOSYS
))) {
1764 #if defined(HAVE_UTIMES)
1766 struct timeval tv
[2];
1767 tv
[0] = convert_timespec_to_timeval(ft
->atime
);
1768 tv
[1] = convert_timespec_to_timeval(ft
->mtime
);
1769 result
= utimes(smb_fname
->base_name
, tv
);
1771 result
= utimes(smb_fname
->base_name
, NULL
);
1773 if (!((result
== -1) && (errno
== ENOSYS
))) {
1777 #if defined(HAVE_UTIME)
1779 struct utimbuf times
;
1780 times
.actime
= convert_timespec_to_time_t(ft
->atime
);
1781 times
.modtime
= convert_timespec_to_time_t(ft
->mtime
);
1782 result
= utime(smb_fname
->base_name
, ×
);
1784 result
= utime(smb_fname
->base_name
, NULL
);
1786 if (!((result
== -1) && (errno
== ENOSYS
))) {
1794 END_PROFILE(syscall_ntimes
);
1798 /*********************************************************************
1799 A version of ftruncate that will write the space on disk if strict
1801 **********************************************************************/
1803 static int strict_allocate_ftruncate(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t len
)
1805 off_t space_to_write
;
1806 uint64_t space_avail
;
1807 uint64_t bsize
,dfree
,dsize
;
1810 SMB_STRUCT_STAT
*pst
;
1812 status
= vfs_stat_fsp(fsp
);
1813 if (!NT_STATUS_IS_OK(status
)) {
1816 pst
= &fsp
->fsp_name
->st
;
1819 if (S_ISFIFO(pst
->st_ex_mode
))
1823 if (pst
->st_ex_size
== len
)
1826 /* Shrink - just ftruncate. */
1827 if (pst
->st_ex_size
> len
)
1828 return ftruncate(fsp
->fh
->fd
, len
);
1830 space_to_write
= len
- pst
->st_ex_size
;
1832 /* for allocation try fallocate first. This can fail on some
1833 platforms e.g. when the filesystem doesn't support it and no
1834 emulation is being done by the libc (like on AIX with JFS1). In that
1835 case we do our own emulation. fallocate implementations can
1836 return ENOTSUP or EINVAL in cases like that. */
1837 ret
= SMB_VFS_FALLOCATE(fsp
, VFS_FALLOCATE_EXTEND_SIZE
,
1838 pst
->st_ex_size
, space_to_write
);
1839 if (ret
== ENOSPC
) {
1846 DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with "
1847 "error %d. Falling back to slow manual allocation\n", ret
));
1849 /* available disk space is enough or not? */
1850 space_avail
= get_dfree_info(fsp
->conn
,
1851 fsp
->fsp_name
->base_name
, false,
1852 &bsize
,&dfree
,&dsize
);
1853 /* space_avail is 1k blocks */
1854 if (space_avail
== (uint64_t)-1 ||
1855 ((uint64_t)space_to_write
/1024 > space_avail
) ) {
1860 /* Write out the real space on disk. */
1861 ret
= vfs_slow_fallocate(fsp
, pst
->st_ex_size
, space_to_write
);
1870 static int vfswrap_ftruncate(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t len
)
1873 SMB_STRUCT_STAT
*pst
;
1877 START_PROFILE(syscall_ftruncate
);
1879 if (lp_strict_allocate(SNUM(fsp
->conn
)) && !fsp
->is_sparse
) {
1880 result
= strict_allocate_ftruncate(handle
, fsp
, len
);
1881 END_PROFILE(syscall_ftruncate
);
1885 /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
1886 ftruncate if the system supports it. Then I discovered that
1887 you can have some filesystems that support ftruncate
1888 expansion and some that don't! On Linux fat can't do
1889 ftruncate extend but ext2 can. */
1891 result
= ftruncate(fsp
->fh
->fd
, len
);
1895 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
1896 extend a file with ftruncate. Provide alternate implementation
1899 /* Do an fstat to see if the file is longer than the requested
1900 size in which case the ftruncate above should have
1901 succeeded or shorter, in which case seek to len - 1 and
1902 write 1 byte of zero */
1903 status
= vfs_stat_fsp(fsp
);
1904 if (!NT_STATUS_IS_OK(status
)) {
1907 pst
= &fsp
->fsp_name
->st
;
1910 if (S_ISFIFO(pst
->st_ex_mode
)) {
1916 if (pst
->st_ex_size
== len
) {
1921 if (pst
->st_ex_size
> len
) {
1922 /* the ftruncate should have worked */
1926 if (SMB_VFS_PWRITE(fsp
, &c
, 1, len
-1)!=1) {
1934 END_PROFILE(syscall_ftruncate
);
1938 static int vfswrap_fallocate(vfs_handle_struct
*handle
,
1940 enum vfs_fallocate_mode mode
,
1946 START_PROFILE(syscall_fallocate
);
1947 if (mode
== VFS_FALLOCATE_EXTEND_SIZE
) {
1948 result
= sys_posix_fallocate(fsp
->fh
->fd
, offset
, len
);
1949 } else if (mode
== VFS_FALLOCATE_KEEP_SIZE
) {
1950 result
= sys_fallocate(fsp
->fh
->fd
, mode
, offset
, len
);
1955 END_PROFILE(syscall_fallocate
);
1959 static bool vfswrap_lock(vfs_handle_struct
*handle
, files_struct
*fsp
, int op
, off_t offset
, off_t count
, int type
)
1963 START_PROFILE(syscall_fcntl_lock
);
1964 result
= fcntl_lock(fsp
->fh
->fd
, op
, offset
, count
, type
);
1965 END_PROFILE(syscall_fcntl_lock
);
1969 static int vfswrap_kernel_flock(vfs_handle_struct
*handle
, files_struct
*fsp
,
1970 uint32 share_mode
, uint32 access_mask
)
1972 START_PROFILE(syscall_kernel_flock
);
1973 kernel_flock(fsp
->fh
->fd
, share_mode
, access_mask
);
1974 END_PROFILE(syscall_kernel_flock
);
1978 static bool vfswrap_getlock(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t
*poffset
, off_t
*pcount
, int *ptype
, pid_t
*ppid
)
1982 START_PROFILE(syscall_fcntl_getlock
);
1983 result
= fcntl_getlock(fsp
->fh
->fd
, poffset
, pcount
, ptype
, ppid
);
1984 END_PROFILE(syscall_fcntl_getlock
);
1988 static int vfswrap_linux_setlease(vfs_handle_struct
*handle
, files_struct
*fsp
,
1993 START_PROFILE(syscall_linux_setlease
);
1995 #ifdef HAVE_KERNEL_OPLOCKS_LINUX
1996 result
= linux_setlease(fsp
->fh
->fd
, leasetype
);
2000 END_PROFILE(syscall_linux_setlease
);
2004 static int vfswrap_symlink(vfs_handle_struct
*handle
, const char *oldpath
, const char *newpath
)
2008 START_PROFILE(syscall_symlink
);
2009 result
= symlink(oldpath
, newpath
);
2010 END_PROFILE(syscall_symlink
);
2014 static int vfswrap_readlink(vfs_handle_struct
*handle
, const char *path
, char *buf
, size_t bufsiz
)
2018 START_PROFILE(syscall_readlink
);
2019 result
= readlink(path
, buf
, bufsiz
);
2020 END_PROFILE(syscall_readlink
);
2024 static int vfswrap_link(vfs_handle_struct
*handle
, const char *oldpath
, const char *newpath
)
2028 START_PROFILE(syscall_link
);
2029 result
= link(oldpath
, newpath
);
2030 END_PROFILE(syscall_link
);
2034 static int vfswrap_mknod(vfs_handle_struct
*handle
, const char *pathname
, mode_t mode
, SMB_DEV_T dev
)
2038 START_PROFILE(syscall_mknod
);
2039 result
= sys_mknod(pathname
, mode
, dev
);
2040 END_PROFILE(syscall_mknod
);
2044 static char *vfswrap_realpath(vfs_handle_struct
*handle
, const char *path
)
2048 START_PROFILE(syscall_realpath
);
2049 #ifdef REALPATH_TAKES_NULL
2050 result
= realpath(path
, NULL
);
2052 result
= SMB_MALLOC_ARRAY(char, PATH_MAX
+1);
2054 char *resolved_path
= realpath(path
, result
);
2055 if (!resolved_path
) {
2058 /* SMB_ASSERT(result == resolved_path) ? */
2059 result
= resolved_path
;
2063 END_PROFILE(syscall_realpath
);
2067 static NTSTATUS
vfswrap_notify_watch(vfs_handle_struct
*vfs_handle
,
2068 struct sys_notify_context
*ctx
,
2071 uint32_t *subdir_filter
,
2072 void (*callback
)(struct sys_notify_context
*ctx
,
2074 struct notify_event
*ev
),
2075 void *private_data
, void *handle
)
2078 * So far inotify is the only supported default notify mechanism. If
2079 * another platform like the the BSD's or a proprietary Unix comes
2080 * along and wants another default, we can play the same trick we
2081 * played with Posix ACLs.
2083 * Until that is the case, hard-code inotify here.
2086 if (lp_kernel_change_notify(vfs_handle
->conn
->params
)) {
2087 return inotify_watch(ctx
, path
, filter
, subdir_filter
,
2088 callback
, private_data
, handle
);
2092 * Do nothing, leave everything to notify_internal.c
2094 return NT_STATUS_OK
;
2097 static int vfswrap_chflags(vfs_handle_struct
*handle
, const char *path
,
2101 return chflags(path
, flags
);
2108 static struct file_id
vfswrap_file_id_create(struct vfs_handle_struct
*handle
,
2109 const SMB_STRUCT_STAT
*sbuf
)
2113 /* the ZERO_STRUCT ensures padding doesn't break using the key as a
2117 key
.devid
= sbuf
->st_ex_dev
;
2118 key
.inode
= sbuf
->st_ex_ino
;
2119 /* key.extid is unused by default. */
2124 static NTSTATUS
vfswrap_streaminfo(vfs_handle_struct
*handle
,
2125 struct files_struct
*fsp
,
2127 TALLOC_CTX
*mem_ctx
,
2128 unsigned int *pnum_streams
,
2129 struct stream_struct
**pstreams
)
2131 SMB_STRUCT_STAT sbuf
;
2132 struct stream_struct
*tmp_streams
= NULL
;
2135 if ((fsp
!= NULL
) && (fsp
->is_directory
)) {
2137 * No default streams on directories
2142 if ((fsp
!= NULL
) && (fsp
->fh
->fd
!= -1)) {
2143 ret
= SMB_VFS_FSTAT(fsp
, &sbuf
);
2146 struct smb_filename smb_fname
;
2148 ZERO_STRUCT(smb_fname
);
2149 smb_fname
.base_name
= discard_const_p(char, fname
);
2151 if (lp_posix_pathnames()) {
2152 ret
= SMB_VFS_LSTAT(handle
->conn
, &smb_fname
);
2154 ret
= SMB_VFS_STAT(handle
->conn
, &smb_fname
);
2156 sbuf
= smb_fname
.st
;
2160 return map_nt_error_from_unix(errno
);
2163 if (S_ISDIR(sbuf
.st_ex_mode
)) {
2167 tmp_streams
= talloc_realloc(mem_ctx
, *pstreams
, struct stream_struct
,
2168 (*pnum_streams
) + 1);
2169 if (tmp_streams
== NULL
) {
2170 return NT_STATUS_NO_MEMORY
;
2172 tmp_streams
[*pnum_streams
].name
= talloc_strdup(tmp_streams
, "::$DATA");
2173 if (tmp_streams
[*pnum_streams
].name
== NULL
) {
2174 return NT_STATUS_NO_MEMORY
;
2176 tmp_streams
[*pnum_streams
].size
= sbuf
.st_ex_size
;
2177 tmp_streams
[*pnum_streams
].alloc_size
= SMB_VFS_GET_ALLOC_SIZE(handle
->conn
, fsp
, &sbuf
);
2180 *pstreams
= tmp_streams
;
2182 return NT_STATUS_OK
;
2185 static int vfswrap_get_real_filename(struct vfs_handle_struct
*handle
,
2188 TALLOC_CTX
*mem_ctx
,
2192 * Don't fall back to get_real_filename so callers can differentiate
2193 * between a full directory scan and an actual case-insensitive stat.
2199 static const char *vfswrap_connectpath(struct vfs_handle_struct
*handle
,
2202 return handle
->conn
->connectpath
;
2205 static NTSTATUS
vfswrap_brl_lock_windows(struct vfs_handle_struct
*handle
,
2206 struct byte_range_lock
*br_lck
,
2207 struct lock_struct
*plock
,
2210 SMB_ASSERT(plock
->lock_flav
== WINDOWS_LOCK
);
2212 /* Note: blr is not used in the default implementation. */
2213 return brl_lock_windows_default(br_lck
, plock
, blocking_lock
);
2216 static bool vfswrap_brl_unlock_windows(struct vfs_handle_struct
*handle
,
2217 struct messaging_context
*msg_ctx
,
2218 struct byte_range_lock
*br_lck
,
2219 const struct lock_struct
*plock
)
2221 SMB_ASSERT(plock
->lock_flav
== WINDOWS_LOCK
);
2223 return brl_unlock_windows_default(msg_ctx
, br_lck
, plock
);
2226 static bool vfswrap_brl_cancel_windows(struct vfs_handle_struct
*handle
,
2227 struct byte_range_lock
*br_lck
,
2228 struct lock_struct
*plock
)
2230 SMB_ASSERT(plock
->lock_flav
== WINDOWS_LOCK
);
2232 /* Note: blr is not used in the default implementation. */
2233 return brl_lock_cancel_default(br_lck
, plock
);
2236 static bool vfswrap_strict_lock(struct vfs_handle_struct
*handle
,
2238 struct lock_struct
*plock
)
2240 SMB_ASSERT(plock
->lock_type
== READ_LOCK
||
2241 plock
->lock_type
== WRITE_LOCK
);
2243 return strict_lock_default(fsp
, plock
);
2246 static void vfswrap_strict_unlock(struct vfs_handle_struct
*handle
,
2248 struct lock_struct
*plock
)
2250 SMB_ASSERT(plock
->lock_type
== READ_LOCK
||
2251 plock
->lock_type
== WRITE_LOCK
);
2253 strict_unlock_default(fsp
, plock
);
2256 /* NT ACL operations. */
2258 static NTSTATUS
vfswrap_fget_nt_acl(vfs_handle_struct
*handle
,
2260 uint32 security_info
,
2261 TALLOC_CTX
*mem_ctx
,
2262 struct security_descriptor
**ppdesc
)
2266 START_PROFILE(fget_nt_acl
);
2267 result
= posix_fget_nt_acl(fsp
, security_info
,
2269 END_PROFILE(fget_nt_acl
);
2273 static NTSTATUS
vfswrap_get_nt_acl(vfs_handle_struct
*handle
,
2275 uint32 security_info
,
2276 TALLOC_CTX
*mem_ctx
,
2277 struct security_descriptor
**ppdesc
)
2281 START_PROFILE(get_nt_acl
);
2282 result
= posix_get_nt_acl(handle
->conn
, name
, security_info
,
2284 END_PROFILE(get_nt_acl
);
2288 static NTSTATUS
vfswrap_fset_nt_acl(vfs_handle_struct
*handle
, files_struct
*fsp
, uint32 security_info_sent
, const struct security_descriptor
*psd
)
2292 START_PROFILE(fset_nt_acl
);
2293 result
= set_nt_acl(fsp
, security_info_sent
, psd
);
2294 END_PROFILE(fset_nt_acl
);
2298 static NTSTATUS
vfswrap_audit_file(struct vfs_handle_struct
*handle
,
2299 struct smb_filename
*file
,
2300 struct security_acl
*sacl
,
2301 uint32_t access_requested
,
2302 uint32_t access_denied
)
2304 return NT_STATUS_OK
; /* Nothing to do here ... */
2307 static int vfswrap_chmod_acl(vfs_handle_struct
*handle
, const char *name
, mode_t mode
)
2315 START_PROFILE(chmod_acl
);
2316 result
= chmod_acl(handle
->conn
, name
, mode
);
2317 END_PROFILE(chmod_acl
);
2322 static int vfswrap_fchmod_acl(vfs_handle_struct
*handle
, files_struct
*fsp
, mode_t mode
)
2330 START_PROFILE(fchmod_acl
);
2331 result
= fchmod_acl(fsp
, mode
);
2332 END_PROFILE(fchmod_acl
);
2337 static SMB_ACL_T
vfswrap_sys_acl_get_file(vfs_handle_struct
*handle
,
2339 SMB_ACL_TYPE_T type
,
2340 TALLOC_CTX
*mem_ctx
)
2342 return sys_acl_get_file(handle
, path_p
, type
, mem_ctx
);
2345 static SMB_ACL_T
vfswrap_sys_acl_get_fd(vfs_handle_struct
*handle
,
2347 TALLOC_CTX
*mem_ctx
)
2349 return sys_acl_get_fd(handle
, fsp
, mem_ctx
);
2352 static int vfswrap_sys_acl_set_file(vfs_handle_struct
*handle
, const char *name
, SMB_ACL_TYPE_T acltype
, SMB_ACL_T theacl
)
2354 return sys_acl_set_file(handle
, name
, acltype
, theacl
);
2357 static int vfswrap_sys_acl_set_fd(vfs_handle_struct
*handle
, files_struct
*fsp
, SMB_ACL_T theacl
)
2359 return sys_acl_set_fd(handle
, fsp
, theacl
);
2362 static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct
*handle
, const char *path
)
2364 return sys_acl_delete_def_file(handle
, path
);
2367 /****************************************************************
2368 Extended attribute operations.
2369 *****************************************************************/
2371 static ssize_t
vfswrap_getxattr(struct vfs_handle_struct
*handle
,const char *path
, const char *name
, void *value
, size_t size
)
2373 return getxattr(path
, name
, value
, size
);
2376 static ssize_t
vfswrap_fgetxattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, const char *name
, void *value
, size_t size
)
2378 return fgetxattr(fsp
->fh
->fd
, name
, value
, size
);
2381 static ssize_t
vfswrap_listxattr(struct vfs_handle_struct
*handle
, const char *path
, char *list
, size_t size
)
2383 return listxattr(path
, list
, size
);
2386 static ssize_t
vfswrap_flistxattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, char *list
, size_t size
)
2388 return flistxattr(fsp
->fh
->fd
, list
, size
);
2391 static int vfswrap_removexattr(struct vfs_handle_struct
*handle
, const char *path
, const char *name
)
2393 return removexattr(path
, name
);
2396 static int vfswrap_fremovexattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, const char *name
)
2398 return fremovexattr(fsp
->fh
->fd
, name
);
2401 static int vfswrap_setxattr(struct vfs_handle_struct
*handle
, const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
2403 return setxattr(path
, name
, value
, size
, flags
);
2406 static int vfswrap_fsetxattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, const char *name
, const void *value
, size_t size
, int flags
)
2408 return fsetxattr(fsp
->fh
->fd
, name
, value
, size
, flags
);
2411 static bool vfswrap_aio_force(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
)
2416 static bool vfswrap_is_offline(struct vfs_handle_struct
*handle
,
2417 const struct smb_filename
*fname
,
2418 SMB_STRUCT_STAT
*sbuf
)
2422 bool offline
= false;
2424 if (ISDOT(fname
->base_name
) || ISDOTDOT(fname
->base_name
)) {
2428 if (!lp_dmapi_support(SNUM(handle
->conn
)) || !dmapi_have_session()) {
2429 #if defined(ENOTSUP)
2435 status
= get_full_smb_filename(talloc_tos(), fname
, &path
);
2436 if (!NT_STATUS_IS_OK(status
)) {
2437 errno
= map_errno_from_nt_status(status
);
2441 offline
= (dmapi_file_flags(path
) & FILE_ATTRIBUTE_OFFLINE
) != 0;
2448 static int vfswrap_set_offline(struct vfs_handle_struct
*handle
,
2449 const struct smb_filename
*fname
)
2451 /* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */
2452 #if defined(ENOTSUP)
2458 static NTSTATUS
vfswrap_durable_cookie(struct vfs_handle_struct
*handle
,
2459 struct files_struct
*fsp
,
2460 TALLOC_CTX
*mem_ctx
,
2463 return vfs_default_durable_cookie(fsp
, mem_ctx
, cookie
);
2466 static NTSTATUS
vfswrap_durable_disconnect(struct vfs_handle_struct
*handle
,
2467 struct files_struct
*fsp
,
2468 const DATA_BLOB old_cookie
,
2469 TALLOC_CTX
*mem_ctx
,
2470 DATA_BLOB
*new_cookie
)
2472 return vfs_default_durable_disconnect(fsp
, old_cookie
, mem_ctx
,
2476 static NTSTATUS
vfswrap_durable_reconnect(struct vfs_handle_struct
*handle
,
2477 struct smb_request
*smb1req
,
2478 struct smbXsrv_open
*op
,
2479 const DATA_BLOB old_cookie
,
2480 TALLOC_CTX
*mem_ctx
,
2481 struct files_struct
**fsp
,
2482 DATA_BLOB
*new_cookie
)
2484 return vfs_default_durable_reconnect(handle
->conn
, smb1req
, op
,
2485 old_cookie
, mem_ctx
,
2489 static struct vfs_fn_pointers vfs_default_fns
= {
2490 /* Disk operations */
2492 .connect_fn
= vfswrap_connect
,
2493 .disconnect_fn
= vfswrap_disconnect
,
2494 .disk_free_fn
= vfswrap_disk_free
,
2495 .get_quota_fn
= vfswrap_get_quota
,
2496 .set_quota_fn
= vfswrap_set_quota
,
2497 .get_shadow_copy_data_fn
= vfswrap_get_shadow_copy_data
,
2498 .statvfs_fn
= vfswrap_statvfs
,
2499 .fs_capabilities_fn
= vfswrap_fs_capabilities
,
2500 .get_dfs_referrals_fn
= vfswrap_get_dfs_referrals
,
2502 /* Directory operations */
2504 .opendir_fn
= vfswrap_opendir
,
2505 .fdopendir_fn
= vfswrap_fdopendir
,
2506 .readdir_fn
= vfswrap_readdir
,
2507 .seekdir_fn
= vfswrap_seekdir
,
2508 .telldir_fn
= vfswrap_telldir
,
2509 .rewind_dir_fn
= vfswrap_rewinddir
,
2510 .mkdir_fn
= vfswrap_mkdir
,
2511 .rmdir_fn
= vfswrap_rmdir
,
2512 .closedir_fn
= vfswrap_closedir
,
2513 .init_search_op_fn
= vfswrap_init_search_op
,
2515 /* File operations */
2517 .open_fn
= vfswrap_open
,
2518 .create_file_fn
= vfswrap_create_file
,
2519 .close_fn
= vfswrap_close
,
2520 .read_fn
= vfswrap_read
,
2521 .pread_fn
= vfswrap_pread
,
2522 .pread_send_fn
= vfswrap_pread_send
,
2523 .pread_recv_fn
= vfswrap_asys_ssize_t_recv
,
2524 .write_fn
= vfswrap_write
,
2525 .pwrite_fn
= vfswrap_pwrite
,
2526 .pwrite_send_fn
= vfswrap_pwrite_send
,
2527 .pwrite_recv_fn
= vfswrap_asys_ssize_t_recv
,
2528 .lseek_fn
= vfswrap_lseek
,
2529 .sendfile_fn
= vfswrap_sendfile
,
2530 .recvfile_fn
= vfswrap_recvfile
,
2531 .rename_fn
= vfswrap_rename
,
2532 .fsync_fn
= vfswrap_fsync
,
2533 .fsync_send_fn
= vfswrap_fsync_send
,
2534 .fsync_recv_fn
= vfswrap_asys_int_recv
,
2535 .stat_fn
= vfswrap_stat
,
2536 .fstat_fn
= vfswrap_fstat
,
2537 .lstat_fn
= vfswrap_lstat
,
2538 .get_alloc_size_fn
= vfswrap_get_alloc_size
,
2539 .unlink_fn
= vfswrap_unlink
,
2540 .chmod_fn
= vfswrap_chmod
,
2541 .fchmod_fn
= vfswrap_fchmod
,
2542 .chown_fn
= vfswrap_chown
,
2543 .fchown_fn
= vfswrap_fchown
,
2544 .lchown_fn
= vfswrap_lchown
,
2545 .chdir_fn
= vfswrap_chdir
,
2546 .getwd_fn
= vfswrap_getwd
,
2547 .ntimes_fn
= vfswrap_ntimes
,
2548 .ftruncate_fn
= vfswrap_ftruncate
,
2549 .fallocate_fn
= vfswrap_fallocate
,
2550 .lock_fn
= vfswrap_lock
,
2551 .kernel_flock_fn
= vfswrap_kernel_flock
,
2552 .linux_setlease_fn
= vfswrap_linux_setlease
,
2553 .getlock_fn
= vfswrap_getlock
,
2554 .symlink_fn
= vfswrap_symlink
,
2555 .readlink_fn
= vfswrap_readlink
,
2556 .link_fn
= vfswrap_link
,
2557 .mknod_fn
= vfswrap_mknod
,
2558 .realpath_fn
= vfswrap_realpath
,
2559 .notify_watch_fn
= vfswrap_notify_watch
,
2560 .chflags_fn
= vfswrap_chflags
,
2561 .file_id_create_fn
= vfswrap_file_id_create
,
2562 .streaminfo_fn
= vfswrap_streaminfo
,
2563 .get_real_filename_fn
= vfswrap_get_real_filename
,
2564 .connectpath_fn
= vfswrap_connectpath
,
2565 .brl_lock_windows_fn
= vfswrap_brl_lock_windows
,
2566 .brl_unlock_windows_fn
= vfswrap_brl_unlock_windows
,
2567 .brl_cancel_windows_fn
= vfswrap_brl_cancel_windows
,
2568 .strict_lock_fn
= vfswrap_strict_lock
,
2569 .strict_unlock_fn
= vfswrap_strict_unlock
,
2570 .translate_name_fn
= vfswrap_translate_name
,
2571 .fsctl_fn
= vfswrap_fsctl
,
2572 .copy_chunk_send_fn
= vfswrap_copy_chunk_send
,
2573 .copy_chunk_recv_fn
= vfswrap_copy_chunk_recv
,
2574 .get_compression_fn
= vfswrap_get_compression
,
2575 .set_compression_fn
= vfswrap_set_compression
,
2577 /* NT ACL operations. */
2579 .fget_nt_acl_fn
= vfswrap_fget_nt_acl
,
2580 .get_nt_acl_fn
= vfswrap_get_nt_acl
,
2581 .fset_nt_acl_fn
= vfswrap_fset_nt_acl
,
2582 .audit_file_fn
= vfswrap_audit_file
,
2584 /* POSIX ACL operations. */
2586 .chmod_acl_fn
= vfswrap_chmod_acl
,
2587 .fchmod_acl_fn
= vfswrap_fchmod_acl
,
2589 .sys_acl_get_file_fn
= vfswrap_sys_acl_get_file
,
2590 .sys_acl_get_fd_fn
= vfswrap_sys_acl_get_fd
,
2591 .sys_acl_blob_get_file_fn
= posix_sys_acl_blob_get_file
,
2592 .sys_acl_blob_get_fd_fn
= posix_sys_acl_blob_get_fd
,
2593 .sys_acl_set_file_fn
= vfswrap_sys_acl_set_file
,
2594 .sys_acl_set_fd_fn
= vfswrap_sys_acl_set_fd
,
2595 .sys_acl_delete_def_file_fn
= vfswrap_sys_acl_delete_def_file
,
2597 /* EA operations. */
2598 .getxattr_fn
= vfswrap_getxattr
,
2599 .fgetxattr_fn
= vfswrap_fgetxattr
,
2600 .listxattr_fn
= vfswrap_listxattr
,
2601 .flistxattr_fn
= vfswrap_flistxattr
,
2602 .removexattr_fn
= vfswrap_removexattr
,
2603 .fremovexattr_fn
= vfswrap_fremovexattr
,
2604 .setxattr_fn
= vfswrap_setxattr
,
2605 .fsetxattr_fn
= vfswrap_fsetxattr
,
2607 /* aio operations */
2608 .aio_force_fn
= vfswrap_aio_force
,
2610 /* offline operations */
2611 .is_offline_fn
= vfswrap_is_offline
,
2612 .set_offline_fn
= vfswrap_set_offline
,
2614 /* durable handle operations */
2615 .durable_cookie_fn
= vfswrap_durable_cookie
,
2616 .durable_disconnect_fn
= vfswrap_durable_disconnect
,
2617 .durable_reconnect_fn
= vfswrap_durable_reconnect
,
2620 NTSTATUS
vfs_default_init(void);
2621 NTSTATUS
vfs_default_init(void)
2623 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION
,
2624 DEFAULT_VFS_MODULE_NAME
, &vfs_default_fns
);