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 tevent_req
*req
;
797 struct vfswrap_asys_state
*state
;
803 if ((flags
& TEVENT_FD_READ
) == 0) {
808 res
= asys_result(asys_ctx
, &ret
, &err
, &private_data
);
809 if (res
== EINTR
|| res
== EAGAIN
) {
813 if (res
== EWOULDBLOCK
) {
818 if (res
== ECANCELED
) {
823 DEBUG(1, ("asys_result returned %s\n", strerror(res
)));
827 req
= talloc_get_type_abort(private_data
, struct tevent_req
);
828 state
= tevent_req_data(req
, struct vfswrap_asys_state
);
830 talloc_set_destructor(state
, NULL
);
834 tevent_req_defer_callback(req
, ev
);
835 tevent_req_done(req
);
839 static ssize_t
vfswrap_asys_ssize_t_recv(struct tevent_req
*req
, int *err
)
841 struct vfswrap_asys_state
*state
= tevent_req_data(
842 req
, struct vfswrap_asys_state
);
844 if (tevent_req_is_unix_error(req
, err
)) {
851 static int vfswrap_asys_int_recv(struct tevent_req
*req
, int *err
)
853 struct vfswrap_asys_state
*state
= tevent_req_data(
854 req
, struct vfswrap_asys_state
);
856 if (tevent_req_is_unix_error(req
, err
)) {
863 static off_t
vfswrap_lseek(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t offset
, int whence
)
867 START_PROFILE(syscall_lseek
);
869 /* Cope with 'stat' file opens. */
870 if (fsp
->fh
->fd
!= -1)
871 result
= lseek(fsp
->fh
->fd
, offset
, whence
);
874 * We want to maintain the fiction that we can seek
875 * on a fifo for file system purposes. This allows
876 * people to set up UNIX fifo's that feed data to Windows
880 if((result
== -1) && (errno
== ESPIPE
)) {
885 END_PROFILE(syscall_lseek
);
889 static ssize_t
vfswrap_sendfile(vfs_handle_struct
*handle
, int tofd
, files_struct
*fromfsp
, const DATA_BLOB
*hdr
,
890 off_t offset
, size_t n
)
894 START_PROFILE_BYTES(syscall_sendfile
, n
);
895 result
= sys_sendfile(tofd
, fromfsp
->fh
->fd
, hdr
, offset
, n
);
896 END_PROFILE(syscall_sendfile
);
900 static ssize_t
vfswrap_recvfile(vfs_handle_struct
*handle
,
908 START_PROFILE_BYTES(syscall_recvfile
, n
);
909 result
= sys_recvfile(fromfd
, tofsp
->fh
->fd
, offset
, n
);
910 END_PROFILE(syscall_recvfile
);
914 static int vfswrap_rename(vfs_handle_struct
*handle
,
915 const struct smb_filename
*smb_fname_src
,
916 const struct smb_filename
*smb_fname_dst
)
920 START_PROFILE(syscall_rename
);
922 if (smb_fname_src
->stream_name
|| smb_fname_dst
->stream_name
) {
927 result
= rename(smb_fname_src
->base_name
, smb_fname_dst
->base_name
);
930 END_PROFILE(syscall_rename
);
934 static int vfswrap_fsync(vfs_handle_struct
*handle
, files_struct
*fsp
)
939 START_PROFILE(syscall_fsync
);
940 result
= fsync(fsp
->fh
->fd
);
941 END_PROFILE(syscall_fsync
);
948 static int vfswrap_stat(vfs_handle_struct
*handle
,
949 struct smb_filename
*smb_fname
)
953 START_PROFILE(syscall_stat
);
955 if (smb_fname
->stream_name
) {
960 result
= sys_stat(smb_fname
->base_name
, &smb_fname
->st
,
961 lp_fake_directory_create_times(SNUM(handle
->conn
)));
963 END_PROFILE(syscall_stat
);
967 static int vfswrap_fstat(vfs_handle_struct
*handle
, files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
971 START_PROFILE(syscall_fstat
);
972 result
= sys_fstat(fsp
->fh
->fd
,
973 sbuf
, lp_fake_directory_create_times(SNUM(handle
->conn
)));
974 END_PROFILE(syscall_fstat
);
978 static int vfswrap_lstat(vfs_handle_struct
*handle
,
979 struct smb_filename
*smb_fname
)
983 START_PROFILE(syscall_lstat
);
985 if (smb_fname
->stream_name
) {
990 result
= sys_lstat(smb_fname
->base_name
, &smb_fname
->st
,
991 lp_fake_directory_create_times(SNUM(handle
->conn
)));
993 END_PROFILE(syscall_lstat
);
997 static NTSTATUS
vfswrap_translate_name(struct vfs_handle_struct
*handle
,
999 enum vfs_translate_direction direction
,
1000 TALLOC_CTX
*mem_ctx
,
1003 return NT_STATUS_NONE_MAPPED
;
1007 * Implement the default fsctl operation.
1009 static bool vfswrap_logged_ioctl_message
= false;
1011 static NTSTATUS
vfswrap_fsctl(struct vfs_handle_struct
*handle
,
1012 struct files_struct
*fsp
,
1015 uint16_t req_flags
, /* Needed for UNICODE ... */
1016 const uint8_t *_in_data
,
1018 uint8_t **_out_data
,
1019 uint32_t max_out_len
,
1022 const char *in_data
= (const char *)_in_data
;
1023 char **out_data
= (char **)_out_data
;
1027 case FSCTL_SET_SPARSE
:
1029 bool set_sparse
= true;
1031 if (in_len
>= 1 && in_data
[0] == 0) {
1035 status
= file_set_sparse(handle
->conn
, fsp
, set_sparse
);
1037 DEBUG(NT_STATUS_IS_OK(status
) ? 10 : 9,
1038 ("FSCTL_SET_SPARSE: fname[%s] set[%u] - %s\n",
1039 smb_fname_str_dbg(fsp
->fsp_name
), set_sparse
,
1040 nt_errstr(status
)));
1045 case FSCTL_CREATE_OR_GET_OBJECT_ID
:
1047 unsigned char objid
[16];
1048 char *return_data
= NULL
;
1050 /* This should return the object-id on this file.
1051 * I think I'll make this be the inode+dev. JRA.
1054 DEBUG(10,("FSCTL_CREATE_OR_GET_OBJECT_ID: called on %s\n",
1055 fsp_fnum_dbg(fsp
)));
1057 *out_len
= MIN(max_out_len
, 64);
1059 /* Hmmm, will this cause problems if less data asked for? */
1060 return_data
= talloc_array(ctx
, char, 64);
1061 if (return_data
== NULL
) {
1062 return NT_STATUS_NO_MEMORY
;
1065 /* For backwards compatibility only store the dev/inode. */
1066 push_file_id_16(return_data
, &fsp
->file_id
);
1067 memcpy(return_data
+16,create_volume_objectid(fsp
->conn
,objid
),16);
1068 push_file_id_16(return_data
+32, &fsp
->file_id
);
1069 memset(return_data
+48, 0, 16);
1070 *out_data
= return_data
;
1071 return NT_STATUS_OK
;
1074 case FSCTL_GET_REPARSE_POINT
:
1076 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
1077 DEBUG(10, ("FSCTL_GET_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_SET_REPARSE_POINT
:
1084 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
1085 DEBUG(10, ("FSCTL_SET_REPARSE_POINT: called on %s. "
1086 "Status: NOT_IMPLEMENTED\n", fsp_fnum_dbg(fsp
)));
1087 return NT_STATUS_NOT_A_REPARSE_POINT
;
1090 case FSCTL_GET_SHADOW_COPY_DATA
:
1093 * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
1094 * and return their volume names. If max_data_count is 16, then it is just
1095 * asking for the number of volumes and length of the combined names.
1097 * pdata is the data allocated by our caller, but that uses
1098 * total_data_count (which is 0 in our case) rather than max_data_count.
1099 * Allocate the correct amount and return the pointer to let
1100 * it be deallocated when we return.
1102 struct shadow_copy_data
*shadow_data
= NULL
;
1103 bool labels
= False
;
1104 uint32 labels_data_count
= 0;
1106 char *cur_pdata
= NULL
;
1108 if (max_out_len
< 16) {
1109 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
1111 return NT_STATUS_INVALID_PARAMETER
;
1114 if (max_out_len
> 16) {
1118 shadow_data
= talloc_zero(ctx
, struct shadow_copy_data
);
1119 if (shadow_data
== NULL
) {
1120 DEBUG(0,("TALLOC_ZERO() failed!\n"));
1121 return NT_STATUS_NO_MEMORY
;
1125 * Call the VFS routine to actually do the work.
1127 if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp
, shadow_data
, labels
)!=0) {
1130 /* broken module didn't set errno on error */
1131 status
= NT_STATUS_UNSUCCESSFUL
;
1133 status
= map_nt_error_from_unix(errno
);
1134 if (NT_STATUS_EQUAL(status
,
1135 NT_STATUS_NOT_SUPPORTED
)) {
1139 DEBUG(log_lev
, ("FSCTL_GET_SHADOW_COPY_DATA: "
1140 "connectpath %s, failed - %s.\n",
1141 fsp
->conn
->connectpath
,
1142 nt_errstr(status
)));
1143 TALLOC_FREE(shadow_data
);
1147 labels_data_count
= (shadow_data
->num_volumes
* 2 *
1148 sizeof(SHADOW_COPY_LABEL
)) + 2;
1153 *out_len
= 12 + labels_data_count
;
1156 if (max_out_len
< *out_len
) {
1157 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
1158 max_out_len
, *out_len
));
1159 TALLOC_FREE(shadow_data
);
1160 return NT_STATUS_BUFFER_TOO_SMALL
;
1163 cur_pdata
= talloc_zero_array(ctx
, char, *out_len
);
1164 if (cur_pdata
== NULL
) {
1165 TALLOC_FREE(shadow_data
);
1166 return NT_STATUS_NO_MEMORY
;
1169 *out_data
= cur_pdata
;
1171 /* num_volumes 4 bytes */
1172 SIVAL(cur_pdata
, 0, shadow_data
->num_volumes
);
1175 /* num_labels 4 bytes */
1176 SIVAL(cur_pdata
, 4, shadow_data
->num_volumes
);
1179 /* needed_data_count 4 bytes */
1180 SIVAL(cur_pdata
, 8, labels_data_count
);
1184 DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
1185 shadow_data
->num_volumes
, fsp_str_dbg(fsp
)));
1186 if (labels
&& shadow_data
->labels
) {
1187 for (i
=0; i
<shadow_data
->num_volumes
; i
++) {
1188 srvstr_push(cur_pdata
, req_flags
,
1189 cur_pdata
, shadow_data
->labels
[i
],
1190 2 * sizeof(SHADOW_COPY_LABEL
),
1191 STR_UNICODE
|STR_TERMINATE
);
1192 cur_pdata
+= 2 * sizeof(SHADOW_COPY_LABEL
);
1193 DEBUGADD(10,("Label[%u]: '%s'\n",i
,shadow_data
->labels
[i
]));
1197 TALLOC_FREE(shadow_data
);
1199 return NT_STATUS_OK
;
1202 case FSCTL_FIND_FILES_BY_SID
:
1204 /* pretend this succeeded -
1206 * we have to send back a list with all files owned by this SID
1208 * but I have to check that --metze
1214 DEBUG(10, ("FSCTL_FIND_FILES_BY_SID: called on %s\n",
1215 fsp_fnum_dbg(fsp
)));
1218 /* NT_STATUS_BUFFER_TOO_SMALL maybe? */
1219 return NT_STATUS_INVALID_PARAMETER
;
1222 sid_len
= MIN(in_len
- 4,SID_MAX_SIZE
);
1224 /* unknown 4 bytes: this is not the length of the sid :-( */
1225 /*unknown = IVAL(pdata,0);*/
1227 if (!sid_parse(in_data
+ 4, sid_len
, &sid
)) {
1228 return NT_STATUS_INVALID_PARAMETER
;
1230 DEBUGADD(10, ("for SID: %s\n", sid_string_dbg(&sid
)));
1232 if (!sid_to_uid(&sid
, &uid
)) {
1233 DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
1234 sid_string_dbg(&sid
),
1235 (unsigned long)sid_len
));
1239 /* we can take a look at the find source :-)
1241 * find ./ -uid $uid -name '*' is what we need here
1244 * and send 4bytes len and then NULL terminated unicode strings
1247 * but I don't know how to deal with the paged results
1248 * (maybe we can hang the result anywhere in the fsp struct)
1250 * but I don't know how to deal with the paged results
1251 * (maybe we can hang the result anywhere in the fsp struct)
1253 * we don't send all files at once
1254 * and at the next we should *not* start from the beginning,
1255 * so we have to cache the result
1260 /* this works for now... */
1261 return NT_STATUS_OK
;
1264 case FSCTL_QUERY_ALLOCATED_RANGES
:
1266 /* FIXME: This is just a dummy reply, telling that all of the
1267 * file is allocated. MKS cp needs that.
1268 * Adding the real allocated ranges via FIEMAP on Linux
1269 * and SEEK_DATA/SEEK_HOLE on Solaris is needed to make
1270 * this FSCTL correct for sparse files.
1272 uint64_t offset
, length
;
1273 char *out_data_tmp
= NULL
;
1276 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: data_count(%u) != 16 is invalid!\n",
1278 return NT_STATUS_INVALID_PARAMETER
;
1281 if (max_out_len
< 16) {
1282 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: max_out_len (%u) < 16 is invalid!\n",
1284 return NT_STATUS_INVALID_PARAMETER
;
1287 offset
= BVAL(in_data
,0);
1288 length
= BVAL(in_data
,8);
1290 if (offset
+ length
< offset
) {
1291 /* No 64-bit integer wrap. */
1292 return NT_STATUS_INVALID_PARAMETER
;
1295 /* Shouldn't this be SMB_VFS_STAT ... ? */
1296 status
= vfs_stat_fsp(fsp
);
1297 if (!NT_STATUS_IS_OK(status
)) {
1302 out_data_tmp
= talloc_array(ctx
, char, *out_len
);
1303 if (out_data_tmp
== NULL
) {
1304 DEBUG(10, ("unable to allocate memory for response\n"));
1305 return NT_STATUS_NO_MEMORY
;
1308 if (offset
> fsp
->fsp_name
->st
.st_ex_size
||
1309 fsp
->fsp_name
->st
.st_ex_size
== 0 ||
1311 memset(out_data_tmp
, 0, *out_len
);
1313 uint64_t end
= offset
+ length
;
1314 end
= MIN(end
, fsp
->fsp_name
->st
.st_ex_size
);
1315 SBVAL(out_data_tmp
, 0, 0);
1316 SBVAL(out_data_tmp
, 8, end
);
1319 *out_data
= out_data_tmp
;
1321 return NT_STATUS_OK
;
1324 case FSCTL_IS_VOLUME_DIRTY
:
1326 DEBUG(10,("FSCTL_IS_VOLUME_DIRTY: called on %s "
1327 "(but remotely not supported)\n", fsp_fnum_dbg(fsp
)));
1329 * http://msdn.microsoft.com/en-us/library/cc232128%28PROT.10%29.aspx
1330 * says we have to respond with NT_STATUS_INVALID_PARAMETER
1332 return NT_STATUS_INVALID_PARAMETER
;
1337 * Only print once ... unfortunately there could be lots of
1338 * different FSCTLs that are called.
1340 if (!vfswrap_logged_ioctl_message
) {
1341 vfswrap_logged_ioctl_message
= true;
1342 DEBUG(2, ("%s (0x%x): Currently not implemented.\n",
1343 __func__
, function
));
1347 return NT_STATUS_NOT_SUPPORTED
;
1350 struct vfs_cc_state
{
1355 static struct tevent_req
*vfswrap_copy_chunk_send(struct vfs_handle_struct
*handle
,
1356 TALLOC_CTX
*mem_ctx
,
1357 struct tevent_context
*ev
,
1358 struct files_struct
*src_fsp
,
1360 struct files_struct
*dest_fsp
,
1364 struct tevent_req
*req
;
1365 struct vfs_cc_state
*vfs_cc_state
;
1368 DEBUG(10, ("performing server side copy chunk of length %lu\n",
1369 (unsigned long)num
));
1371 req
= tevent_req_create(mem_ctx
, &vfs_cc_state
, struct vfs_cc_state
);
1376 status
= vfs_stat_fsp(src_fsp
);
1377 if (tevent_req_nterror(req
, status
)) {
1378 return tevent_req_post(req
, ev
);
1381 if (src_fsp
->fsp_name
->st
.st_ex_size
< src_off
+ num
) {
1383 * [MS-SMB2] 3.3.5.15.6 Handling a Server-Side Data Copy Request
1384 * If the SourceOffset or SourceOffset + Length extends beyond
1385 * the end of file, the server SHOULD<240> treat this as a
1386 * STATUS_END_OF_FILE error.
1388 * <240> Section 3.3.5.15.6: Windows servers will return
1389 * STATUS_INVALID_VIEW_SIZE instead of STATUS_END_OF_FILE.
1391 tevent_req_nterror(req
, NT_STATUS_INVALID_VIEW_SIZE
);
1392 return tevent_req_post(req
, ev
);
1395 /* could use 2.6.33+ sendfile here to do this in kernel */
1396 while (vfs_cc_state
->copied
< num
) {
1398 struct lock_struct lck
;
1401 off_t this_num
= MIN(sizeof(vfs_cc_state
->buf
),
1402 num
- vfs_cc_state
->copied
);
1404 init_strict_lock_struct(src_fsp
,
1405 src_fsp
->op
->global
->open_persistent_id
,
1411 if (!SMB_VFS_STRICT_LOCK(src_fsp
->conn
, src_fsp
, &lck
)) {
1412 tevent_req_nterror(req
, NT_STATUS_FILE_LOCK_CONFLICT
);
1413 return tevent_req_post(req
, ev
);
1416 ret
= SMB_VFS_PREAD(src_fsp
, vfs_cc_state
->buf
,
1419 saved_errno
= errno
;
1422 SMB_VFS_STRICT_UNLOCK(src_fsp
->conn
, src_fsp
, &lck
);
1425 errno
= saved_errno
;
1426 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
1427 return tevent_req_post(req
, ev
);
1429 if (ret
!= this_num
) {
1430 /* zero tolerance for short reads */
1431 tevent_req_nterror(req
, NT_STATUS_IO_DEVICE_ERROR
);
1432 return tevent_req_post(req
, ev
);
1437 init_strict_lock_struct(dest_fsp
,
1438 dest_fsp
->op
->global
->open_persistent_id
,
1444 if (!SMB_VFS_STRICT_LOCK(dest_fsp
->conn
, dest_fsp
, &lck
)) {
1445 tevent_req_nterror(req
, NT_STATUS_FILE_LOCK_CONFLICT
);
1446 return tevent_req_post(req
, ev
);
1449 ret
= SMB_VFS_PWRITE(dest_fsp
, vfs_cc_state
->buf
,
1450 this_num
, dest_off
);
1452 saved_errno
= errno
;
1455 SMB_VFS_STRICT_UNLOCK(src_fsp
->conn
, src_fsp
, &lck
);
1458 errno
= saved_errno
;
1459 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
1460 return tevent_req_post(req
, ev
);
1462 if (ret
!= this_num
) {
1463 /* zero tolerance for short writes */
1464 tevent_req_nterror(req
, NT_STATUS_IO_DEVICE_ERROR
);
1465 return tevent_req_post(req
, ev
);
1469 vfs_cc_state
->copied
+= this_num
;
1472 tevent_req_done(req
);
1473 return tevent_req_post(req
, ev
);
1476 static NTSTATUS
vfswrap_copy_chunk_recv(struct vfs_handle_struct
*handle
,
1477 struct tevent_req
*req
,
1480 struct vfs_cc_state
*vfs_cc_state
= tevent_req_data(req
,
1481 struct vfs_cc_state
);
1484 if (tevent_req_is_nterror(req
, &status
)) {
1485 DEBUG(2, ("server side copy chunk failed: %s\n",
1486 nt_errstr(status
)));
1488 tevent_req_received(req
);
1492 *copied
= vfs_cc_state
->copied
;
1493 DEBUG(10, ("server side copy chunk copied %lu\n",
1494 (unsigned long)*copied
));
1495 tevent_req_received(req
);
1497 return NT_STATUS_OK
;
1500 static NTSTATUS
vfswrap_get_compression(struct vfs_handle_struct
*handle
,
1501 TALLOC_CTX
*mem_ctx
,
1502 struct files_struct
*fsp
,
1503 struct smb_filename
*smb_fname
,
1504 uint16_t *_compression_fmt
)
1506 return NT_STATUS_INVALID_DEVICE_REQUEST
;
1509 static NTSTATUS
vfswrap_set_compression(struct vfs_handle_struct
*handle
,
1510 TALLOC_CTX
*mem_ctx
,
1511 struct files_struct
*fsp
,
1512 uint16_t compression_fmt
)
1514 return NT_STATUS_INVALID_DEVICE_REQUEST
;
1517 /********************************************************************
1518 Given a stat buffer return the allocated size on disk, taking into
1519 account sparse files.
1520 ********************************************************************/
1521 static uint64_t vfswrap_get_alloc_size(vfs_handle_struct
*handle
,
1522 struct files_struct
*fsp
,
1523 const SMB_STRUCT_STAT
*sbuf
)
1527 START_PROFILE(syscall_get_alloc_size
);
1529 if(S_ISDIR(sbuf
->st_ex_mode
)) {
1534 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
1535 /* The type of st_blocksize is blkcnt_t which *MUST* be
1536 signed (according to POSIX) and can be less than 64-bits.
1537 Ensure when we're converting to 64 bits wide we don't
1539 #if defined(SIZEOF_BLKCNT_T_8)
1540 result
= (uint64_t)STAT_ST_BLOCKSIZE
* (uint64_t)sbuf
->st_ex_blocks
;
1541 #elif defined(SIZEOF_BLKCNT_T_4)
1543 uint64_t bs
= ((uint64_t)sbuf
->st_ex_blocks
) & 0xFFFFFFFFLL
;
1544 result
= (uint64_t)STAT_ST_BLOCKSIZE
* bs
;
1547 #error SIZEOF_BLKCNT_T_NOT_A_SUPPORTED_VALUE
1550 result
= get_file_size_stat(sbuf
);
1553 if (fsp
&& fsp
->initial_allocation_size
)
1554 result
= MAX(result
,fsp
->initial_allocation_size
);
1556 result
= smb_roundup(handle
->conn
, result
);
1559 END_PROFILE(syscall_get_alloc_size
);
1563 static int vfswrap_unlink(vfs_handle_struct
*handle
,
1564 const struct smb_filename
*smb_fname
)
1568 START_PROFILE(syscall_unlink
);
1570 if (smb_fname
->stream_name
) {
1574 result
= unlink(smb_fname
->base_name
);
1577 END_PROFILE(syscall_unlink
);
1581 static int vfswrap_chmod(vfs_handle_struct
*handle
, const char *path
, mode_t mode
)
1585 START_PROFILE(syscall_chmod
);
1588 * We need to do this due to the fact that the default POSIX ACL
1589 * chmod modifies the ACL *mask* for the group owner, not the
1590 * group owner bits directly. JRA.
1595 int saved_errno
= errno
; /* We might get ENOSYS */
1596 if ((result
= SMB_VFS_CHMOD_ACL(handle
->conn
, path
, mode
)) == 0) {
1597 END_PROFILE(syscall_chmod
);
1600 /* Error - return the old errno. */
1601 errno
= saved_errno
;
1604 result
= chmod(path
, mode
);
1605 END_PROFILE(syscall_chmod
);
1609 static int vfswrap_fchmod(vfs_handle_struct
*handle
, files_struct
*fsp
, mode_t mode
)
1613 START_PROFILE(syscall_fchmod
);
1616 * We need to do this due to the fact that the default POSIX ACL
1617 * chmod modifies the ACL *mask* for the group owner, not the
1618 * group owner bits directly. JRA.
1622 int saved_errno
= errno
; /* We might get ENOSYS */
1623 if ((result
= SMB_VFS_FCHMOD_ACL(fsp
, mode
)) == 0) {
1624 END_PROFILE(syscall_fchmod
);
1627 /* Error - return the old errno. */
1628 errno
= saved_errno
;
1631 #if defined(HAVE_FCHMOD)
1632 result
= fchmod(fsp
->fh
->fd
, mode
);
1638 END_PROFILE(syscall_fchmod
);
1642 static int vfswrap_chown(vfs_handle_struct
*handle
, const char *path
, uid_t uid
, gid_t gid
)
1646 START_PROFILE(syscall_chown
);
1647 result
= chown(path
, uid
, gid
);
1648 END_PROFILE(syscall_chown
);
1652 static int vfswrap_fchown(vfs_handle_struct
*handle
, files_struct
*fsp
, uid_t uid
, gid_t gid
)
1657 START_PROFILE(syscall_fchown
);
1658 result
= fchown(fsp
->fh
->fd
, uid
, gid
);
1659 END_PROFILE(syscall_fchown
);
1667 static int vfswrap_lchown(vfs_handle_struct
*handle
, const char *path
, uid_t uid
, gid_t gid
)
1671 START_PROFILE(syscall_lchown
);
1672 result
= lchown(path
, uid
, gid
);
1673 END_PROFILE(syscall_lchown
);
1677 static int vfswrap_chdir(vfs_handle_struct
*handle
, const char *path
)
1681 START_PROFILE(syscall_chdir
);
1682 result
= chdir(path
);
1683 END_PROFILE(syscall_chdir
);
1687 static char *vfswrap_getwd(vfs_handle_struct
*handle
)
1691 START_PROFILE(syscall_getwd
);
1692 result
= sys_getwd();
1693 END_PROFILE(syscall_getwd
);
1697 /*********************************************************************
1698 nsec timestamp resolution call. Convert down to whatever the underlying
1699 system will support.
1700 **********************************************************************/
1702 static int vfswrap_ntimes(vfs_handle_struct
*handle
,
1703 const struct smb_filename
*smb_fname
,
1704 struct smb_file_time
*ft
)
1708 START_PROFILE(syscall_ntimes
);
1710 if (smb_fname
->stream_name
) {
1716 if (null_timespec(ft
->atime
)) {
1717 ft
->atime
= smb_fname
->st
.st_ex_atime
;
1720 if (null_timespec(ft
->mtime
)) {
1721 ft
->mtime
= smb_fname
->st
.st_ex_mtime
;
1724 if (!null_timespec(ft
->create_time
)) {
1725 set_create_timespec_ea(handle
->conn
,
1730 if ((timespec_compare(&ft
->atime
,
1731 &smb_fname
->st
.st_ex_atime
) == 0) &&
1732 (timespec_compare(&ft
->mtime
,
1733 &smb_fname
->st
.st_ex_mtime
) == 0)) {
1738 #if defined(HAVE_UTIMENSAT)
1740 struct timespec ts
[2];
1743 result
= utimensat(AT_FDCWD
, smb_fname
->base_name
, ts
, 0);
1745 result
= utimensat(AT_FDCWD
, smb_fname
->base_name
, NULL
, 0);
1747 if (!((result
== -1) && (errno
== ENOSYS
))) {
1751 #if defined(HAVE_UTIMES)
1753 struct timeval tv
[2];
1754 tv
[0] = convert_timespec_to_timeval(ft
->atime
);
1755 tv
[1] = convert_timespec_to_timeval(ft
->mtime
);
1756 result
= utimes(smb_fname
->base_name
, tv
);
1758 result
= utimes(smb_fname
->base_name
, NULL
);
1760 if (!((result
== -1) && (errno
== ENOSYS
))) {
1764 #if defined(HAVE_UTIME)
1766 struct utimbuf times
;
1767 times
.actime
= convert_timespec_to_time_t(ft
->atime
);
1768 times
.modtime
= convert_timespec_to_time_t(ft
->mtime
);
1769 result
= utime(smb_fname
->base_name
, ×
);
1771 result
= utime(smb_fname
->base_name
, NULL
);
1773 if (!((result
== -1) && (errno
== ENOSYS
))) {
1781 END_PROFILE(syscall_ntimes
);
1785 /*********************************************************************
1786 A version of ftruncate that will write the space on disk if strict
1788 **********************************************************************/
1790 static int strict_allocate_ftruncate(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t len
)
1792 off_t space_to_write
;
1793 uint64_t space_avail
;
1794 uint64_t bsize
,dfree
,dsize
;
1797 SMB_STRUCT_STAT
*pst
;
1799 status
= vfs_stat_fsp(fsp
);
1800 if (!NT_STATUS_IS_OK(status
)) {
1803 pst
= &fsp
->fsp_name
->st
;
1806 if (S_ISFIFO(pst
->st_ex_mode
))
1810 if (pst
->st_ex_size
== len
)
1813 /* Shrink - just ftruncate. */
1814 if (pst
->st_ex_size
> len
)
1815 return ftruncate(fsp
->fh
->fd
, len
);
1817 space_to_write
= len
- pst
->st_ex_size
;
1819 /* for allocation try fallocate first. This can fail on some
1820 platforms e.g. when the filesystem doesn't support it and no
1821 emulation is being done by the libc (like on AIX with JFS1). In that
1822 case we do our own emulation. fallocate implementations can
1823 return ENOTSUP or EINVAL in cases like that. */
1824 ret
= SMB_VFS_FALLOCATE(fsp
, VFS_FALLOCATE_EXTEND_SIZE
,
1825 pst
->st_ex_size
, space_to_write
);
1826 if (ret
== ENOSPC
) {
1833 DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with "
1834 "error %d. Falling back to slow manual allocation\n", ret
));
1836 /* available disk space is enough or not? */
1837 space_avail
= get_dfree_info(fsp
->conn
,
1838 fsp
->fsp_name
->base_name
, false,
1839 &bsize
,&dfree
,&dsize
);
1840 /* space_avail is 1k blocks */
1841 if (space_avail
== (uint64_t)-1 ||
1842 ((uint64_t)space_to_write
/1024 > space_avail
) ) {
1847 /* Write out the real space on disk. */
1848 ret
= vfs_slow_fallocate(fsp
, pst
->st_ex_size
, space_to_write
);
1857 static int vfswrap_ftruncate(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t len
)
1860 SMB_STRUCT_STAT
*pst
;
1864 START_PROFILE(syscall_ftruncate
);
1866 if (lp_strict_allocate(SNUM(fsp
->conn
)) && !fsp
->is_sparse
) {
1867 result
= strict_allocate_ftruncate(handle
, fsp
, len
);
1868 END_PROFILE(syscall_ftruncate
);
1872 /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
1873 ftruncate if the system supports it. Then I discovered that
1874 you can have some filesystems that support ftruncate
1875 expansion and some that don't! On Linux fat can't do
1876 ftruncate extend but ext2 can. */
1878 result
= ftruncate(fsp
->fh
->fd
, len
);
1882 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
1883 extend a file with ftruncate. Provide alternate implementation
1886 /* Do an fstat to see if the file is longer than the requested
1887 size in which case the ftruncate above should have
1888 succeeded or shorter, in which case seek to len - 1 and
1889 write 1 byte of zero */
1890 status
= vfs_stat_fsp(fsp
);
1891 if (!NT_STATUS_IS_OK(status
)) {
1894 pst
= &fsp
->fsp_name
->st
;
1897 if (S_ISFIFO(pst
->st_ex_mode
)) {
1903 if (pst
->st_ex_size
== len
) {
1908 if (pst
->st_ex_size
> len
) {
1909 /* the ftruncate should have worked */
1913 if (SMB_VFS_PWRITE(fsp
, &c
, 1, len
-1)!=1) {
1921 END_PROFILE(syscall_ftruncate
);
1925 static int vfswrap_fallocate(vfs_handle_struct
*handle
,
1927 enum vfs_fallocate_mode mode
,
1933 START_PROFILE(syscall_fallocate
);
1934 if (mode
== VFS_FALLOCATE_EXTEND_SIZE
) {
1935 result
= sys_posix_fallocate(fsp
->fh
->fd
, offset
, len
);
1936 } else if (mode
== VFS_FALLOCATE_KEEP_SIZE
) {
1937 result
= sys_fallocate(fsp
->fh
->fd
, mode
, offset
, len
);
1942 END_PROFILE(syscall_fallocate
);
1946 static bool vfswrap_lock(vfs_handle_struct
*handle
, files_struct
*fsp
, int op
, off_t offset
, off_t count
, int type
)
1950 START_PROFILE(syscall_fcntl_lock
);
1951 result
= fcntl_lock(fsp
->fh
->fd
, op
, offset
, count
, type
);
1952 END_PROFILE(syscall_fcntl_lock
);
1956 static int vfswrap_kernel_flock(vfs_handle_struct
*handle
, files_struct
*fsp
,
1957 uint32 share_mode
, uint32 access_mask
)
1959 START_PROFILE(syscall_kernel_flock
);
1960 kernel_flock(fsp
->fh
->fd
, share_mode
, access_mask
);
1961 END_PROFILE(syscall_kernel_flock
);
1965 static bool vfswrap_getlock(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t
*poffset
, off_t
*pcount
, int *ptype
, pid_t
*ppid
)
1969 START_PROFILE(syscall_fcntl_getlock
);
1970 result
= fcntl_getlock(fsp
->fh
->fd
, poffset
, pcount
, ptype
, ppid
);
1971 END_PROFILE(syscall_fcntl_getlock
);
1975 static int vfswrap_linux_setlease(vfs_handle_struct
*handle
, files_struct
*fsp
,
1980 START_PROFILE(syscall_linux_setlease
);
1982 #ifdef HAVE_KERNEL_OPLOCKS_LINUX
1983 result
= linux_setlease(fsp
->fh
->fd
, leasetype
);
1987 END_PROFILE(syscall_linux_setlease
);
1991 static int vfswrap_symlink(vfs_handle_struct
*handle
, const char *oldpath
, const char *newpath
)
1995 START_PROFILE(syscall_symlink
);
1996 result
= symlink(oldpath
, newpath
);
1997 END_PROFILE(syscall_symlink
);
2001 static int vfswrap_readlink(vfs_handle_struct
*handle
, const char *path
, char *buf
, size_t bufsiz
)
2005 START_PROFILE(syscall_readlink
);
2006 result
= readlink(path
, buf
, bufsiz
);
2007 END_PROFILE(syscall_readlink
);
2011 static int vfswrap_link(vfs_handle_struct
*handle
, const char *oldpath
, const char *newpath
)
2015 START_PROFILE(syscall_link
);
2016 result
= link(oldpath
, newpath
);
2017 END_PROFILE(syscall_link
);
2021 static int vfswrap_mknod(vfs_handle_struct
*handle
, const char *pathname
, mode_t mode
, SMB_DEV_T dev
)
2025 START_PROFILE(syscall_mknod
);
2026 result
= sys_mknod(pathname
, mode
, dev
);
2027 END_PROFILE(syscall_mknod
);
2031 static char *vfswrap_realpath(vfs_handle_struct
*handle
, const char *path
)
2035 START_PROFILE(syscall_realpath
);
2036 #ifdef REALPATH_TAKES_NULL
2037 result
= realpath(path
, NULL
);
2039 result
= SMB_MALLOC_ARRAY(char, PATH_MAX
+1);
2041 char *resolved_path
= realpath(path
, result
);
2042 if (!resolved_path
) {
2045 /* SMB_ASSERT(result == resolved_path) ? */
2046 result
= resolved_path
;
2050 END_PROFILE(syscall_realpath
);
2054 static NTSTATUS
vfswrap_notify_watch(vfs_handle_struct
*vfs_handle
,
2055 struct sys_notify_context
*ctx
,
2058 uint32_t *subdir_filter
,
2059 void (*callback
)(struct sys_notify_context
*ctx
,
2061 struct notify_event
*ev
),
2062 void *private_data
, void *handle
)
2065 * So far inotify is the only supported default notify mechanism. If
2066 * another platform like the the BSD's or a proprietary Unix comes
2067 * along and wants another default, we can play the same trick we
2068 * played with Posix ACLs.
2070 * Until that is the case, hard-code inotify here.
2073 if (lp_kernel_change_notify(vfs_handle
->conn
->params
)) {
2074 return inotify_watch(ctx
, path
, filter
, subdir_filter
,
2075 callback
, private_data
, handle
);
2079 * Do nothing, leave everything to notify_internal.c
2081 return NT_STATUS_OK
;
2084 static int vfswrap_chflags(vfs_handle_struct
*handle
, const char *path
,
2088 return chflags(path
, flags
);
2095 static struct file_id
vfswrap_file_id_create(struct vfs_handle_struct
*handle
,
2096 const SMB_STRUCT_STAT
*sbuf
)
2100 /* the ZERO_STRUCT ensures padding doesn't break using the key as a
2104 key
.devid
= sbuf
->st_ex_dev
;
2105 key
.inode
= sbuf
->st_ex_ino
;
2106 /* key.extid is unused by default. */
2111 static NTSTATUS
vfswrap_streaminfo(vfs_handle_struct
*handle
,
2112 struct files_struct
*fsp
,
2114 TALLOC_CTX
*mem_ctx
,
2115 unsigned int *pnum_streams
,
2116 struct stream_struct
**pstreams
)
2118 SMB_STRUCT_STAT sbuf
;
2119 struct stream_struct
*tmp_streams
= NULL
;
2122 if ((fsp
!= NULL
) && (fsp
->is_directory
)) {
2124 * No default streams on directories
2129 if ((fsp
!= NULL
) && (fsp
->fh
->fd
!= -1)) {
2130 ret
= SMB_VFS_FSTAT(fsp
, &sbuf
);
2133 struct smb_filename smb_fname
;
2135 ZERO_STRUCT(smb_fname
);
2136 smb_fname
.base_name
= discard_const_p(char, fname
);
2138 if (lp_posix_pathnames()) {
2139 ret
= SMB_VFS_LSTAT(handle
->conn
, &smb_fname
);
2141 ret
= SMB_VFS_STAT(handle
->conn
, &smb_fname
);
2143 sbuf
= smb_fname
.st
;
2147 return map_nt_error_from_unix(errno
);
2150 if (S_ISDIR(sbuf
.st_ex_mode
)) {
2154 tmp_streams
= talloc_realloc(mem_ctx
, *pstreams
, struct stream_struct
,
2155 (*pnum_streams
) + 1);
2156 if (tmp_streams
== NULL
) {
2157 return NT_STATUS_NO_MEMORY
;
2159 tmp_streams
[*pnum_streams
].name
= talloc_strdup(tmp_streams
, "::$DATA");
2160 if (tmp_streams
[*pnum_streams
].name
== NULL
) {
2161 return NT_STATUS_NO_MEMORY
;
2163 tmp_streams
[*pnum_streams
].size
= sbuf
.st_ex_size
;
2164 tmp_streams
[*pnum_streams
].alloc_size
= SMB_VFS_GET_ALLOC_SIZE(handle
->conn
, fsp
, &sbuf
);
2167 *pstreams
= tmp_streams
;
2169 return NT_STATUS_OK
;
2172 static int vfswrap_get_real_filename(struct vfs_handle_struct
*handle
,
2175 TALLOC_CTX
*mem_ctx
,
2179 * Don't fall back to get_real_filename so callers can differentiate
2180 * between a full directory scan and an actual case-insensitive stat.
2186 static const char *vfswrap_connectpath(struct vfs_handle_struct
*handle
,
2189 return handle
->conn
->connectpath
;
2192 static NTSTATUS
vfswrap_brl_lock_windows(struct vfs_handle_struct
*handle
,
2193 struct byte_range_lock
*br_lck
,
2194 struct lock_struct
*plock
,
2196 struct blocking_lock_record
*blr
)
2198 SMB_ASSERT(plock
->lock_flav
== WINDOWS_LOCK
);
2200 /* Note: blr is not used in the default implementation. */
2201 return brl_lock_windows_default(br_lck
, plock
, blocking_lock
);
2204 static bool vfswrap_brl_unlock_windows(struct vfs_handle_struct
*handle
,
2205 struct messaging_context
*msg_ctx
,
2206 struct byte_range_lock
*br_lck
,
2207 const struct lock_struct
*plock
)
2209 SMB_ASSERT(plock
->lock_flav
== WINDOWS_LOCK
);
2211 return brl_unlock_windows_default(msg_ctx
, br_lck
, plock
);
2214 static bool vfswrap_brl_cancel_windows(struct vfs_handle_struct
*handle
,
2215 struct byte_range_lock
*br_lck
,
2216 struct lock_struct
*plock
,
2217 struct blocking_lock_record
*blr
)
2219 SMB_ASSERT(plock
->lock_flav
== WINDOWS_LOCK
);
2221 /* Note: blr is not used in the default implementation. */
2222 return brl_lock_cancel_default(br_lck
, plock
);
2225 static bool vfswrap_strict_lock(struct vfs_handle_struct
*handle
,
2227 struct lock_struct
*plock
)
2229 SMB_ASSERT(plock
->lock_type
== READ_LOCK
||
2230 plock
->lock_type
== WRITE_LOCK
);
2232 return strict_lock_default(fsp
, plock
);
2235 static void vfswrap_strict_unlock(struct vfs_handle_struct
*handle
,
2237 struct lock_struct
*plock
)
2239 SMB_ASSERT(plock
->lock_type
== READ_LOCK
||
2240 plock
->lock_type
== WRITE_LOCK
);
2242 strict_unlock_default(fsp
, plock
);
2245 /* NT ACL operations. */
2247 static NTSTATUS
vfswrap_fget_nt_acl(vfs_handle_struct
*handle
,
2249 uint32 security_info
,
2250 TALLOC_CTX
*mem_ctx
,
2251 struct security_descriptor
**ppdesc
)
2255 START_PROFILE(fget_nt_acl
);
2256 result
= posix_fget_nt_acl(fsp
, security_info
,
2258 END_PROFILE(fget_nt_acl
);
2262 static NTSTATUS
vfswrap_get_nt_acl(vfs_handle_struct
*handle
,
2264 uint32 security_info
,
2265 TALLOC_CTX
*mem_ctx
,
2266 struct security_descriptor
**ppdesc
)
2270 START_PROFILE(get_nt_acl
);
2271 result
= posix_get_nt_acl(handle
->conn
, name
, security_info
,
2273 END_PROFILE(get_nt_acl
);
2277 static NTSTATUS
vfswrap_fset_nt_acl(vfs_handle_struct
*handle
, files_struct
*fsp
, uint32 security_info_sent
, const struct security_descriptor
*psd
)
2281 START_PROFILE(fset_nt_acl
);
2282 result
= set_nt_acl(fsp
, security_info_sent
, psd
);
2283 END_PROFILE(fset_nt_acl
);
2287 static NTSTATUS
vfswrap_audit_file(struct vfs_handle_struct
*handle
,
2288 struct smb_filename
*file
,
2289 struct security_acl
*sacl
,
2290 uint32_t access_requested
,
2291 uint32_t access_denied
)
2293 return NT_STATUS_OK
; /* Nothing to do here ... */
2296 static int vfswrap_chmod_acl(vfs_handle_struct
*handle
, const char *name
, mode_t mode
)
2304 START_PROFILE(chmod_acl
);
2305 result
= chmod_acl(handle
->conn
, name
, mode
);
2306 END_PROFILE(chmod_acl
);
2311 static int vfswrap_fchmod_acl(vfs_handle_struct
*handle
, files_struct
*fsp
, mode_t mode
)
2319 START_PROFILE(fchmod_acl
);
2320 result
= fchmod_acl(fsp
, mode
);
2321 END_PROFILE(fchmod_acl
);
2326 static SMB_ACL_T
vfswrap_sys_acl_get_file(vfs_handle_struct
*handle
,
2328 SMB_ACL_TYPE_T type
,
2329 TALLOC_CTX
*mem_ctx
)
2331 return sys_acl_get_file(handle
, path_p
, type
, mem_ctx
);
2334 static SMB_ACL_T
vfswrap_sys_acl_get_fd(vfs_handle_struct
*handle
,
2336 TALLOC_CTX
*mem_ctx
)
2338 return sys_acl_get_fd(handle
, fsp
, mem_ctx
);
2341 static int vfswrap_sys_acl_set_file(vfs_handle_struct
*handle
, const char *name
, SMB_ACL_TYPE_T acltype
, SMB_ACL_T theacl
)
2343 return sys_acl_set_file(handle
, name
, acltype
, theacl
);
2346 static int vfswrap_sys_acl_set_fd(vfs_handle_struct
*handle
, files_struct
*fsp
, SMB_ACL_T theacl
)
2348 return sys_acl_set_fd(handle
, fsp
, theacl
);
2351 static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct
*handle
, const char *path
)
2353 return sys_acl_delete_def_file(handle
, path
);
2356 /****************************************************************
2357 Extended attribute operations.
2358 *****************************************************************/
2360 static ssize_t
vfswrap_getxattr(struct vfs_handle_struct
*handle
,const char *path
, const char *name
, void *value
, size_t size
)
2362 return getxattr(path
, name
, value
, size
);
2365 static ssize_t
vfswrap_fgetxattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, const char *name
, void *value
, size_t size
)
2367 return fgetxattr(fsp
->fh
->fd
, name
, value
, size
);
2370 static ssize_t
vfswrap_listxattr(struct vfs_handle_struct
*handle
, const char *path
, char *list
, size_t size
)
2372 return listxattr(path
, list
, size
);
2375 static ssize_t
vfswrap_flistxattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, char *list
, size_t size
)
2377 return flistxattr(fsp
->fh
->fd
, list
, size
);
2380 static int vfswrap_removexattr(struct vfs_handle_struct
*handle
, const char *path
, const char *name
)
2382 return removexattr(path
, name
);
2385 static int vfswrap_fremovexattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, const char *name
)
2387 return fremovexattr(fsp
->fh
->fd
, name
);
2390 static int vfswrap_setxattr(struct vfs_handle_struct
*handle
, const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
2392 return setxattr(path
, name
, value
, size
, flags
);
2395 static int vfswrap_fsetxattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, const char *name
, const void *value
, size_t size
, int flags
)
2397 return fsetxattr(fsp
->fh
->fd
, name
, value
, size
, flags
);
2400 static bool vfswrap_aio_force(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
)
2405 static bool vfswrap_is_offline(struct vfs_handle_struct
*handle
,
2406 const struct smb_filename
*fname
,
2407 SMB_STRUCT_STAT
*sbuf
)
2411 bool offline
= false;
2413 if (ISDOT(fname
->base_name
) || ISDOTDOT(fname
->base_name
)) {
2417 if (!lp_dmapi_support(SNUM(handle
->conn
)) || !dmapi_have_session()) {
2418 #if defined(ENOTSUP)
2424 status
= get_full_smb_filename(talloc_tos(), fname
, &path
);
2425 if (!NT_STATUS_IS_OK(status
)) {
2426 errno
= map_errno_from_nt_status(status
);
2430 offline
= (dmapi_file_flags(path
) & FILE_ATTRIBUTE_OFFLINE
) != 0;
2437 static int vfswrap_set_offline(struct vfs_handle_struct
*handle
,
2438 const struct smb_filename
*fname
)
2440 /* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */
2441 #if defined(ENOTSUP)
2447 static NTSTATUS
vfswrap_durable_cookie(struct vfs_handle_struct
*handle
,
2448 struct files_struct
*fsp
,
2449 TALLOC_CTX
*mem_ctx
,
2452 return vfs_default_durable_cookie(fsp
, mem_ctx
, cookie
);
2455 static NTSTATUS
vfswrap_durable_disconnect(struct vfs_handle_struct
*handle
,
2456 struct files_struct
*fsp
,
2457 const DATA_BLOB old_cookie
,
2458 TALLOC_CTX
*mem_ctx
,
2459 DATA_BLOB
*new_cookie
)
2461 return vfs_default_durable_disconnect(fsp
, old_cookie
, mem_ctx
,
2465 static NTSTATUS
vfswrap_durable_reconnect(struct vfs_handle_struct
*handle
,
2466 struct smb_request
*smb1req
,
2467 struct smbXsrv_open
*op
,
2468 const DATA_BLOB old_cookie
,
2469 TALLOC_CTX
*mem_ctx
,
2470 struct files_struct
**fsp
,
2471 DATA_BLOB
*new_cookie
)
2473 return vfs_default_durable_reconnect(handle
->conn
, smb1req
, op
,
2474 old_cookie
, mem_ctx
,
2478 static struct vfs_fn_pointers vfs_default_fns
= {
2479 /* Disk operations */
2481 .connect_fn
= vfswrap_connect
,
2482 .disconnect_fn
= vfswrap_disconnect
,
2483 .disk_free_fn
= vfswrap_disk_free
,
2484 .get_quota_fn
= vfswrap_get_quota
,
2485 .set_quota_fn
= vfswrap_set_quota
,
2486 .get_shadow_copy_data_fn
= vfswrap_get_shadow_copy_data
,
2487 .statvfs_fn
= vfswrap_statvfs
,
2488 .fs_capabilities_fn
= vfswrap_fs_capabilities
,
2489 .get_dfs_referrals_fn
= vfswrap_get_dfs_referrals
,
2491 /* Directory operations */
2493 .opendir_fn
= vfswrap_opendir
,
2494 .fdopendir_fn
= vfswrap_fdopendir
,
2495 .readdir_fn
= vfswrap_readdir
,
2496 .seekdir_fn
= vfswrap_seekdir
,
2497 .telldir_fn
= vfswrap_telldir
,
2498 .rewind_dir_fn
= vfswrap_rewinddir
,
2499 .mkdir_fn
= vfswrap_mkdir
,
2500 .rmdir_fn
= vfswrap_rmdir
,
2501 .closedir_fn
= vfswrap_closedir
,
2502 .init_search_op_fn
= vfswrap_init_search_op
,
2504 /* File operations */
2506 .open_fn
= vfswrap_open
,
2507 .create_file_fn
= vfswrap_create_file
,
2508 .close_fn
= vfswrap_close
,
2509 .read_fn
= vfswrap_read
,
2510 .pread_fn
= vfswrap_pread
,
2511 .pread_send_fn
= vfswrap_pread_send
,
2512 .pread_recv_fn
= vfswrap_asys_ssize_t_recv
,
2513 .write_fn
= vfswrap_write
,
2514 .pwrite_fn
= vfswrap_pwrite
,
2515 .pwrite_send_fn
= vfswrap_pwrite_send
,
2516 .pwrite_recv_fn
= vfswrap_asys_ssize_t_recv
,
2517 .lseek_fn
= vfswrap_lseek
,
2518 .sendfile_fn
= vfswrap_sendfile
,
2519 .recvfile_fn
= vfswrap_recvfile
,
2520 .rename_fn
= vfswrap_rename
,
2521 .fsync_fn
= vfswrap_fsync
,
2522 .fsync_send_fn
= vfswrap_fsync_send
,
2523 .fsync_recv_fn
= vfswrap_asys_int_recv
,
2524 .stat_fn
= vfswrap_stat
,
2525 .fstat_fn
= vfswrap_fstat
,
2526 .lstat_fn
= vfswrap_lstat
,
2527 .get_alloc_size_fn
= vfswrap_get_alloc_size
,
2528 .unlink_fn
= vfswrap_unlink
,
2529 .chmod_fn
= vfswrap_chmod
,
2530 .fchmod_fn
= vfswrap_fchmod
,
2531 .chown_fn
= vfswrap_chown
,
2532 .fchown_fn
= vfswrap_fchown
,
2533 .lchown_fn
= vfswrap_lchown
,
2534 .chdir_fn
= vfswrap_chdir
,
2535 .getwd_fn
= vfswrap_getwd
,
2536 .ntimes_fn
= vfswrap_ntimes
,
2537 .ftruncate_fn
= vfswrap_ftruncate
,
2538 .fallocate_fn
= vfswrap_fallocate
,
2539 .lock_fn
= vfswrap_lock
,
2540 .kernel_flock_fn
= vfswrap_kernel_flock
,
2541 .linux_setlease_fn
= vfswrap_linux_setlease
,
2542 .getlock_fn
= vfswrap_getlock
,
2543 .symlink_fn
= vfswrap_symlink
,
2544 .readlink_fn
= vfswrap_readlink
,
2545 .link_fn
= vfswrap_link
,
2546 .mknod_fn
= vfswrap_mknod
,
2547 .realpath_fn
= vfswrap_realpath
,
2548 .notify_watch_fn
= vfswrap_notify_watch
,
2549 .chflags_fn
= vfswrap_chflags
,
2550 .file_id_create_fn
= vfswrap_file_id_create
,
2551 .streaminfo_fn
= vfswrap_streaminfo
,
2552 .get_real_filename_fn
= vfswrap_get_real_filename
,
2553 .connectpath_fn
= vfswrap_connectpath
,
2554 .brl_lock_windows_fn
= vfswrap_brl_lock_windows
,
2555 .brl_unlock_windows_fn
= vfswrap_brl_unlock_windows
,
2556 .brl_cancel_windows_fn
= vfswrap_brl_cancel_windows
,
2557 .strict_lock_fn
= vfswrap_strict_lock
,
2558 .strict_unlock_fn
= vfswrap_strict_unlock
,
2559 .translate_name_fn
= vfswrap_translate_name
,
2560 .fsctl_fn
= vfswrap_fsctl
,
2561 .copy_chunk_send_fn
= vfswrap_copy_chunk_send
,
2562 .copy_chunk_recv_fn
= vfswrap_copy_chunk_recv
,
2563 .get_compression_fn
= vfswrap_get_compression
,
2564 .set_compression_fn
= vfswrap_set_compression
,
2566 /* NT ACL operations. */
2568 .fget_nt_acl_fn
= vfswrap_fget_nt_acl
,
2569 .get_nt_acl_fn
= vfswrap_get_nt_acl
,
2570 .fset_nt_acl_fn
= vfswrap_fset_nt_acl
,
2571 .audit_file_fn
= vfswrap_audit_file
,
2573 /* POSIX ACL operations. */
2575 .chmod_acl_fn
= vfswrap_chmod_acl
,
2576 .fchmod_acl_fn
= vfswrap_fchmod_acl
,
2578 .sys_acl_get_file_fn
= vfswrap_sys_acl_get_file
,
2579 .sys_acl_get_fd_fn
= vfswrap_sys_acl_get_fd
,
2580 .sys_acl_blob_get_file_fn
= posix_sys_acl_blob_get_file
,
2581 .sys_acl_blob_get_fd_fn
= posix_sys_acl_blob_get_fd
,
2582 .sys_acl_set_file_fn
= vfswrap_sys_acl_set_file
,
2583 .sys_acl_set_fd_fn
= vfswrap_sys_acl_set_fd
,
2584 .sys_acl_delete_def_file_fn
= vfswrap_sys_acl_delete_def_file
,
2586 /* EA operations. */
2587 .getxattr_fn
= vfswrap_getxattr
,
2588 .fgetxattr_fn
= vfswrap_fgetxattr
,
2589 .listxattr_fn
= vfswrap_listxattr
,
2590 .flistxattr_fn
= vfswrap_flistxattr
,
2591 .removexattr_fn
= vfswrap_removexattr
,
2592 .fremovexattr_fn
= vfswrap_fremovexattr
,
2593 .setxattr_fn
= vfswrap_setxattr
,
2594 .fsetxattr_fn
= vfswrap_fsetxattr
,
2596 /* aio operations */
2597 .aio_force_fn
= vfswrap_aio_force
,
2599 /* offline operations */
2600 .is_offline_fn
= vfswrap_is_offline
,
2601 .set_offline_fn
= vfswrap_set_offline
,
2603 /* durable handle operations */
2604 .durable_cookie_fn
= vfswrap_durable_cookie
,
2605 .durable_disconnect_fn
= vfswrap_durable_disconnect
,
2606 .durable_reconnect_fn
= vfswrap_durable_reconnect
,
2609 NTSTATUS
vfs_default_init(void);
2610 NTSTATUS
vfs_default_init(void)
2612 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION
,
2613 DEFAULT_VFS_MODULE_NAME
, &vfs_default_fns
);