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"
35 #include "lib/util/sys_rw.h"
38 #define DBGC_CLASS DBGC_VFS
40 /* Check for NULL pointer parameters in vfswrap_* functions */
42 /* We don't want to have NULL function pointers lying around. Someone
43 is sure to try and execute them. These stubs are used to prevent
46 static int vfswrap_connect(vfs_handle_struct
*handle
, const char *service
, const char *user
)
48 return 0; /* Return >= 0 for success */
51 static void vfswrap_disconnect(vfs_handle_struct
*handle
)
57 static uint64_t vfswrap_disk_free(vfs_handle_struct
*handle
, const char *path
,
58 uint64_t *bsize
, uint64_t *dfree
,
61 if (sys_fsusage(path
, dfree
, dsize
) != 0) {
69 static int vfswrap_get_quota(struct vfs_handle_struct
*handle
, const char *path
,
70 enum SMB_QUOTA_TYPE qtype
, unid_t id
,
73 #ifdef HAVE_SYS_QUOTAS
76 START_PROFILE(syscall_get_quota
);
77 result
= sys_get_quota(path
, qtype
, id
, qt
);
78 END_PROFILE(syscall_get_quota
);
86 static int vfswrap_set_quota(struct vfs_handle_struct
*handle
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*qt
)
88 #ifdef HAVE_SYS_QUOTAS
91 START_PROFILE(syscall_set_quota
);
92 result
= sys_set_quota(handle
->conn
->connectpath
, qtype
, id
, qt
);
93 END_PROFILE(syscall_set_quota
);
101 static int vfswrap_get_shadow_copy_data(struct vfs_handle_struct
*handle
,
102 struct files_struct
*fsp
,
103 struct shadow_copy_data
*shadow_copy_data
,
107 return -1; /* Not implemented. */
110 static int vfswrap_statvfs(struct vfs_handle_struct
*handle
, const char *path
, vfs_statvfs_struct
*statbuf
)
112 return sys_statvfs(path
, statbuf
);
115 static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct
*handle
,
116 enum timestamp_set_resolution
*p_ts_res
)
118 connection_struct
*conn
= handle
->conn
;
119 uint32_t caps
= FILE_CASE_SENSITIVE_SEARCH
| FILE_CASE_PRESERVED_NAMES
;
120 struct smb_filename
*smb_fname_cpath
= NULL
;
121 struct vfs_statvfs_struct statbuf
;
124 ZERO_STRUCT(statbuf
);
125 ret
= sys_statvfs(conn
->connectpath
, &statbuf
);
127 caps
= statbuf
.FsCapabilities
;
130 *p_ts_res
= TIMESTAMP_SET_SECONDS
;
132 /* Work out what timestamp resolution we can
133 * use when setting a timestamp. */
135 smb_fname_cpath
= synthetic_smb_fname(talloc_tos(), conn
->connectpath
,
137 if (smb_fname_cpath
== NULL
) {
141 ret
= SMB_VFS_STAT(conn
, smb_fname_cpath
);
143 TALLOC_FREE(smb_fname_cpath
);
147 if (smb_fname_cpath
->st
.st_ex_mtime
.tv_nsec
||
148 smb_fname_cpath
->st
.st_ex_atime
.tv_nsec
||
149 smb_fname_cpath
->st
.st_ex_ctime
.tv_nsec
) {
150 /* If any of the normal UNIX directory timestamps
151 * have a non-zero tv_nsec component assume
152 * we might be able to set sub-second timestamps.
153 * See what filetime set primitives we have.
155 #if defined(HAVE_UTIMENSAT)
156 *p_ts_res
= TIMESTAMP_SET_NT_OR_BETTER
;
157 #elif defined(HAVE_UTIMES)
158 /* utimes allows msec timestamps to be set. */
159 *p_ts_res
= TIMESTAMP_SET_MSEC
;
160 #elif defined(HAVE_UTIME)
161 /* utime only allows sec timestamps to be set. */
162 *p_ts_res
= TIMESTAMP_SET_SECONDS
;
165 DEBUG(10,("vfswrap_fs_capabilities: timestamp "
167 "available on share %s, directory %s\n",
168 *p_ts_res
== TIMESTAMP_SET_MSEC
? "msec" : "sec",
169 lp_servicename(talloc_tos(), conn
->params
->service
),
170 conn
->connectpath
));
172 TALLOC_FREE(smb_fname_cpath
);
176 static NTSTATUS
vfswrap_get_dfs_referrals(struct vfs_handle_struct
*handle
,
177 struct dfs_GetDFSReferral
*r
)
179 struct junction_map
*junction
= NULL
;
181 bool self_referral
= false;
182 char *pathnamep
= NULL
;
183 char *local_dfs_path
= NULL
;
186 uint16_t max_referral_level
= r
->in
.req
.max_referral_level
;
189 NDR_PRINT_IN_DEBUG(dfs_GetDFSReferral
, r
);
192 /* get the junction entry */
193 if (r
->in
.req
.servername
== NULL
) {
194 return NT_STATUS_NOT_FOUND
;
198 * Trim pathname sent by client so it begins with only one backslash.
199 * Two backslashes confuse some dfs clients
202 local_dfs_path
= talloc_strdup(r
, r
->in
.req
.servername
);
203 if (local_dfs_path
== NULL
) {
204 return NT_STATUS_NO_MEMORY
;
206 pathnamep
= local_dfs_path
;
207 while (IS_DIRECTORY_SEP(pathnamep
[0]) &&
208 IS_DIRECTORY_SEP(pathnamep
[1])) {
212 junction
= talloc_zero(r
, struct junction_map
);
213 if (junction
== NULL
) {
214 return NT_STATUS_NO_MEMORY
;
217 /* The following call can change cwd. */
218 status
= get_referred_path(r
, pathnamep
,
219 !handle
->conn
->sconn
->using_smb2
,
220 junction
, &consumedcnt
, &self_referral
);
221 if (!NT_STATUS_IS_OK(status
)) {
222 vfs_ChDir(handle
->conn
, handle
->conn
->connectpath
);
225 vfs_ChDir(handle
->conn
, handle
->conn
->connectpath
);
227 if (!self_referral
) {
228 pathnamep
[consumedcnt
] = '\0';
231 dbgtext("Path %s to alternate path(s):",
233 for (i
=0; i
< junction
->referral_count
; i
++) {
235 junction
->referral_list
[i
].alternate_path
);
241 if (r
->in
.req
.max_referral_level
<= 2) {
242 max_referral_level
= 2;
244 if (r
->in
.req
.max_referral_level
>= 3) {
245 max_referral_level
= 3;
248 r
->out
.resp
= talloc_zero(r
, struct dfs_referral_resp
);
249 if (r
->out
.resp
== NULL
) {
250 return NT_STATUS_NO_MEMORY
;
253 r
->out
.resp
->path_consumed
= strlen_m(pathnamep
) * 2;
254 r
->out
.resp
->nb_referrals
= junction
->referral_count
;
256 r
->out
.resp
->header_flags
= DFS_HEADER_FLAG_STORAGE_SVR
;
258 r
->out
.resp
->header_flags
|= DFS_HEADER_FLAG_REFERAL_SVR
;
261 r
->out
.resp
->referral_entries
= talloc_zero_array(r
,
262 struct dfs_referral_type
,
263 r
->out
.resp
->nb_referrals
);
264 if (r
->out
.resp
->referral_entries
== NULL
) {
265 return NT_STATUS_NO_MEMORY
;
268 switch (max_referral_level
) {
270 for(i
=0; i
< junction
->referral_count
; i
++) {
271 struct referral
*ref
= &junction
->referral_list
[i
];
272 TALLOC_CTX
*mem_ctx
= r
->out
.resp
->referral_entries
;
273 struct dfs_referral_type
*t
=
274 &r
->out
.resp
->referral_entries
[i
];
275 struct dfs_referral_v2
*v2
= &t
->referral
.v2
;
278 v2
->size
= VERSION2_REFERRAL_SIZE
;
280 v2
->server_type
= DFS_SERVER_ROOT
;
282 v2
->server_type
= DFS_SERVER_NON_ROOT
;
285 v2
->proximity
= ref
->proximity
;
287 v2
->DFS_path
= talloc_strdup(mem_ctx
, pathnamep
);
288 if (v2
->DFS_path
== NULL
) {
289 return NT_STATUS_NO_MEMORY
;
291 v2
->DFS_alt_path
= talloc_strdup(mem_ctx
, pathnamep
);
292 if (v2
->DFS_alt_path
== NULL
) {
293 return NT_STATUS_NO_MEMORY
;
295 v2
->netw_address
= talloc_strdup(mem_ctx
,
296 ref
->alternate_path
);
297 if (v2
->netw_address
== NULL
) {
298 return NT_STATUS_NO_MEMORY
;
304 for(i
=0; i
< junction
->referral_count
; i
++) {
305 struct referral
*ref
= &junction
->referral_list
[i
];
306 TALLOC_CTX
*mem_ctx
= r
->out
.resp
->referral_entries
;
307 struct dfs_referral_type
*t
=
308 &r
->out
.resp
->referral_entries
[i
];
309 struct dfs_referral_v3
*v3
= &t
->referral
.v3
;
310 struct dfs_normal_referral
*r1
= &v3
->referrals
.r1
;
313 v3
->size
= VERSION3_REFERRAL_SIZE
;
315 v3
->server_type
= DFS_SERVER_ROOT
;
317 v3
->server_type
= DFS_SERVER_NON_ROOT
;
321 r1
->DFS_path
= talloc_strdup(mem_ctx
, pathnamep
);
322 if (r1
->DFS_path
== NULL
) {
323 return NT_STATUS_NO_MEMORY
;
325 r1
->DFS_alt_path
= talloc_strdup(mem_ctx
, pathnamep
);
326 if (r1
->DFS_alt_path
== NULL
) {
327 return NT_STATUS_NO_MEMORY
;
329 r1
->netw_address
= talloc_strdup(mem_ctx
,
330 ref
->alternate_path
);
331 if (r1
->netw_address
== NULL
) {
332 return NT_STATUS_NO_MEMORY
;
337 DEBUG(0,("Invalid dfs referral version: %d\n",
338 max_referral_level
));
339 return NT_STATUS_INVALID_LEVEL
;
343 NDR_PRINT_OUT_DEBUG(dfs_GetDFSReferral
, r
);
349 static NTSTATUS
vfswrap_snap_check_path(struct vfs_handle_struct
*handle
,
351 const char *service_path
,
354 return NT_STATUS_NOT_SUPPORTED
;
357 static NTSTATUS
vfswrap_snap_create(struct vfs_handle_struct
*handle
,
359 const char *base_volume
,
365 return NT_STATUS_NOT_SUPPORTED
;
368 static NTSTATUS
vfswrap_snap_delete(struct vfs_handle_struct
*handle
,
373 return NT_STATUS_NOT_SUPPORTED
;
376 /* Directory operations */
378 static DIR *vfswrap_opendir(vfs_handle_struct
*handle
,
379 const struct smb_filename
*smb_fname
,
385 START_PROFILE(syscall_opendir
);
386 result
= opendir(smb_fname
->base_name
);
387 END_PROFILE(syscall_opendir
);
391 static DIR *vfswrap_fdopendir(vfs_handle_struct
*handle
,
398 START_PROFILE(syscall_fdopendir
);
399 result
= sys_fdopendir(fsp
->fh
->fd
);
400 END_PROFILE(syscall_fdopendir
);
405 static struct dirent
*vfswrap_readdir(vfs_handle_struct
*handle
,
407 SMB_STRUCT_STAT
*sbuf
)
409 struct dirent
*result
;
411 START_PROFILE(syscall_readdir
);
412 result
= readdir(dirp
);
413 END_PROFILE(syscall_readdir
);
415 /* Default Posix readdir() does not give us stat info.
416 * Set to invalid to indicate we didn't return this info. */
417 SET_STAT_INVALID(*sbuf
);
418 #if defined(HAVE_DIRFD) && defined(HAVE_FSTATAT)
419 if (result
!= NULL
) {
420 /* See if we can efficiently return this. */
422 int flags
= AT_SYMLINK_NOFOLLOW
;
423 int ret
= fstatat(dirfd(dirp
),
428 * As this is an optimization,
429 * ignore it if we stat'ed a
430 * symlink. Make the caller
431 * do it again as we don't
432 * know if they wanted the link
433 * info, or its target info.
435 if ((ret
== 0) && (!S_ISLNK(st
.st_mode
))) {
436 init_stat_ex_from_stat(sbuf
,
438 lp_fake_directory_create_times(
439 SNUM(handle
->conn
)));
447 static NTSTATUS
vfswrap_readdir_attr(struct vfs_handle_struct
*handle
,
448 const struct smb_filename
*fname
,
450 struct readdir_attr_data
**attr_data
)
452 return NT_STATUS_NOT_SUPPORTED
;
455 static void vfswrap_seekdir(vfs_handle_struct
*handle
, DIR *dirp
, long offset
)
457 START_PROFILE(syscall_seekdir
);
458 seekdir(dirp
, offset
);
459 END_PROFILE(syscall_seekdir
);
462 static long vfswrap_telldir(vfs_handle_struct
*handle
, DIR *dirp
)
465 START_PROFILE(syscall_telldir
);
466 result
= telldir(dirp
);
467 END_PROFILE(syscall_telldir
);
471 static void vfswrap_rewinddir(vfs_handle_struct
*handle
, DIR *dirp
)
473 START_PROFILE(syscall_rewinddir
);
475 END_PROFILE(syscall_rewinddir
);
478 static int vfswrap_mkdir(vfs_handle_struct
*handle
,
479 const struct smb_filename
*smb_fname
,
483 bool has_dacl
= False
;
484 const char *path
= smb_fname
->base_name
;
487 START_PROFILE(syscall_mkdir
);
489 if (lp_inherit_acls(SNUM(handle
->conn
))
490 && parent_dirname(talloc_tos(), path
, &parent
, NULL
)
491 && (has_dacl
= directory_has_default_acl(handle
->conn
, parent
))) {
492 mode
= (0777 & lp_directory_mask(SNUM(handle
->conn
)));
497 result
= mkdir(path
, mode
);
499 if (result
== 0 && !has_dacl
) {
501 * We need to do this as the default behavior of POSIX ACLs
502 * is to set the mask to be the requested group permission
503 * bits, not the group permission bits to be the requested
504 * group permission bits. This is not what we want, as it will
505 * mess up any inherited ACL bits that were set. JRA.
507 int saved_errno
= errno
; /* We may get ENOSYS */
508 if ((SMB_VFS_CHMOD_ACL(handle
->conn
, smb_fname
, mode
) == -1) &&
514 END_PROFILE(syscall_mkdir
);
518 static int vfswrap_rmdir(vfs_handle_struct
*handle
,
519 const struct smb_filename
*smb_fname
)
523 START_PROFILE(syscall_rmdir
);
524 result
= rmdir(smb_fname
->base_name
);
525 END_PROFILE(syscall_rmdir
);
529 static int vfswrap_closedir(vfs_handle_struct
*handle
, DIR *dirp
)
533 START_PROFILE(syscall_closedir
);
534 result
= closedir(dirp
);
535 END_PROFILE(syscall_closedir
);
539 static void vfswrap_init_search_op(vfs_handle_struct
*handle
,
542 /* Default behavior is a NOOP */
545 /* File operations */
547 static int vfswrap_open(vfs_handle_struct
*handle
,
548 struct smb_filename
*smb_fname
,
549 files_struct
*fsp
, int flags
, mode_t mode
)
553 START_PROFILE(syscall_open
);
555 if (smb_fname
->stream_name
) {
560 result
= open(smb_fname
->base_name
, flags
, mode
);
562 END_PROFILE(syscall_open
);
566 static NTSTATUS
vfswrap_create_file(vfs_handle_struct
*handle
,
567 struct smb_request
*req
,
568 uint16_t root_dir_fid
,
569 struct smb_filename
*smb_fname
,
570 uint32_t access_mask
,
571 uint32_t share_access
,
572 uint32_t create_disposition
,
573 uint32_t create_options
,
574 uint32_t file_attributes
,
575 uint32_t oplock_request
,
576 struct smb2_lease
*lease
,
577 uint64_t allocation_size
,
578 uint32_t private_flags
,
579 struct security_descriptor
*sd
,
580 struct ea_list
*ea_list
,
581 files_struct
**result
,
583 const struct smb2_create_blobs
*in_context_blobs
,
584 struct smb2_create_blobs
*out_context_blobs
)
586 return create_file_default(handle
->conn
, req
, root_dir_fid
, smb_fname
,
587 access_mask
, share_access
,
588 create_disposition
, create_options
,
589 file_attributes
, oplock_request
, lease
,
590 allocation_size
, private_flags
,
592 pinfo
, in_context_blobs
, out_context_blobs
);
595 static int vfswrap_close(vfs_handle_struct
*handle
, files_struct
*fsp
)
599 START_PROFILE(syscall_close
);
600 result
= fd_close_posix(fsp
);
601 END_PROFILE(syscall_close
);
605 static ssize_t
vfswrap_read(vfs_handle_struct
*handle
, files_struct
*fsp
, void *data
, size_t n
)
609 START_PROFILE_BYTES(syscall_read
, n
);
610 result
= sys_read(fsp
->fh
->fd
, data
, n
);
611 END_PROFILE_BYTES(syscall_read
);
615 static ssize_t
vfswrap_pread(vfs_handle_struct
*handle
, files_struct
*fsp
, void *data
,
616 size_t n
, off_t offset
)
620 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
621 START_PROFILE_BYTES(syscall_pread
, n
);
622 result
= sys_pread(fsp
->fh
->fd
, data
, n
, offset
);
623 END_PROFILE_BYTES(syscall_pread
);
625 if (result
== -1 && errno
== ESPIPE
) {
626 /* Maintain the fiction that pipes can be seeked (sought?) on. */
627 result
= SMB_VFS_READ(fsp
, data
, n
);
631 #else /* HAVE_PREAD */
635 curr
= SMB_VFS_LSEEK(fsp
, 0, SEEK_CUR
);
636 if (curr
== -1 && errno
== ESPIPE
) {
637 /* Maintain the fiction that pipes can be seeked (sought?) on. */
638 result
= SMB_VFS_READ(fsp
, data
, n
);
643 if (SMB_VFS_LSEEK(fsp
, offset
, SEEK_SET
) == -1) {
648 result
= SMB_VFS_READ(fsp
, data
, n
);
651 SMB_VFS_LSEEK(fsp
, curr
, SEEK_SET
);
654 #endif /* HAVE_PREAD */
659 static ssize_t
vfswrap_write(vfs_handle_struct
*handle
, files_struct
*fsp
, const void *data
, size_t n
)
663 START_PROFILE_BYTES(syscall_write
, n
);
664 result
= sys_write(fsp
->fh
->fd
, data
, n
);
665 END_PROFILE_BYTES(syscall_write
);
669 static ssize_t
vfswrap_pwrite(vfs_handle_struct
*handle
, files_struct
*fsp
, const void *data
,
670 size_t n
, off_t offset
)
674 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
675 START_PROFILE_BYTES(syscall_pwrite
, n
);
676 result
= sys_pwrite(fsp
->fh
->fd
, data
, n
, offset
);
677 END_PROFILE_BYTES(syscall_pwrite
);
679 if (result
== -1 && errno
== ESPIPE
) {
680 /* Maintain the fiction that pipes can be sought on. */
681 result
= SMB_VFS_WRITE(fsp
, data
, n
);
684 #else /* HAVE_PWRITE */
688 curr
= SMB_VFS_LSEEK(fsp
, 0, SEEK_CUR
);
693 if (SMB_VFS_LSEEK(fsp
, offset
, SEEK_SET
) == -1) {
697 result
= SMB_VFS_WRITE(fsp
, data
, n
);
700 SMB_VFS_LSEEK(fsp
, curr
, SEEK_SET
);
703 #endif /* HAVE_PWRITE */
708 static void vfswrap_asys_finished(struct tevent_context
*ev
,
709 struct tevent_fd
*fde
,
710 uint16_t flags
, void *p
);
712 static bool vfswrap_init_asys_ctx(struct smbd_server_connection
*conn
)
714 struct asys_context
*ctx
;
715 struct tevent_fd
*fde
;
719 if (conn
->asys_ctx
!= NULL
) {
723 ret
= asys_context_init(&ctx
, lp_aio_max_threads());
725 DEBUG(1, ("asys_context_init failed: %s\n", strerror(ret
)));
729 fd
= asys_signalfd(ctx
);
731 ret
= set_blocking(fd
, false);
733 DBG_WARNING("set_blocking failed: %s\n", strerror(errno
));
737 fde
= tevent_add_fd(conn
->ev_ctx
, conn
, fd
, TEVENT_FD_READ
,
738 vfswrap_asys_finished
, ctx
);
740 DEBUG(1, ("tevent_add_fd failed\n"));
744 conn
->asys_ctx
= ctx
;
745 conn
->asys_fde
= fde
;
749 asys_context_destroy(ctx
);
753 struct vfswrap_asys_state
{
754 struct asys_context
*asys_ctx
;
755 struct tevent_req
*req
;
757 struct vfs_aio_state vfs_aio_state
;
758 SMBPROFILE_BASIC_ASYNC_STATE(profile_basic
);
759 SMBPROFILE_BYTES_ASYNC_STATE(profile_bytes
);
762 static int vfswrap_asys_state_destructor(struct vfswrap_asys_state
*s
)
764 asys_cancel(s
->asys_ctx
, s
->req
);
768 static struct tevent_req
*vfswrap_pread_send(struct vfs_handle_struct
*handle
,
770 struct tevent_context
*ev
,
771 struct files_struct
*fsp
,
773 size_t n
, off_t offset
)
775 struct tevent_req
*req
;
776 struct vfswrap_asys_state
*state
;
779 req
= tevent_req_create(mem_ctx
, &state
, struct vfswrap_asys_state
);
783 if (!vfswrap_init_asys_ctx(handle
->conn
->sconn
)) {
785 return tevent_req_post(req
, ev
);
787 state
->asys_ctx
= handle
->conn
->sconn
->asys_ctx
;
790 SMBPROFILE_BYTES_ASYNC_START(syscall_asys_pread
, profile_p
,
791 state
->profile_bytes
, n
);
792 ret
= asys_pread(state
->asys_ctx
, fsp
->fh
->fd
, data
, n
, offset
, req
);
794 tevent_req_error(req
, ret
);
795 return tevent_req_post(req
, ev
);
797 talloc_set_destructor(state
, vfswrap_asys_state_destructor
);
802 static struct tevent_req
*vfswrap_pwrite_send(struct vfs_handle_struct
*handle
,
804 struct tevent_context
*ev
,
805 struct files_struct
*fsp
,
807 size_t n
, off_t offset
)
809 struct tevent_req
*req
;
810 struct vfswrap_asys_state
*state
;
813 req
= tevent_req_create(mem_ctx
, &state
, struct vfswrap_asys_state
);
817 if (!vfswrap_init_asys_ctx(handle
->conn
->sconn
)) {
819 return tevent_req_post(req
, ev
);
821 state
->asys_ctx
= handle
->conn
->sconn
->asys_ctx
;
824 SMBPROFILE_BYTES_ASYNC_START(syscall_asys_pwrite
, profile_p
,
825 state
->profile_bytes
, n
);
826 ret
= asys_pwrite(state
->asys_ctx
, fsp
->fh
->fd
, data
, n
, offset
, req
);
828 tevent_req_error(req
, ret
);
829 return tevent_req_post(req
, ev
);
831 talloc_set_destructor(state
, vfswrap_asys_state_destructor
);
836 static struct tevent_req
*vfswrap_fsync_send(struct vfs_handle_struct
*handle
,
838 struct tevent_context
*ev
,
839 struct files_struct
*fsp
)
841 struct tevent_req
*req
;
842 struct vfswrap_asys_state
*state
;
845 req
= tevent_req_create(mem_ctx
, &state
, struct vfswrap_asys_state
);
849 if (!vfswrap_init_asys_ctx(handle
->conn
->sconn
)) {
851 return tevent_req_post(req
, ev
);
853 state
->asys_ctx
= handle
->conn
->sconn
->asys_ctx
;
856 SMBPROFILE_BASIC_ASYNC_START(syscall_asys_fsync
, profile_p
,
857 state
->profile_basic
);
858 ret
= asys_fsync(state
->asys_ctx
, fsp
->fh
->fd
, req
);
860 tevent_req_error(req
, ret
);
861 return tevent_req_post(req
, ev
);
863 talloc_set_destructor(state
, vfswrap_asys_state_destructor
);
868 static void vfswrap_asys_finished(struct tevent_context
*ev
,
869 struct tevent_fd
*fde
,
870 uint16_t flags
, void *p
)
872 struct asys_context
*asys_ctx
= (struct asys_context
*)p
;
873 struct asys_result results
[get_outstanding_aio_calls()];
876 if ((flags
& TEVENT_FD_READ
) == 0) {
880 ret
= asys_results(asys_ctx
, results
, get_outstanding_aio_calls());
882 DEBUG(1, ("asys_results returned %s\n", strerror(-ret
)));
886 for (i
=0; i
<ret
; i
++) {
887 struct asys_result
*result
= &results
[i
];
888 struct tevent_req
*req
;
889 struct vfswrap_asys_state
*state
;
891 if ((result
->ret
== -1) && (result
->err
== ECANCELED
)) {
895 req
= talloc_get_type_abort(result
->private_data
,
897 state
= tevent_req_data(req
, struct vfswrap_asys_state
);
899 talloc_set_destructor(state
, NULL
);
901 SMBPROFILE_BASIC_ASYNC_END(state
->profile_basic
);
902 SMBPROFILE_BYTES_ASYNC_END(state
->profile_bytes
);
903 state
->ret
= result
->ret
;
904 state
->vfs_aio_state
.error
= result
->err
;
905 state
->vfs_aio_state
.duration
= result
->duration
;
906 tevent_req_defer_callback(req
, ev
);
907 tevent_req_done(req
);
911 static ssize_t
vfswrap_asys_ssize_t_recv(struct tevent_req
*req
,
912 struct vfs_aio_state
*vfs_aio_state
)
914 struct vfswrap_asys_state
*state
= tevent_req_data(
915 req
, struct vfswrap_asys_state
);
917 if (tevent_req_is_unix_error(req
, &vfs_aio_state
->error
)) {
920 *vfs_aio_state
= state
->vfs_aio_state
;
924 static int vfswrap_asys_int_recv(struct tevent_req
*req
,
925 struct vfs_aio_state
*vfs_aio_state
)
927 struct vfswrap_asys_state
*state
= tevent_req_data(
928 req
, struct vfswrap_asys_state
);
930 if (tevent_req_is_unix_error(req
, &vfs_aio_state
->error
)) {
933 *vfs_aio_state
= state
->vfs_aio_state
;
937 static off_t
vfswrap_lseek(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t offset
, int whence
)
941 START_PROFILE(syscall_lseek
);
943 /* Cope with 'stat' file opens. */
944 if (fsp
->fh
->fd
!= -1)
945 result
= lseek(fsp
->fh
->fd
, offset
, whence
);
948 * We want to maintain the fiction that we can seek
949 * on a fifo for file system purposes. This allows
950 * people to set up UNIX fifo's that feed data to Windows
954 if((result
== -1) && (errno
== ESPIPE
)) {
959 END_PROFILE(syscall_lseek
);
963 static ssize_t
vfswrap_sendfile(vfs_handle_struct
*handle
, int tofd
, files_struct
*fromfsp
, const DATA_BLOB
*hdr
,
964 off_t offset
, size_t n
)
968 START_PROFILE_BYTES(syscall_sendfile
, n
);
969 result
= sys_sendfile(tofd
, fromfsp
->fh
->fd
, hdr
, offset
, n
);
970 END_PROFILE_BYTES(syscall_sendfile
);
974 static ssize_t
vfswrap_recvfile(vfs_handle_struct
*handle
,
982 START_PROFILE_BYTES(syscall_recvfile
, n
);
983 result
= sys_recvfile(fromfd
, tofsp
->fh
->fd
, offset
, n
);
984 END_PROFILE_BYTES(syscall_recvfile
);
988 static int vfswrap_rename(vfs_handle_struct
*handle
,
989 const struct smb_filename
*smb_fname_src
,
990 const struct smb_filename
*smb_fname_dst
)
994 START_PROFILE(syscall_rename
);
996 if (smb_fname_src
->stream_name
|| smb_fname_dst
->stream_name
) {
1001 result
= rename(smb_fname_src
->base_name
, smb_fname_dst
->base_name
);
1004 END_PROFILE(syscall_rename
);
1008 static int vfswrap_fsync(vfs_handle_struct
*handle
, files_struct
*fsp
)
1013 START_PROFILE(syscall_fsync
);
1014 result
= fsync(fsp
->fh
->fd
);
1015 END_PROFILE(syscall_fsync
);
1022 static int vfswrap_stat(vfs_handle_struct
*handle
,
1023 struct smb_filename
*smb_fname
)
1027 START_PROFILE(syscall_stat
);
1029 if (smb_fname
->stream_name
) {
1034 result
= sys_stat(smb_fname
->base_name
, &smb_fname
->st
,
1035 lp_fake_directory_create_times(SNUM(handle
->conn
)));
1037 END_PROFILE(syscall_stat
);
1041 static int vfswrap_fstat(vfs_handle_struct
*handle
, files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
1045 START_PROFILE(syscall_fstat
);
1046 result
= sys_fstat(fsp
->fh
->fd
,
1047 sbuf
, lp_fake_directory_create_times(SNUM(handle
->conn
)));
1048 END_PROFILE(syscall_fstat
);
1052 static int vfswrap_lstat(vfs_handle_struct
*handle
,
1053 struct smb_filename
*smb_fname
)
1057 START_PROFILE(syscall_lstat
);
1059 if (smb_fname
->stream_name
) {
1064 result
= sys_lstat(smb_fname
->base_name
, &smb_fname
->st
,
1065 lp_fake_directory_create_times(SNUM(handle
->conn
)));
1067 END_PROFILE(syscall_lstat
);
1071 static NTSTATUS
vfswrap_translate_name(struct vfs_handle_struct
*handle
,
1073 enum vfs_translate_direction direction
,
1074 TALLOC_CTX
*mem_ctx
,
1077 return NT_STATUS_NONE_MAPPED
;
1081 * Implement the default fsctl operation.
1083 static bool vfswrap_logged_ioctl_message
= false;
1085 static NTSTATUS
vfswrap_fsctl(struct vfs_handle_struct
*handle
,
1086 struct files_struct
*fsp
,
1089 uint16_t req_flags
, /* Needed for UNICODE ... */
1090 const uint8_t *_in_data
,
1092 uint8_t **_out_data
,
1093 uint32_t max_out_len
,
1096 const char *in_data
= (const char *)_in_data
;
1097 char **out_data
= (char **)_out_data
;
1101 case FSCTL_SET_SPARSE
:
1103 bool set_sparse
= true;
1105 if (in_len
>= 1 && in_data
[0] == 0) {
1109 status
= file_set_sparse(handle
->conn
, fsp
, set_sparse
);
1111 DEBUG(NT_STATUS_IS_OK(status
) ? 10 : 9,
1112 ("FSCTL_SET_SPARSE: fname[%s] set[%u] - %s\n",
1113 smb_fname_str_dbg(fsp
->fsp_name
), set_sparse
,
1114 nt_errstr(status
)));
1119 case FSCTL_CREATE_OR_GET_OBJECT_ID
:
1121 unsigned char objid
[16];
1122 char *return_data
= NULL
;
1124 /* This should return the object-id on this file.
1125 * I think I'll make this be the inode+dev. JRA.
1128 DEBUG(10,("FSCTL_CREATE_OR_GET_OBJECT_ID: called on %s\n",
1129 fsp_fnum_dbg(fsp
)));
1131 *out_len
= MIN(max_out_len
, 64);
1133 /* Hmmm, will this cause problems if less data asked for? */
1134 return_data
= talloc_array(ctx
, char, 64);
1135 if (return_data
== NULL
) {
1136 return NT_STATUS_NO_MEMORY
;
1139 /* For backwards compatibility only store the dev/inode. */
1140 push_file_id_16(return_data
, &fsp
->file_id
);
1141 memcpy(return_data
+16,create_volume_objectid(fsp
->conn
,objid
),16);
1142 push_file_id_16(return_data
+32, &fsp
->file_id
);
1143 memset(return_data
+48, 0, 16);
1144 *out_data
= return_data
;
1145 return NT_STATUS_OK
;
1148 case FSCTL_GET_REPARSE_POINT
:
1150 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
1151 DEBUG(10, ("FSCTL_GET_REPARSE_POINT: called on %s. "
1152 "Status: NOT_IMPLEMENTED\n", fsp_fnum_dbg(fsp
)));
1153 return NT_STATUS_NOT_A_REPARSE_POINT
;
1156 case FSCTL_SET_REPARSE_POINT
:
1158 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
1159 DEBUG(10, ("FSCTL_SET_REPARSE_POINT: called on %s. "
1160 "Status: NOT_IMPLEMENTED\n", fsp_fnum_dbg(fsp
)));
1161 return NT_STATUS_NOT_A_REPARSE_POINT
;
1164 case FSCTL_GET_SHADOW_COPY_DATA
:
1167 * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
1168 * and return their volume names. If max_data_count is 16, then it is just
1169 * asking for the number of volumes and length of the combined names.
1171 * pdata is the data allocated by our caller, but that uses
1172 * total_data_count (which is 0 in our case) rather than max_data_count.
1173 * Allocate the correct amount and return the pointer to let
1174 * it be deallocated when we return.
1176 struct shadow_copy_data
*shadow_data
= NULL
;
1177 bool labels
= False
;
1178 uint32_t labels_data_count
= 0;
1180 char *cur_pdata
= NULL
;
1182 if (max_out_len
< 16) {
1183 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
1185 return NT_STATUS_INVALID_PARAMETER
;
1188 if (max_out_len
> 16) {
1192 shadow_data
= talloc_zero(ctx
, struct shadow_copy_data
);
1193 if (shadow_data
== NULL
) {
1194 DEBUG(0,("TALLOC_ZERO() failed!\n"));
1195 return NT_STATUS_NO_MEMORY
;
1199 * Call the VFS routine to actually do the work.
1201 if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp
, shadow_data
, labels
)!=0) {
1204 /* broken module didn't set errno on error */
1205 status
= NT_STATUS_UNSUCCESSFUL
;
1207 status
= map_nt_error_from_unix(errno
);
1208 if (NT_STATUS_EQUAL(status
,
1209 NT_STATUS_NOT_SUPPORTED
)) {
1213 DEBUG(log_lev
, ("FSCTL_GET_SHADOW_COPY_DATA: "
1214 "connectpath %s, failed - %s.\n",
1215 fsp
->conn
->connectpath
,
1216 nt_errstr(status
)));
1217 TALLOC_FREE(shadow_data
);
1221 labels_data_count
= (shadow_data
->num_volumes
* 2 *
1222 sizeof(SHADOW_COPY_LABEL
)) + 2;
1227 *out_len
= 12 + labels_data_count
;
1230 if (max_out_len
< *out_len
) {
1231 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
1232 max_out_len
, *out_len
));
1233 TALLOC_FREE(shadow_data
);
1234 return NT_STATUS_BUFFER_TOO_SMALL
;
1237 cur_pdata
= talloc_zero_array(ctx
, char, *out_len
);
1238 if (cur_pdata
== NULL
) {
1239 TALLOC_FREE(shadow_data
);
1240 return NT_STATUS_NO_MEMORY
;
1243 *out_data
= cur_pdata
;
1245 /* num_volumes 4 bytes */
1246 SIVAL(cur_pdata
, 0, shadow_data
->num_volumes
);
1249 /* num_labels 4 bytes */
1250 SIVAL(cur_pdata
, 4, shadow_data
->num_volumes
);
1253 /* needed_data_count 4 bytes */
1254 SIVAL(cur_pdata
, 8, labels_data_count
);
1258 DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
1259 shadow_data
->num_volumes
, fsp_str_dbg(fsp
)));
1260 if (labels
&& shadow_data
->labels
) {
1261 for (i
=0; i
<shadow_data
->num_volumes
; i
++) {
1263 status
= srvstr_push(cur_pdata
, req_flags
,
1264 cur_pdata
, shadow_data
->labels
[i
],
1265 2 * sizeof(SHADOW_COPY_LABEL
),
1266 STR_UNICODE
|STR_TERMINATE
, &len
);
1267 if (!NT_STATUS_IS_OK(status
)) {
1268 TALLOC_FREE(*out_data
);
1269 TALLOC_FREE(shadow_data
);
1272 cur_pdata
+= 2 * sizeof(SHADOW_COPY_LABEL
);
1273 DEBUGADD(10,("Label[%u]: '%s'\n",i
,shadow_data
->labels
[i
]));
1277 TALLOC_FREE(shadow_data
);
1279 return NT_STATUS_OK
;
1282 case FSCTL_FIND_FILES_BY_SID
:
1284 /* pretend this succeeded -
1286 * we have to send back a list with all files owned by this SID
1288 * but I have to check that --metze
1294 DEBUG(10, ("FSCTL_FIND_FILES_BY_SID: called on %s\n",
1295 fsp_fnum_dbg(fsp
)));
1298 /* NT_STATUS_BUFFER_TOO_SMALL maybe? */
1299 return NT_STATUS_INVALID_PARAMETER
;
1302 sid_len
= MIN(in_len
- 4,SID_MAX_SIZE
);
1304 /* unknown 4 bytes: this is not the length of the sid :-( */
1305 /*unknown = IVAL(pdata,0);*/
1307 if (!sid_parse(_in_data
+ 4, sid_len
, &sid
)) {
1308 return NT_STATUS_INVALID_PARAMETER
;
1310 DEBUGADD(10, ("for SID: %s\n", sid_string_dbg(&sid
)));
1312 if (!sid_to_uid(&sid
, &uid
)) {
1313 DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
1314 sid_string_dbg(&sid
),
1315 (unsigned long)sid_len
));
1319 /* we can take a look at the find source :-)
1321 * find ./ -uid $uid -name '*' is what we need here
1324 * and send 4bytes len and then NULL terminated unicode strings
1327 * but I don't know how to deal with the paged results
1328 * (maybe we can hang the result anywhere in the fsp struct)
1330 * but I don't know how to deal with the paged results
1331 * (maybe we can hang the result anywhere in the fsp struct)
1333 * we don't send all files at once
1334 * and at the next we should *not* start from the beginning,
1335 * so we have to cache the result
1340 /* this works for now... */
1341 return NT_STATUS_OK
;
1344 case FSCTL_QUERY_ALLOCATED_RANGES
:
1346 /* FIXME: This is just a dummy reply, telling that all of the
1347 * file is allocated. MKS cp needs that.
1348 * Adding the real allocated ranges via FIEMAP on Linux
1349 * and SEEK_DATA/SEEK_HOLE on Solaris is needed to make
1350 * this FSCTL correct for sparse files.
1352 uint64_t offset
, length
;
1353 char *out_data_tmp
= NULL
;
1356 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: data_count(%u) != 16 is invalid!\n",
1358 return NT_STATUS_INVALID_PARAMETER
;
1361 if (max_out_len
< 16) {
1362 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: max_out_len (%u) < 16 is invalid!\n",
1364 return NT_STATUS_INVALID_PARAMETER
;
1367 offset
= BVAL(in_data
,0);
1368 length
= BVAL(in_data
,8);
1370 if (offset
+ length
< offset
) {
1371 /* No 64-bit integer wrap. */
1372 return NT_STATUS_INVALID_PARAMETER
;
1375 /* Shouldn't this be SMB_VFS_STAT ... ? */
1376 status
= vfs_stat_fsp(fsp
);
1377 if (!NT_STATUS_IS_OK(status
)) {
1382 out_data_tmp
= talloc_array(ctx
, char, *out_len
);
1383 if (out_data_tmp
== NULL
) {
1384 DEBUG(10, ("unable to allocate memory for response\n"));
1385 return NT_STATUS_NO_MEMORY
;
1388 if (offset
> fsp
->fsp_name
->st
.st_ex_size
||
1389 fsp
->fsp_name
->st
.st_ex_size
== 0 ||
1391 memset(out_data_tmp
, 0, *out_len
);
1393 uint64_t end
= offset
+ length
;
1394 end
= MIN(end
, fsp
->fsp_name
->st
.st_ex_size
);
1395 SBVAL(out_data_tmp
, 0, 0);
1396 SBVAL(out_data_tmp
, 8, end
);
1399 *out_data
= out_data_tmp
;
1401 return NT_STATUS_OK
;
1404 case FSCTL_IS_VOLUME_DIRTY
:
1406 DEBUG(10,("FSCTL_IS_VOLUME_DIRTY: called on %s "
1407 "(but remotely not supported)\n", fsp_fnum_dbg(fsp
)));
1409 * http://msdn.microsoft.com/en-us/library/cc232128%28PROT.10%29.aspx
1410 * says we have to respond with NT_STATUS_INVALID_PARAMETER
1412 return NT_STATUS_INVALID_PARAMETER
;
1417 * Only print once ... unfortunately there could be lots of
1418 * different FSCTLs that are called.
1420 if (!vfswrap_logged_ioctl_message
) {
1421 vfswrap_logged_ioctl_message
= true;
1422 DEBUG(2, ("%s (0x%x): Currently not implemented.\n",
1423 __func__
, function
));
1427 return NT_STATUS_NOT_SUPPORTED
;
1430 static NTSTATUS
vfswrap_get_dos_attributes(struct vfs_handle_struct
*handle
,
1431 struct smb_filename
*smb_fname
,
1434 return get_ea_dos_attribute(handle
->conn
, smb_fname
, dosmode
);
1437 static NTSTATUS
vfswrap_fget_dos_attributes(struct vfs_handle_struct
*handle
,
1438 struct files_struct
*fsp
,
1441 return get_ea_dos_attribute(handle
->conn
, fsp
->fsp_name
, dosmode
);
1444 static NTSTATUS
vfswrap_set_dos_attributes(struct vfs_handle_struct
*handle
,
1445 const struct smb_filename
*smb_fname
,
1448 return set_ea_dos_attribute(handle
->conn
, smb_fname
, dosmode
);
1451 static NTSTATUS
vfswrap_fset_dos_attributes(struct vfs_handle_struct
*handle
,
1452 struct files_struct
*fsp
,
1455 return set_ea_dos_attribute(handle
->conn
, fsp
->fsp_name
, dosmode
);
1458 struct vfs_cc_state
{
1463 static struct tevent_req
*vfswrap_copy_chunk_send(struct vfs_handle_struct
*handle
,
1464 TALLOC_CTX
*mem_ctx
,
1465 struct tevent_context
*ev
,
1466 struct files_struct
*src_fsp
,
1468 struct files_struct
*dest_fsp
,
1472 struct tevent_req
*req
;
1473 struct vfs_cc_state
*vfs_cc_state
;
1476 DEBUG(10, ("performing server side copy chunk of length %lu\n",
1477 (unsigned long)num
));
1479 req
= tevent_req_create(mem_ctx
, &vfs_cc_state
, struct vfs_cc_state
);
1484 vfs_cc_state
->buf
= talloc_array(vfs_cc_state
, uint8_t,
1485 MIN(num
, 8*1024*1024));
1486 if (tevent_req_nomem(vfs_cc_state
->buf
, req
)) {
1487 return tevent_req_post(req
, ev
);
1490 status
= vfs_stat_fsp(src_fsp
);
1491 if (tevent_req_nterror(req
, status
)) {
1492 return tevent_req_post(req
, ev
);
1495 if (src_fsp
->fsp_name
->st
.st_ex_size
< src_off
+ num
) {
1497 * [MS-SMB2] 3.3.5.15.6 Handling a Server-Side Data Copy Request
1498 * If the SourceOffset or SourceOffset + Length extends beyond
1499 * the end of file, the server SHOULD<240> treat this as a
1500 * STATUS_END_OF_FILE error.
1502 * <240> Section 3.3.5.15.6: Windows servers will return
1503 * STATUS_INVALID_VIEW_SIZE instead of STATUS_END_OF_FILE.
1505 tevent_req_nterror(req
, NT_STATUS_INVALID_VIEW_SIZE
);
1506 return tevent_req_post(req
, ev
);
1509 /* could use 2.6.33+ sendfile here to do this in kernel */
1510 while (vfs_cc_state
->copied
< num
) {
1512 struct lock_struct lck
;
1515 off_t this_num
= MIN(talloc_array_length(vfs_cc_state
->buf
),
1516 num
- vfs_cc_state
->copied
);
1518 if (src_fsp
->op
== NULL
) {
1519 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
1520 return tevent_req_post(req
, ev
);
1522 init_strict_lock_struct(src_fsp
,
1523 src_fsp
->op
->global
->open_persistent_id
,
1529 if (!SMB_VFS_STRICT_LOCK(src_fsp
->conn
, src_fsp
, &lck
)) {
1530 tevent_req_nterror(req
, NT_STATUS_FILE_LOCK_CONFLICT
);
1531 return tevent_req_post(req
, ev
);
1534 ret
= SMB_VFS_PREAD(src_fsp
, vfs_cc_state
->buf
,
1537 saved_errno
= errno
;
1540 SMB_VFS_STRICT_UNLOCK(src_fsp
->conn
, src_fsp
, &lck
);
1543 errno
= saved_errno
;
1544 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
1545 return tevent_req_post(req
, ev
);
1547 if (ret
!= this_num
) {
1548 /* zero tolerance for short reads */
1549 tevent_req_nterror(req
, NT_STATUS_IO_DEVICE_ERROR
);
1550 return tevent_req_post(req
, ev
);
1555 if (dest_fsp
->op
== NULL
) {
1556 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
1557 return tevent_req_post(req
, ev
);
1560 init_strict_lock_struct(dest_fsp
,
1561 dest_fsp
->op
->global
->open_persistent_id
,
1567 if (!SMB_VFS_STRICT_LOCK(dest_fsp
->conn
, dest_fsp
, &lck
)) {
1568 tevent_req_nterror(req
, NT_STATUS_FILE_LOCK_CONFLICT
);
1569 return tevent_req_post(req
, ev
);
1572 ret
= SMB_VFS_PWRITE(dest_fsp
, vfs_cc_state
->buf
,
1573 this_num
, dest_off
);
1575 saved_errno
= errno
;
1578 SMB_VFS_STRICT_UNLOCK(src_fsp
->conn
, src_fsp
, &lck
);
1581 errno
= saved_errno
;
1582 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
1583 return tevent_req_post(req
, ev
);
1585 if (ret
!= this_num
) {
1586 /* zero tolerance for short writes */
1587 tevent_req_nterror(req
, NT_STATUS_IO_DEVICE_ERROR
);
1588 return tevent_req_post(req
, ev
);
1592 vfs_cc_state
->copied
+= this_num
;
1595 tevent_req_done(req
);
1596 return tevent_req_post(req
, ev
);
1599 static NTSTATUS
vfswrap_copy_chunk_recv(struct vfs_handle_struct
*handle
,
1600 struct tevent_req
*req
,
1603 struct vfs_cc_state
*vfs_cc_state
= tevent_req_data(req
,
1604 struct vfs_cc_state
);
1607 if (tevent_req_is_nterror(req
, &status
)) {
1608 DEBUG(2, ("server side copy chunk failed: %s\n",
1609 nt_errstr(status
)));
1611 tevent_req_received(req
);
1615 *copied
= vfs_cc_state
->copied
;
1616 DEBUG(10, ("server side copy chunk copied %lu\n",
1617 (unsigned long)*copied
));
1618 tevent_req_received(req
);
1620 return NT_STATUS_OK
;
1623 static NTSTATUS
vfswrap_get_compression(struct vfs_handle_struct
*handle
,
1624 TALLOC_CTX
*mem_ctx
,
1625 struct files_struct
*fsp
,
1626 struct smb_filename
*smb_fname
,
1627 uint16_t *_compression_fmt
)
1629 return NT_STATUS_INVALID_DEVICE_REQUEST
;
1632 static NTSTATUS
vfswrap_set_compression(struct vfs_handle_struct
*handle
,
1633 TALLOC_CTX
*mem_ctx
,
1634 struct files_struct
*fsp
,
1635 uint16_t compression_fmt
)
1637 return NT_STATUS_INVALID_DEVICE_REQUEST
;
1640 /********************************************************************
1641 Given a stat buffer return the allocated size on disk, taking into
1642 account sparse files.
1643 ********************************************************************/
1644 static uint64_t vfswrap_get_alloc_size(vfs_handle_struct
*handle
,
1645 struct files_struct
*fsp
,
1646 const SMB_STRUCT_STAT
*sbuf
)
1650 START_PROFILE(syscall_get_alloc_size
);
1652 if(S_ISDIR(sbuf
->st_ex_mode
)) {
1657 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
1658 /* The type of st_blocksize is blkcnt_t which *MUST* be
1659 signed (according to POSIX) and can be less than 64-bits.
1660 Ensure when we're converting to 64 bits wide we don't
1662 #if defined(SIZEOF_BLKCNT_T_8)
1663 result
= (uint64_t)STAT_ST_BLOCKSIZE
* (uint64_t)sbuf
->st_ex_blocks
;
1664 #elif defined(SIZEOF_BLKCNT_T_4)
1666 uint64_t bs
= ((uint64_t)sbuf
->st_ex_blocks
) & 0xFFFFFFFFLL
;
1667 result
= (uint64_t)STAT_ST_BLOCKSIZE
* bs
;
1670 #error SIZEOF_BLKCNT_T_NOT_A_SUPPORTED_VALUE
1674 * Some file systems do not allocate a block for very
1675 * small files. But for non-empty file should report a
1679 uint64_t filesize
= get_file_size_stat(sbuf
);
1681 result
= MIN((uint64_t)STAT_ST_BLOCKSIZE
, filesize
);
1685 result
= get_file_size_stat(sbuf
);
1688 if (fsp
&& fsp
->initial_allocation_size
)
1689 result
= MAX(result
,fsp
->initial_allocation_size
);
1691 result
= smb_roundup(handle
->conn
, result
);
1694 END_PROFILE(syscall_get_alloc_size
);
1698 static int vfswrap_unlink(vfs_handle_struct
*handle
,
1699 const struct smb_filename
*smb_fname
)
1703 START_PROFILE(syscall_unlink
);
1705 if (smb_fname
->stream_name
) {
1709 result
= unlink(smb_fname
->base_name
);
1712 END_PROFILE(syscall_unlink
);
1716 static int vfswrap_chmod(vfs_handle_struct
*handle
,
1717 const struct smb_filename
*smb_fname
,
1722 START_PROFILE(syscall_chmod
);
1725 * We need to do this due to the fact that the default POSIX ACL
1726 * chmod modifies the ACL *mask* for the group owner, not the
1727 * group owner bits directly. JRA.
1732 int saved_errno
= errno
; /* We might get ENOSYS */
1733 result
= SMB_VFS_CHMOD_ACL(handle
->conn
,
1737 END_PROFILE(syscall_chmod
);
1740 /* Error - return the old errno. */
1741 errno
= saved_errno
;
1744 result
= chmod(smb_fname
->base_name
, mode
);
1745 END_PROFILE(syscall_chmod
);
1749 static int vfswrap_fchmod(vfs_handle_struct
*handle
, files_struct
*fsp
, mode_t mode
)
1753 START_PROFILE(syscall_fchmod
);
1756 * We need to do this due to the fact that the default POSIX ACL
1757 * chmod modifies the ACL *mask* for the group owner, not the
1758 * group owner bits directly. JRA.
1762 int saved_errno
= errno
; /* We might get ENOSYS */
1763 if ((result
= SMB_VFS_FCHMOD_ACL(fsp
, mode
)) == 0) {
1764 END_PROFILE(syscall_fchmod
);
1767 /* Error - return the old errno. */
1768 errno
= saved_errno
;
1771 #if defined(HAVE_FCHMOD)
1772 result
= fchmod(fsp
->fh
->fd
, mode
);
1778 END_PROFILE(syscall_fchmod
);
1782 static int vfswrap_chown(vfs_handle_struct
*handle
,
1783 const struct smb_filename
*smb_fname
,
1789 START_PROFILE(syscall_chown
);
1790 result
= chown(smb_fname
->base_name
, uid
, gid
);
1791 END_PROFILE(syscall_chown
);
1795 static int vfswrap_fchown(vfs_handle_struct
*handle
, files_struct
*fsp
, uid_t uid
, gid_t gid
)
1800 START_PROFILE(syscall_fchown
);
1801 result
= fchown(fsp
->fh
->fd
, uid
, gid
);
1802 END_PROFILE(syscall_fchown
);
1810 static int vfswrap_lchown(vfs_handle_struct
*handle
,
1811 const struct smb_filename
*smb_fname
,
1817 START_PROFILE(syscall_lchown
);
1818 result
= lchown(smb_fname
->base_name
, uid
, gid
);
1819 END_PROFILE(syscall_lchown
);
1823 static int vfswrap_chdir(vfs_handle_struct
*handle
, const char *path
)
1827 START_PROFILE(syscall_chdir
);
1828 result
= chdir(path
);
1829 END_PROFILE(syscall_chdir
);
1833 static char *vfswrap_getwd(vfs_handle_struct
*handle
)
1837 START_PROFILE(syscall_getwd
);
1838 result
= sys_getwd();
1839 END_PROFILE(syscall_getwd
);
1843 /*********************************************************************
1844 nsec timestamp resolution call. Convert down to whatever the underlying
1845 system will support.
1846 **********************************************************************/
1848 static int vfswrap_ntimes(vfs_handle_struct
*handle
,
1849 const struct smb_filename
*smb_fname
,
1850 struct smb_file_time
*ft
)
1854 START_PROFILE(syscall_ntimes
);
1856 if (smb_fname
->stream_name
) {
1862 if (null_timespec(ft
->atime
)) {
1863 ft
->atime
= smb_fname
->st
.st_ex_atime
;
1866 if (null_timespec(ft
->mtime
)) {
1867 ft
->mtime
= smb_fname
->st
.st_ex_mtime
;
1870 if (!null_timespec(ft
->create_time
)) {
1871 set_create_timespec_ea(handle
->conn
,
1876 if ((timespec_compare(&ft
->atime
,
1877 &smb_fname
->st
.st_ex_atime
) == 0) &&
1878 (timespec_compare(&ft
->mtime
,
1879 &smb_fname
->st
.st_ex_mtime
) == 0)) {
1884 #if defined(HAVE_UTIMENSAT)
1886 struct timespec ts
[2];
1889 result
= utimensat(AT_FDCWD
, smb_fname
->base_name
, ts
, 0);
1891 result
= utimensat(AT_FDCWD
, smb_fname
->base_name
, NULL
, 0);
1893 if (!((result
== -1) && (errno
== ENOSYS
))) {
1897 #if defined(HAVE_UTIMES)
1899 struct timeval tv
[2];
1900 tv
[0] = convert_timespec_to_timeval(ft
->atime
);
1901 tv
[1] = convert_timespec_to_timeval(ft
->mtime
);
1902 result
= utimes(smb_fname
->base_name
, tv
);
1904 result
= utimes(smb_fname
->base_name
, NULL
);
1906 if (!((result
== -1) && (errno
== ENOSYS
))) {
1910 #if defined(HAVE_UTIME)
1912 struct utimbuf times
;
1913 times
.actime
= convert_timespec_to_time_t(ft
->atime
);
1914 times
.modtime
= convert_timespec_to_time_t(ft
->mtime
);
1915 result
= utime(smb_fname
->base_name
, ×
);
1917 result
= utime(smb_fname
->base_name
, NULL
);
1919 if (!((result
== -1) && (errno
== ENOSYS
))) {
1927 END_PROFILE(syscall_ntimes
);
1931 /*********************************************************************
1932 A version of ftruncate that will write the space on disk if strict
1934 **********************************************************************/
1936 static int strict_allocate_ftruncate(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t len
)
1938 off_t space_to_write
;
1939 uint64_t space_avail
;
1940 uint64_t bsize
,dfree
,dsize
;
1943 SMB_STRUCT_STAT
*pst
;
1945 status
= vfs_stat_fsp(fsp
);
1946 if (!NT_STATUS_IS_OK(status
)) {
1949 pst
= &fsp
->fsp_name
->st
;
1952 if (S_ISFIFO(pst
->st_ex_mode
))
1956 if (pst
->st_ex_size
== len
)
1959 /* Shrink - just ftruncate. */
1960 if (pst
->st_ex_size
> len
)
1961 return ftruncate(fsp
->fh
->fd
, len
);
1963 space_to_write
= len
- pst
->st_ex_size
;
1965 /* for allocation try fallocate first. This can fail on some
1966 platforms e.g. when the filesystem doesn't support it and no
1967 emulation is being done by the libc (like on AIX with JFS1). In that
1968 case we do our own emulation. fallocate implementations can
1969 return ENOTSUP or EINVAL in cases like that. */
1970 ret
= SMB_VFS_FALLOCATE(fsp
, 0, pst
->st_ex_size
, space_to_write
);
1971 if (ret
== -1 && errno
== ENOSPC
) {
1977 DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with "
1978 "error %d. Falling back to slow manual allocation\n", errno
));
1980 /* available disk space is enough or not? */
1981 space_avail
= get_dfree_info(fsp
->conn
,
1982 fsp
->fsp_name
->base_name
,
1983 &bsize
, &dfree
, &dsize
);
1984 /* space_avail is 1k blocks */
1985 if (space_avail
== (uint64_t)-1 ||
1986 ((uint64_t)space_to_write
/1024 > space_avail
) ) {
1991 /* Write out the real space on disk. */
1992 ret
= vfs_slow_fallocate(fsp
, pst
->st_ex_size
, space_to_write
);
2000 static int vfswrap_ftruncate(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t len
)
2003 SMB_STRUCT_STAT
*pst
;
2007 START_PROFILE(syscall_ftruncate
);
2009 if (lp_strict_allocate(SNUM(fsp
->conn
)) && !fsp
->is_sparse
) {
2010 result
= strict_allocate_ftruncate(handle
, fsp
, len
);
2011 END_PROFILE(syscall_ftruncate
);
2015 /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
2016 ftruncate if the system supports it. Then I discovered that
2017 you can have some filesystems that support ftruncate
2018 expansion and some that don't! On Linux fat can't do
2019 ftruncate extend but ext2 can. */
2021 result
= ftruncate(fsp
->fh
->fd
, len
);
2023 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
2024 extend a file with ftruncate. Provide alternate implementation
2027 /* Do an fstat to see if the file is longer than the requested
2028 size in which case the ftruncate above should have
2029 succeeded or shorter, in which case seek to len - 1 and
2030 write 1 byte of zero */
2031 status
= vfs_stat_fsp(fsp
);
2032 if (!NT_STATUS_IS_OK(status
)) {
2036 /* We need to update the files_struct after successful ftruncate */
2041 pst
= &fsp
->fsp_name
->st
;
2044 if (S_ISFIFO(pst
->st_ex_mode
)) {
2050 if (pst
->st_ex_size
== len
) {
2055 if (pst
->st_ex_size
> len
) {
2056 /* the ftruncate should have worked */
2060 if (SMB_VFS_PWRITE(fsp
, &c
, 1, len
-1)!=1) {
2068 END_PROFILE(syscall_ftruncate
);
2072 static int vfswrap_fallocate(vfs_handle_struct
*handle
,
2080 START_PROFILE(syscall_fallocate
);
2082 result
= sys_posix_fallocate(fsp
->fh
->fd
, offset
, len
);
2084 * posix_fallocate returns 0 on success, errno on error
2085 * and doesn't set errno. Make it behave like fallocate()
2086 * which returns -1, and sets errno on failure.
2093 /* sys_fallocate handles filtering of unsupported mode flags */
2094 result
= sys_fallocate(fsp
->fh
->fd
, mode
, offset
, len
);
2096 END_PROFILE(syscall_fallocate
);
2100 static bool vfswrap_lock(vfs_handle_struct
*handle
, files_struct
*fsp
, int op
, off_t offset
, off_t count
, int type
)
2104 START_PROFILE(syscall_fcntl_lock
);
2106 if (fsp
->use_ofd_locks
|| !lp_parm_bool(SNUM(fsp
->conn
),
2108 "force process locks",
2110 op
= map_process_lock_to_ofd_lock(op
, &fsp
->use_ofd_locks
);
2113 result
= fcntl_lock(fsp
->fh
->fd
, op
, offset
, count
, type
);
2114 END_PROFILE(syscall_fcntl_lock
);
2118 static int vfswrap_kernel_flock(vfs_handle_struct
*handle
, files_struct
*fsp
,
2119 uint32_t share_mode
, uint32_t access_mask
)
2121 START_PROFILE(syscall_kernel_flock
);
2122 kernel_flock(fsp
->fh
->fd
, share_mode
, access_mask
);
2123 END_PROFILE(syscall_kernel_flock
);
2127 static bool vfswrap_getlock(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t
*poffset
, off_t
*pcount
, int *ptype
, pid_t
*ppid
)
2132 START_PROFILE(syscall_fcntl_getlock
);
2134 if (fsp
->use_ofd_locks
|| !lp_parm_bool(SNUM(fsp
->conn
),
2136 "force process locks",
2138 op
= map_process_lock_to_ofd_lock(op
, &fsp
->use_ofd_locks
);
2141 result
= fcntl_getlock(fsp
->fh
->fd
, op
, poffset
, pcount
, ptype
, ppid
);
2142 END_PROFILE(syscall_fcntl_getlock
);
2146 static int vfswrap_linux_setlease(vfs_handle_struct
*handle
, files_struct
*fsp
,
2151 START_PROFILE(syscall_linux_setlease
);
2153 #ifdef HAVE_KERNEL_OPLOCKS_LINUX
2154 result
= linux_setlease(fsp
->fh
->fd
, leasetype
);
2158 END_PROFILE(syscall_linux_setlease
);
2162 static int vfswrap_symlink(vfs_handle_struct
*handle
, const char *oldpath
, const char *newpath
)
2166 START_PROFILE(syscall_symlink
);
2167 result
= symlink(oldpath
, newpath
);
2168 END_PROFILE(syscall_symlink
);
2172 static int vfswrap_readlink(vfs_handle_struct
*handle
, const char *path
, char *buf
, size_t bufsiz
)
2176 START_PROFILE(syscall_readlink
);
2177 result
= readlink(path
, buf
, bufsiz
);
2178 END_PROFILE(syscall_readlink
);
2182 static int vfswrap_link(vfs_handle_struct
*handle
, const char *oldpath
, const char *newpath
)
2186 START_PROFILE(syscall_link
);
2187 result
= link(oldpath
, newpath
);
2188 END_PROFILE(syscall_link
);
2192 static int vfswrap_mknod(vfs_handle_struct
*handle
, const char *pathname
, mode_t mode
, SMB_DEV_T dev
)
2196 START_PROFILE(syscall_mknod
);
2197 result
= sys_mknod(pathname
, mode
, dev
);
2198 END_PROFILE(syscall_mknod
);
2202 static char *vfswrap_realpath(vfs_handle_struct
*handle
, const char *path
)
2206 START_PROFILE(syscall_realpath
);
2207 result
= sys_realpath(path
);
2208 END_PROFILE(syscall_realpath
);
2212 static int vfswrap_chflags(vfs_handle_struct
*handle
, const char *path
,
2216 return chflags(path
, flags
);
2223 static struct file_id
vfswrap_file_id_create(struct vfs_handle_struct
*handle
,
2224 const SMB_STRUCT_STAT
*sbuf
)
2228 /* the ZERO_STRUCT ensures padding doesn't break using the key as a
2232 key
.devid
= sbuf
->st_ex_dev
;
2233 key
.inode
= sbuf
->st_ex_ino
;
2234 /* key.extid is unused by default. */
2239 static NTSTATUS
vfswrap_streaminfo(vfs_handle_struct
*handle
,
2240 struct files_struct
*fsp
,
2241 const struct smb_filename
*smb_fname
,
2242 TALLOC_CTX
*mem_ctx
,
2243 unsigned int *pnum_streams
,
2244 struct stream_struct
**pstreams
)
2246 SMB_STRUCT_STAT sbuf
;
2247 struct stream_struct
*tmp_streams
= NULL
;
2250 if ((fsp
!= NULL
) && (fsp
->is_directory
)) {
2252 * No default streams on directories
2257 if ((fsp
!= NULL
) && (fsp
->fh
->fd
!= -1)) {
2258 ret
= SMB_VFS_FSTAT(fsp
, &sbuf
);
2261 struct smb_filename smb_fname_cp
;
2263 ZERO_STRUCT(smb_fname_cp
);
2264 smb_fname_cp
.base_name
= discard_const_p(char,
2265 smb_fname
->base_name
);
2266 smb_fname_cp
.flags
= smb_fname
->flags
;
2268 if (smb_fname_cp
.flags
& SMB_FILENAME_POSIX_PATH
) {
2269 ret
= SMB_VFS_LSTAT(handle
->conn
, &smb_fname_cp
);
2271 ret
= SMB_VFS_STAT(handle
->conn
, &smb_fname_cp
);
2273 sbuf
= smb_fname_cp
.st
;
2277 return map_nt_error_from_unix(errno
);
2280 if (S_ISDIR(sbuf
.st_ex_mode
)) {
2284 tmp_streams
= talloc_realloc(mem_ctx
, *pstreams
, struct stream_struct
,
2285 (*pnum_streams
) + 1);
2286 if (tmp_streams
== NULL
) {
2287 return NT_STATUS_NO_MEMORY
;
2289 tmp_streams
[*pnum_streams
].name
= talloc_strdup(tmp_streams
, "::$DATA");
2290 if (tmp_streams
[*pnum_streams
].name
== NULL
) {
2291 return NT_STATUS_NO_MEMORY
;
2293 tmp_streams
[*pnum_streams
].size
= sbuf
.st_ex_size
;
2294 tmp_streams
[*pnum_streams
].alloc_size
= SMB_VFS_GET_ALLOC_SIZE(handle
->conn
, fsp
, &sbuf
);
2297 *pstreams
= tmp_streams
;
2299 return NT_STATUS_OK
;
2302 static int vfswrap_get_real_filename(struct vfs_handle_struct
*handle
,
2305 TALLOC_CTX
*mem_ctx
,
2309 * Don't fall back to get_real_filename so callers can differentiate
2310 * between a full directory scan and an actual case-insensitive stat.
2316 static const char *vfswrap_connectpath(struct vfs_handle_struct
*handle
,
2319 return handle
->conn
->connectpath
;
2322 static NTSTATUS
vfswrap_brl_lock_windows(struct vfs_handle_struct
*handle
,
2323 struct byte_range_lock
*br_lck
,
2324 struct lock_struct
*plock
,
2327 SMB_ASSERT(plock
->lock_flav
== WINDOWS_LOCK
);
2329 /* Note: blr is not used in the default implementation. */
2330 return brl_lock_windows_default(br_lck
, plock
, blocking_lock
);
2333 static bool vfswrap_brl_unlock_windows(struct vfs_handle_struct
*handle
,
2334 struct messaging_context
*msg_ctx
,
2335 struct byte_range_lock
*br_lck
,
2336 const struct lock_struct
*plock
)
2338 SMB_ASSERT(plock
->lock_flav
== WINDOWS_LOCK
);
2340 return brl_unlock_windows_default(msg_ctx
, br_lck
, plock
);
2343 static bool vfswrap_brl_cancel_windows(struct vfs_handle_struct
*handle
,
2344 struct byte_range_lock
*br_lck
,
2345 struct lock_struct
*plock
)
2347 SMB_ASSERT(plock
->lock_flav
== WINDOWS_LOCK
);
2349 /* Note: blr is not used in the default implementation. */
2350 return brl_lock_cancel_default(br_lck
, plock
);
2353 static bool vfswrap_strict_lock(struct vfs_handle_struct
*handle
,
2355 struct lock_struct
*plock
)
2357 SMB_ASSERT(plock
->lock_type
== READ_LOCK
||
2358 plock
->lock_type
== WRITE_LOCK
);
2360 return strict_lock_default(fsp
, plock
);
2363 static void vfswrap_strict_unlock(struct vfs_handle_struct
*handle
,
2365 struct lock_struct
*plock
)
2367 SMB_ASSERT(plock
->lock_type
== READ_LOCK
||
2368 plock
->lock_type
== WRITE_LOCK
);
2370 strict_unlock_default(fsp
, plock
);
2373 /* NT ACL operations. */
2375 static NTSTATUS
vfswrap_fget_nt_acl(vfs_handle_struct
*handle
,
2377 uint32_t security_info
,
2378 TALLOC_CTX
*mem_ctx
,
2379 struct security_descriptor
**ppdesc
)
2383 START_PROFILE(fget_nt_acl
);
2384 result
= posix_fget_nt_acl(fsp
, security_info
,
2386 END_PROFILE(fget_nt_acl
);
2390 static NTSTATUS
vfswrap_get_nt_acl(vfs_handle_struct
*handle
,
2391 const struct smb_filename
*smb_fname
,
2392 uint32_t security_info
,
2393 TALLOC_CTX
*mem_ctx
,
2394 struct security_descriptor
**ppdesc
)
2398 START_PROFILE(get_nt_acl
);
2399 result
= posix_get_nt_acl(handle
->conn
,
2404 END_PROFILE(get_nt_acl
);
2408 static NTSTATUS
vfswrap_fset_nt_acl(vfs_handle_struct
*handle
, files_struct
*fsp
, uint32_t security_info_sent
, const struct security_descriptor
*psd
)
2412 START_PROFILE(fset_nt_acl
);
2413 result
= set_nt_acl(fsp
, security_info_sent
, psd
);
2414 END_PROFILE(fset_nt_acl
);
2418 static NTSTATUS
vfswrap_audit_file(struct vfs_handle_struct
*handle
,
2419 struct smb_filename
*file
,
2420 struct security_acl
*sacl
,
2421 uint32_t access_requested
,
2422 uint32_t access_denied
)
2424 return NT_STATUS_OK
; /* Nothing to do here ... */
2427 static int vfswrap_chmod_acl(vfs_handle_struct
*handle
,
2428 const struct smb_filename
*smb_fname
,
2437 START_PROFILE(chmod_acl
);
2438 result
= chmod_acl(handle
->conn
, smb_fname
->base_name
, mode
);
2439 END_PROFILE(chmod_acl
);
2444 static int vfswrap_fchmod_acl(vfs_handle_struct
*handle
, files_struct
*fsp
, mode_t mode
)
2452 START_PROFILE(fchmod_acl
);
2453 result
= fchmod_acl(fsp
, mode
);
2454 END_PROFILE(fchmod_acl
);
2459 static SMB_ACL_T
vfswrap_sys_acl_get_file(vfs_handle_struct
*handle
,
2461 SMB_ACL_TYPE_T type
,
2462 TALLOC_CTX
*mem_ctx
)
2464 return sys_acl_get_file(handle
, path_p
, type
, mem_ctx
);
2467 static SMB_ACL_T
vfswrap_sys_acl_get_fd(vfs_handle_struct
*handle
,
2469 TALLOC_CTX
*mem_ctx
)
2471 return sys_acl_get_fd(handle
, fsp
, mem_ctx
);
2474 static int vfswrap_sys_acl_set_file(vfs_handle_struct
*handle
, const char *name
, SMB_ACL_TYPE_T acltype
, SMB_ACL_T theacl
)
2476 return sys_acl_set_file(handle
, name
, acltype
, theacl
);
2479 static int vfswrap_sys_acl_set_fd(vfs_handle_struct
*handle
, files_struct
*fsp
, SMB_ACL_T theacl
)
2481 return sys_acl_set_fd(handle
, fsp
, theacl
);
2484 static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct
*handle
, const char *path
)
2486 return sys_acl_delete_def_file(handle
, path
);
2489 /****************************************************************
2490 Extended attribute operations.
2491 *****************************************************************/
2493 static ssize_t
vfswrap_getxattr(struct vfs_handle_struct
*handle
,const char *path
, const char *name
, void *value
, size_t size
)
2495 return getxattr(path
, name
, value
, size
);
2498 static ssize_t
vfswrap_fgetxattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, const char *name
, void *value
, size_t size
)
2500 return fgetxattr(fsp
->fh
->fd
, name
, value
, size
);
2503 static ssize_t
vfswrap_listxattr(struct vfs_handle_struct
*handle
, const char *path
, char *list
, size_t size
)
2505 return listxattr(path
, list
, size
);
2508 static ssize_t
vfswrap_flistxattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, char *list
, size_t size
)
2510 return flistxattr(fsp
->fh
->fd
, list
, size
);
2513 static int vfswrap_removexattr(struct vfs_handle_struct
*handle
, const char *path
, const char *name
)
2515 return removexattr(path
, name
);
2518 static int vfswrap_fremovexattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, const char *name
)
2520 return fremovexattr(fsp
->fh
->fd
, name
);
2523 static int vfswrap_setxattr(struct vfs_handle_struct
*handle
, const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
2525 return setxattr(path
, name
, value
, size
, flags
);
2528 static int vfswrap_fsetxattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, const char *name
, const void *value
, size_t size
, int flags
)
2530 return fsetxattr(fsp
->fh
->fd
, name
, value
, size
, flags
);
2533 static bool vfswrap_aio_force(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
)
2538 static bool vfswrap_is_offline(struct vfs_handle_struct
*handle
,
2539 const struct smb_filename
*fname
,
2540 SMB_STRUCT_STAT
*sbuf
)
2544 bool offline
= false;
2546 if (ISDOT(fname
->base_name
) || ISDOTDOT(fname
->base_name
)) {
2550 if (!lp_dmapi_support(SNUM(handle
->conn
)) || !dmapi_have_session()) {
2551 #if defined(ENOTSUP)
2557 status
= get_full_smb_filename(talloc_tos(), fname
, &path
);
2558 if (!NT_STATUS_IS_OK(status
)) {
2559 errno
= map_errno_from_nt_status(status
);
2563 offline
= (dmapi_file_flags(path
) & FILE_ATTRIBUTE_OFFLINE
) != 0;
2570 static int vfswrap_set_offline(struct vfs_handle_struct
*handle
,
2571 const struct smb_filename
*fname
)
2573 /* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */
2574 #if defined(ENOTSUP)
2580 static NTSTATUS
vfswrap_durable_cookie(struct vfs_handle_struct
*handle
,
2581 struct files_struct
*fsp
,
2582 TALLOC_CTX
*mem_ctx
,
2585 return vfs_default_durable_cookie(fsp
, mem_ctx
, cookie
);
2588 static NTSTATUS
vfswrap_durable_disconnect(struct vfs_handle_struct
*handle
,
2589 struct files_struct
*fsp
,
2590 const DATA_BLOB old_cookie
,
2591 TALLOC_CTX
*mem_ctx
,
2592 DATA_BLOB
*new_cookie
)
2594 return vfs_default_durable_disconnect(fsp
, old_cookie
, mem_ctx
,
2598 static NTSTATUS
vfswrap_durable_reconnect(struct vfs_handle_struct
*handle
,
2599 struct smb_request
*smb1req
,
2600 struct smbXsrv_open
*op
,
2601 const DATA_BLOB old_cookie
,
2602 TALLOC_CTX
*mem_ctx
,
2603 struct files_struct
**fsp
,
2604 DATA_BLOB
*new_cookie
)
2606 return vfs_default_durable_reconnect(handle
->conn
, smb1req
, op
,
2607 old_cookie
, mem_ctx
,
2611 static struct vfs_fn_pointers vfs_default_fns
= {
2612 /* Disk operations */
2614 .connect_fn
= vfswrap_connect
,
2615 .disconnect_fn
= vfswrap_disconnect
,
2616 .disk_free_fn
= vfswrap_disk_free
,
2617 .get_quota_fn
= vfswrap_get_quota
,
2618 .set_quota_fn
= vfswrap_set_quota
,
2619 .get_shadow_copy_data_fn
= vfswrap_get_shadow_copy_data
,
2620 .statvfs_fn
= vfswrap_statvfs
,
2621 .fs_capabilities_fn
= vfswrap_fs_capabilities
,
2622 .get_dfs_referrals_fn
= vfswrap_get_dfs_referrals
,
2623 .snap_check_path_fn
= vfswrap_snap_check_path
,
2624 .snap_create_fn
= vfswrap_snap_create
,
2625 .snap_delete_fn
= vfswrap_snap_delete
,
2627 /* Directory operations */
2629 .opendir_fn
= vfswrap_opendir
,
2630 .fdopendir_fn
= vfswrap_fdopendir
,
2631 .readdir_fn
= vfswrap_readdir
,
2632 .readdir_attr_fn
= vfswrap_readdir_attr
,
2633 .seekdir_fn
= vfswrap_seekdir
,
2634 .telldir_fn
= vfswrap_telldir
,
2635 .rewind_dir_fn
= vfswrap_rewinddir
,
2636 .mkdir_fn
= vfswrap_mkdir
,
2637 .rmdir_fn
= vfswrap_rmdir
,
2638 .closedir_fn
= vfswrap_closedir
,
2639 .init_search_op_fn
= vfswrap_init_search_op
,
2641 /* File operations */
2643 .open_fn
= vfswrap_open
,
2644 .create_file_fn
= vfswrap_create_file
,
2645 .close_fn
= vfswrap_close
,
2646 .read_fn
= vfswrap_read
,
2647 .pread_fn
= vfswrap_pread
,
2648 .pread_send_fn
= vfswrap_pread_send
,
2649 .pread_recv_fn
= vfswrap_asys_ssize_t_recv
,
2650 .write_fn
= vfswrap_write
,
2651 .pwrite_fn
= vfswrap_pwrite
,
2652 .pwrite_send_fn
= vfswrap_pwrite_send
,
2653 .pwrite_recv_fn
= vfswrap_asys_ssize_t_recv
,
2654 .lseek_fn
= vfswrap_lseek
,
2655 .sendfile_fn
= vfswrap_sendfile
,
2656 .recvfile_fn
= vfswrap_recvfile
,
2657 .rename_fn
= vfswrap_rename
,
2658 .fsync_fn
= vfswrap_fsync
,
2659 .fsync_send_fn
= vfswrap_fsync_send
,
2660 .fsync_recv_fn
= vfswrap_asys_int_recv
,
2661 .stat_fn
= vfswrap_stat
,
2662 .fstat_fn
= vfswrap_fstat
,
2663 .lstat_fn
= vfswrap_lstat
,
2664 .get_alloc_size_fn
= vfswrap_get_alloc_size
,
2665 .unlink_fn
= vfswrap_unlink
,
2666 .chmod_fn
= vfswrap_chmod
,
2667 .fchmod_fn
= vfswrap_fchmod
,
2668 .chown_fn
= vfswrap_chown
,
2669 .fchown_fn
= vfswrap_fchown
,
2670 .lchown_fn
= vfswrap_lchown
,
2671 .chdir_fn
= vfswrap_chdir
,
2672 .getwd_fn
= vfswrap_getwd
,
2673 .ntimes_fn
= vfswrap_ntimes
,
2674 .ftruncate_fn
= vfswrap_ftruncate
,
2675 .fallocate_fn
= vfswrap_fallocate
,
2676 .lock_fn
= vfswrap_lock
,
2677 .kernel_flock_fn
= vfswrap_kernel_flock
,
2678 .linux_setlease_fn
= vfswrap_linux_setlease
,
2679 .getlock_fn
= vfswrap_getlock
,
2680 .symlink_fn
= vfswrap_symlink
,
2681 .readlink_fn
= vfswrap_readlink
,
2682 .link_fn
= vfswrap_link
,
2683 .mknod_fn
= vfswrap_mknod
,
2684 .realpath_fn
= vfswrap_realpath
,
2685 .chflags_fn
= vfswrap_chflags
,
2686 .file_id_create_fn
= vfswrap_file_id_create
,
2687 .streaminfo_fn
= vfswrap_streaminfo
,
2688 .get_real_filename_fn
= vfswrap_get_real_filename
,
2689 .connectpath_fn
= vfswrap_connectpath
,
2690 .brl_lock_windows_fn
= vfswrap_brl_lock_windows
,
2691 .brl_unlock_windows_fn
= vfswrap_brl_unlock_windows
,
2692 .brl_cancel_windows_fn
= vfswrap_brl_cancel_windows
,
2693 .strict_lock_fn
= vfswrap_strict_lock
,
2694 .strict_unlock_fn
= vfswrap_strict_unlock
,
2695 .translate_name_fn
= vfswrap_translate_name
,
2696 .fsctl_fn
= vfswrap_fsctl
,
2697 .set_dos_attributes_fn
= vfswrap_set_dos_attributes
,
2698 .fset_dos_attributes_fn
= vfswrap_fset_dos_attributes
,
2699 .get_dos_attributes_fn
= vfswrap_get_dos_attributes
,
2700 .fget_dos_attributes_fn
= vfswrap_fget_dos_attributes
,
2701 .copy_chunk_send_fn
= vfswrap_copy_chunk_send
,
2702 .copy_chunk_recv_fn
= vfswrap_copy_chunk_recv
,
2703 .get_compression_fn
= vfswrap_get_compression
,
2704 .set_compression_fn
= vfswrap_set_compression
,
2706 /* NT ACL operations. */
2708 .fget_nt_acl_fn
= vfswrap_fget_nt_acl
,
2709 .get_nt_acl_fn
= vfswrap_get_nt_acl
,
2710 .fset_nt_acl_fn
= vfswrap_fset_nt_acl
,
2711 .audit_file_fn
= vfswrap_audit_file
,
2713 /* POSIX ACL operations. */
2715 .chmod_acl_fn
= vfswrap_chmod_acl
,
2716 .fchmod_acl_fn
= vfswrap_fchmod_acl
,
2718 .sys_acl_get_file_fn
= vfswrap_sys_acl_get_file
,
2719 .sys_acl_get_fd_fn
= vfswrap_sys_acl_get_fd
,
2720 .sys_acl_blob_get_file_fn
= posix_sys_acl_blob_get_file
,
2721 .sys_acl_blob_get_fd_fn
= posix_sys_acl_blob_get_fd
,
2722 .sys_acl_set_file_fn
= vfswrap_sys_acl_set_file
,
2723 .sys_acl_set_fd_fn
= vfswrap_sys_acl_set_fd
,
2724 .sys_acl_delete_def_file_fn
= vfswrap_sys_acl_delete_def_file
,
2726 /* EA operations. */
2727 .getxattr_fn
= vfswrap_getxattr
,
2728 .fgetxattr_fn
= vfswrap_fgetxattr
,
2729 .listxattr_fn
= vfswrap_listxattr
,
2730 .flistxattr_fn
= vfswrap_flistxattr
,
2731 .removexattr_fn
= vfswrap_removexattr
,
2732 .fremovexattr_fn
= vfswrap_fremovexattr
,
2733 .setxattr_fn
= vfswrap_setxattr
,
2734 .fsetxattr_fn
= vfswrap_fsetxattr
,
2736 /* aio operations */
2737 .aio_force_fn
= vfswrap_aio_force
,
2739 /* offline operations */
2740 .is_offline_fn
= vfswrap_is_offline
,
2741 .set_offline_fn
= vfswrap_set_offline
,
2743 /* durable handle operations */
2744 .durable_cookie_fn
= vfswrap_durable_cookie
,
2745 .durable_disconnect_fn
= vfswrap_durable_disconnect
,
2746 .durable_reconnect_fn
= vfswrap_durable_reconnect
,
2749 NTSTATUS
vfs_default_init(void);
2750 NTSTATUS
vfs_default_init(void)
2752 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION
,
2753 DEFAULT_VFS_MODULE_NAME
, &vfs_default_fns
);