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 /* Default Posix readdir() does not give us stat info.
380 * Set to invalid to indicate we didn't return this info. */
382 SET_STAT_INVALID(*sbuf
);
383 END_PROFILE(syscall_readdir
);
387 static void vfswrap_seekdir(vfs_handle_struct
*handle
, DIR *dirp
, long offset
)
389 START_PROFILE(syscall_seekdir
);
390 seekdir(dirp
, offset
);
391 END_PROFILE(syscall_seekdir
);
394 static long vfswrap_telldir(vfs_handle_struct
*handle
, DIR *dirp
)
397 START_PROFILE(syscall_telldir
);
398 result
= telldir(dirp
);
399 END_PROFILE(syscall_telldir
);
403 static void vfswrap_rewinddir(vfs_handle_struct
*handle
, DIR *dirp
)
405 START_PROFILE(syscall_rewinddir
);
407 END_PROFILE(syscall_rewinddir
);
410 static int vfswrap_mkdir(vfs_handle_struct
*handle
, const char *path
, mode_t mode
)
413 bool has_dacl
= False
;
416 START_PROFILE(syscall_mkdir
);
418 if (lp_inherit_acls(SNUM(handle
->conn
))
419 && parent_dirname(talloc_tos(), path
, &parent
, NULL
)
420 && (has_dacl
= directory_has_default_acl(handle
->conn
, parent
)))
421 mode
= (0777 & lp_dir_mask(SNUM(handle
->conn
)));
425 result
= mkdir(path
, mode
);
427 if (result
== 0 && !has_dacl
) {
429 * We need to do this as the default behavior of POSIX ACLs
430 * is to set the mask to be the requested group permission
431 * bits, not the group permission bits to be the requested
432 * group permission bits. This is not what we want, as it will
433 * mess up any inherited ACL bits that were set. JRA.
435 int saved_errno
= errno
; /* We may get ENOSYS */
436 if ((SMB_VFS_CHMOD_ACL(handle
->conn
, path
, mode
) == -1) && (errno
== ENOSYS
))
440 END_PROFILE(syscall_mkdir
);
444 static int vfswrap_rmdir(vfs_handle_struct
*handle
, const char *path
)
448 START_PROFILE(syscall_rmdir
);
449 result
= rmdir(path
);
450 END_PROFILE(syscall_rmdir
);
454 static int vfswrap_closedir(vfs_handle_struct
*handle
, DIR *dirp
)
458 START_PROFILE(syscall_closedir
);
459 result
= closedir(dirp
);
460 END_PROFILE(syscall_closedir
);
464 static void vfswrap_init_search_op(vfs_handle_struct
*handle
,
467 /* Default behavior is a NOOP */
470 /* File operations */
472 static int vfswrap_open(vfs_handle_struct
*handle
,
473 struct smb_filename
*smb_fname
,
474 files_struct
*fsp
, int flags
, mode_t mode
)
478 START_PROFILE(syscall_open
);
480 if (smb_fname
->stream_name
) {
485 result
= open(smb_fname
->base_name
, flags
, mode
);
487 END_PROFILE(syscall_open
);
491 static NTSTATUS
vfswrap_create_file(vfs_handle_struct
*handle
,
492 struct smb_request
*req
,
493 uint16_t root_dir_fid
,
494 struct smb_filename
*smb_fname
,
495 uint32_t access_mask
,
496 uint32_t share_access
,
497 uint32_t create_disposition
,
498 uint32_t create_options
,
499 uint32_t file_attributes
,
500 uint32_t oplock_request
,
501 uint64_t allocation_size
,
502 uint32_t private_flags
,
503 struct security_descriptor
*sd
,
504 struct ea_list
*ea_list
,
505 files_struct
**result
,
508 return create_file_default(handle
->conn
, req
, root_dir_fid
, smb_fname
,
509 access_mask
, share_access
,
510 create_disposition
, create_options
,
511 file_attributes
, oplock_request
,
512 allocation_size
, private_flags
,
517 static int vfswrap_close(vfs_handle_struct
*handle
, files_struct
*fsp
)
521 START_PROFILE(syscall_close
);
522 result
= fd_close_posix(fsp
);
523 END_PROFILE(syscall_close
);
527 static ssize_t
vfswrap_read(vfs_handle_struct
*handle
, files_struct
*fsp
, void *data
, size_t n
)
531 START_PROFILE_BYTES(syscall_read
, n
);
532 result
= sys_read(fsp
->fh
->fd
, data
, n
);
533 END_PROFILE(syscall_read
);
537 static ssize_t
vfswrap_pread(vfs_handle_struct
*handle
, files_struct
*fsp
, void *data
,
538 size_t n
, off_t offset
)
542 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
543 START_PROFILE_BYTES(syscall_pread
, n
);
544 result
= sys_pread(fsp
->fh
->fd
, data
, n
, offset
);
545 END_PROFILE(syscall_pread
);
547 if (result
== -1 && errno
== ESPIPE
) {
548 /* Maintain the fiction that pipes can be seeked (sought?) on. */
549 result
= SMB_VFS_READ(fsp
, data
, n
);
553 #else /* HAVE_PREAD */
557 curr
= SMB_VFS_LSEEK(fsp
, 0, SEEK_CUR
);
558 if (curr
== -1 && errno
== ESPIPE
) {
559 /* Maintain the fiction that pipes can be seeked (sought?) on. */
560 result
= SMB_VFS_READ(fsp
, data
, n
);
565 if (SMB_VFS_LSEEK(fsp
, offset
, SEEK_SET
) == -1) {
570 result
= SMB_VFS_READ(fsp
, data
, n
);
573 SMB_VFS_LSEEK(fsp
, curr
, SEEK_SET
);
576 #endif /* HAVE_PREAD */
581 static ssize_t
vfswrap_write(vfs_handle_struct
*handle
, files_struct
*fsp
, const void *data
, size_t n
)
585 START_PROFILE_BYTES(syscall_write
, n
);
586 result
= sys_write(fsp
->fh
->fd
, data
, n
);
587 END_PROFILE(syscall_write
);
591 static ssize_t
vfswrap_pwrite(vfs_handle_struct
*handle
, files_struct
*fsp
, const void *data
,
592 size_t n
, off_t offset
)
596 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
597 START_PROFILE_BYTES(syscall_pwrite
, n
);
598 result
= sys_pwrite(fsp
->fh
->fd
, data
, n
, offset
);
599 END_PROFILE(syscall_pwrite
);
601 if (result
== -1 && errno
== ESPIPE
) {
602 /* Maintain the fiction that pipes can be sought on. */
603 result
= SMB_VFS_WRITE(fsp
, data
, n
);
606 #else /* HAVE_PWRITE */
610 curr
= SMB_VFS_LSEEK(fsp
, 0, SEEK_CUR
);
615 if (SMB_VFS_LSEEK(fsp
, offset
, SEEK_SET
) == -1) {
619 result
= SMB_VFS_WRITE(fsp
, data
, n
);
622 SMB_VFS_LSEEK(fsp
, curr
, SEEK_SET
);
625 #endif /* HAVE_PWRITE */
630 static void vfswrap_asys_finished(struct tevent_context
*ev
,
631 struct tevent_fd
*fde
,
632 uint16_t flags
, void *p
);
634 static bool vfswrap_init_asys_ctx(struct smbXsrv_connection
*conn
)
639 if (conn
->asys_ctx
!= NULL
) {
642 ret
= asys_context_init(&conn
->asys_ctx
, aio_pending_size
);
644 DEBUG(1, ("asys_context_init failed: %s\n", strerror(ret
)));
648 fd
= asys_signalfd(conn
->asys_ctx
);
650 set_blocking(fd
, false);
652 conn
->asys_fde
= tevent_add_fd(conn
->ev_ctx
, conn
, fd
,
654 vfswrap_asys_finished
,
656 if (conn
->asys_fde
== NULL
) {
657 DEBUG(1, ("tevent_add_fd failed\n"));
658 asys_context_destroy(conn
->asys_ctx
);
659 conn
->asys_ctx
= NULL
;
665 struct vfswrap_asys_state
{
666 struct asys_context
*asys_ctx
;
667 struct tevent_req
*req
;
672 static int vfswrap_asys_state_destructor(struct vfswrap_asys_state
*s
)
674 asys_cancel(s
->asys_ctx
, s
->req
);
678 static struct tevent_req
*vfswrap_pread_send(struct vfs_handle_struct
*handle
,
680 struct tevent_context
*ev
,
681 struct files_struct
*fsp
,
683 size_t n
, off_t offset
)
685 struct tevent_req
*req
;
686 struct vfswrap_asys_state
*state
;
689 req
= tevent_req_create(mem_ctx
, &state
, struct vfswrap_asys_state
);
693 if (!vfswrap_init_asys_ctx(handle
->conn
->sconn
->conn
)) {
695 return tevent_req_post(req
, ev
);
697 state
->asys_ctx
= handle
->conn
->sconn
->conn
->asys_ctx
;
700 ret
= asys_pread(state
->asys_ctx
, fsp
->fh
->fd
, data
, n
, offset
, req
);
702 tevent_req_error(req
, ret
);
703 return tevent_req_post(req
, ev
);
705 talloc_set_destructor(state
, vfswrap_asys_state_destructor
);
710 static struct tevent_req
*vfswrap_pwrite_send(struct vfs_handle_struct
*handle
,
712 struct tevent_context
*ev
,
713 struct files_struct
*fsp
,
715 size_t n
, off_t offset
)
717 struct tevent_req
*req
;
718 struct vfswrap_asys_state
*state
;
721 req
= tevent_req_create(mem_ctx
, &state
, struct vfswrap_asys_state
);
725 if (!vfswrap_init_asys_ctx(handle
->conn
->sconn
->conn
)) {
727 return tevent_req_post(req
, ev
);
729 state
->asys_ctx
= handle
->conn
->sconn
->conn
->asys_ctx
;
732 ret
= asys_pwrite(state
->asys_ctx
, fsp
->fh
->fd
, data
, n
, offset
, req
);
734 tevent_req_error(req
, ret
);
735 return tevent_req_post(req
, ev
);
737 talloc_set_destructor(state
, vfswrap_asys_state_destructor
);
742 static struct tevent_req
*vfswrap_fsync_send(struct vfs_handle_struct
*handle
,
744 struct tevent_context
*ev
,
745 struct files_struct
*fsp
)
747 struct tevent_req
*req
;
748 struct vfswrap_asys_state
*state
;
751 req
= tevent_req_create(mem_ctx
, &state
, struct vfswrap_asys_state
);
755 if (!vfswrap_init_asys_ctx(handle
->conn
->sconn
->conn
)) {
757 return tevent_req_post(req
, ev
);
759 state
->asys_ctx
= handle
->conn
->sconn
->conn
->asys_ctx
;
762 ret
= asys_fsync(state
->asys_ctx
, fsp
->fh
->fd
, req
);
764 tevent_req_error(req
, ret
);
765 return tevent_req_post(req
, ev
);
767 talloc_set_destructor(state
, vfswrap_asys_state_destructor
);
772 static void vfswrap_asys_finished(struct tevent_context
*ev
,
773 struct tevent_fd
*fde
,
774 uint16_t flags
, void *p
)
776 struct asys_context
*asys_ctx
= (struct asys_context
*)p
;
777 struct tevent_req
*req
;
778 struct vfswrap_asys_state
*state
;
784 if ((flags
& TEVENT_FD_READ
) == 0) {
789 res
= asys_result(asys_ctx
, &ret
, &err
, &private_data
);
790 if (res
== EINTR
|| res
== EAGAIN
) {
794 if (res
== EWOULDBLOCK
) {
799 if (res
== ECANCELED
) {
804 DEBUG(1, ("asys_result returned %s\n", strerror(res
)));
808 req
= talloc_get_type_abort(private_data
, struct tevent_req
);
809 state
= tevent_req_data(req
, struct vfswrap_asys_state
);
811 talloc_set_destructor(state
, NULL
);
815 tevent_req_defer_callback(req
, ev
);
816 tevent_req_done(req
);
820 static ssize_t
vfswrap_asys_ssize_t_recv(struct tevent_req
*req
, int *err
)
822 struct vfswrap_asys_state
*state
= tevent_req_data(
823 req
, struct vfswrap_asys_state
);
825 if (tevent_req_is_unix_error(req
, err
)) {
832 static int vfswrap_asys_int_recv(struct tevent_req
*req
, int *err
)
834 struct vfswrap_asys_state
*state
= tevent_req_data(
835 req
, struct vfswrap_asys_state
);
837 if (tevent_req_is_unix_error(req
, err
)) {
844 static off_t
vfswrap_lseek(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t offset
, int whence
)
848 START_PROFILE(syscall_lseek
);
850 /* Cope with 'stat' file opens. */
851 if (fsp
->fh
->fd
!= -1)
852 result
= lseek(fsp
->fh
->fd
, offset
, whence
);
855 * We want to maintain the fiction that we can seek
856 * on a fifo for file system purposes. This allows
857 * people to set up UNIX fifo's that feed data to Windows
861 if((result
== -1) && (errno
== ESPIPE
)) {
866 END_PROFILE(syscall_lseek
);
870 static ssize_t
vfswrap_sendfile(vfs_handle_struct
*handle
, int tofd
, files_struct
*fromfsp
, const DATA_BLOB
*hdr
,
871 off_t offset
, size_t n
)
875 START_PROFILE_BYTES(syscall_sendfile
, n
);
876 result
= sys_sendfile(tofd
, fromfsp
->fh
->fd
, hdr
, offset
, n
);
877 END_PROFILE(syscall_sendfile
);
881 static ssize_t
vfswrap_recvfile(vfs_handle_struct
*handle
,
889 START_PROFILE_BYTES(syscall_recvfile
, n
);
890 result
= sys_recvfile(fromfd
, tofsp
->fh
->fd
, offset
, n
);
891 END_PROFILE(syscall_recvfile
);
895 static int vfswrap_rename(vfs_handle_struct
*handle
,
896 const struct smb_filename
*smb_fname_src
,
897 const struct smb_filename
*smb_fname_dst
)
901 START_PROFILE(syscall_rename
);
903 if (smb_fname_src
->stream_name
|| smb_fname_dst
->stream_name
) {
908 result
= rename(smb_fname_src
->base_name
, smb_fname_dst
->base_name
);
911 END_PROFILE(syscall_rename
);
915 static int vfswrap_fsync(vfs_handle_struct
*handle
, files_struct
*fsp
)
920 START_PROFILE(syscall_fsync
);
921 result
= fsync(fsp
->fh
->fd
);
922 END_PROFILE(syscall_fsync
);
929 static int vfswrap_stat(vfs_handle_struct
*handle
,
930 struct smb_filename
*smb_fname
)
934 START_PROFILE(syscall_stat
);
936 if (smb_fname
->stream_name
) {
941 result
= sys_stat(smb_fname
->base_name
, &smb_fname
->st
,
942 lp_fake_dir_create_times(SNUM(handle
->conn
)));
944 END_PROFILE(syscall_stat
);
948 static int vfswrap_fstat(vfs_handle_struct
*handle
, files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
952 START_PROFILE(syscall_fstat
);
953 result
= sys_fstat(fsp
->fh
->fd
,
954 sbuf
, lp_fake_dir_create_times(SNUM(handle
->conn
)));
955 END_PROFILE(syscall_fstat
);
959 static int vfswrap_lstat(vfs_handle_struct
*handle
,
960 struct smb_filename
*smb_fname
)
964 START_PROFILE(syscall_lstat
);
966 if (smb_fname
->stream_name
) {
971 result
= sys_lstat(smb_fname
->base_name
, &smb_fname
->st
,
972 lp_fake_dir_create_times(SNUM(handle
->conn
)));
974 END_PROFILE(syscall_lstat
);
978 static NTSTATUS
vfswrap_translate_name(struct vfs_handle_struct
*handle
,
980 enum vfs_translate_direction direction
,
984 return NT_STATUS_NONE_MAPPED
;
988 * Implement the default fsctl operation.
990 static bool vfswrap_logged_ioctl_message
= false;
992 static NTSTATUS
vfswrap_fsctl(struct vfs_handle_struct
*handle
,
993 struct files_struct
*fsp
,
996 uint16_t req_flags
, /* Needed for UNICODE ... */
997 const uint8_t *_in_data
,
1000 uint32_t max_out_len
,
1003 const char *in_data
= (const char *)_in_data
;
1004 char **out_data
= (char **)_out_data
;
1007 case FSCTL_SET_SPARSE
:
1009 bool set_sparse
= true;
1012 if (in_len
>= 1 && in_data
[0] == 0) {
1016 status
= file_set_sparse(handle
->conn
, fsp
, set_sparse
);
1018 DEBUG(NT_STATUS_IS_OK(status
) ? 10 : 9,
1019 ("FSCTL_SET_SPARSE: fname[%s] set[%u] - %s\n",
1020 smb_fname_str_dbg(fsp
->fsp_name
), set_sparse
,
1021 nt_errstr(status
)));
1026 case FSCTL_CREATE_OR_GET_OBJECT_ID
:
1028 unsigned char objid
[16];
1029 char *return_data
= NULL
;
1031 /* This should return the object-id on this file.
1032 * I think I'll make this be the inode+dev. JRA.
1035 DEBUG(10,("FSCTL_CREATE_OR_GET_OBJECT_ID: called on %s\n",
1036 fsp_fnum_dbg(fsp
)));
1038 *out_len
= (max_out_len
>= 64) ? 64 : max_out_len
;
1039 /* Hmmm, will this cause problems if less data asked for? */
1040 return_data
= talloc_array(ctx
, char, 64);
1041 if (return_data
== NULL
) {
1042 return NT_STATUS_NO_MEMORY
;
1045 /* For backwards compatibility only store the dev/inode. */
1046 push_file_id_16(return_data
, &fsp
->file_id
);
1047 memcpy(return_data
+16,create_volume_objectid(fsp
->conn
,objid
),16);
1048 push_file_id_16(return_data
+32, &fsp
->file_id
);
1049 *out_data
= return_data
;
1050 return NT_STATUS_OK
;
1053 case FSCTL_GET_REPARSE_POINT
:
1055 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
1056 DEBUG(10, ("FSCTL_GET_REPARSE_POINT: called on %s. "
1057 "Status: NOT_IMPLEMENTED\n", fsp_fnum_dbg(fsp
)));
1058 return NT_STATUS_NOT_A_REPARSE_POINT
;
1061 case FSCTL_SET_REPARSE_POINT
:
1063 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
1064 DEBUG(10, ("FSCTL_SET_REPARSE_POINT: called on %s. "
1065 "Status: NOT_IMPLEMENTED\n", fsp_fnum_dbg(fsp
)));
1066 return NT_STATUS_NOT_A_REPARSE_POINT
;
1069 case FSCTL_GET_SHADOW_COPY_DATA
:
1072 * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
1073 * and return their volume names. If max_data_count is 16, then it is just
1074 * asking for the number of volumes and length of the combined names.
1076 * pdata is the data allocated by our caller, but that uses
1077 * total_data_count (which is 0 in our case) rather than max_data_count.
1078 * Allocate the correct amount and return the pointer to let
1079 * it be deallocated when we return.
1081 struct shadow_copy_data
*shadow_data
= NULL
;
1082 bool labels
= False
;
1083 uint32 labels_data_count
= 0;
1085 char *cur_pdata
= NULL
;
1087 if (max_out_len
< 16) {
1088 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
1090 return NT_STATUS_INVALID_PARAMETER
;
1093 if (max_out_len
> 16) {
1097 shadow_data
= talloc_zero(ctx
, struct shadow_copy_data
);
1098 if (shadow_data
== NULL
) {
1099 DEBUG(0,("TALLOC_ZERO() failed!\n"));
1100 return NT_STATUS_NO_MEMORY
;
1104 * Call the VFS routine to actually do the work.
1106 if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp
, shadow_data
, labels
)!=0) {
1107 TALLOC_FREE(shadow_data
);
1108 if (errno
== ENOSYS
) {
1109 DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n",
1110 fsp
->conn
->connectpath
));
1111 return NT_STATUS_NOT_SUPPORTED
;
1113 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n",
1114 fsp
->conn
->connectpath
));
1115 return NT_STATUS_UNSUCCESSFUL
;
1119 labels_data_count
= (shadow_data
->num_volumes
* 2 *
1120 sizeof(SHADOW_COPY_LABEL
)) + 2;
1125 *out_len
= 12 + labels_data_count
+ 4;
1128 if (max_out_len
< *out_len
) {
1129 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
1130 max_out_len
, *out_len
));
1131 TALLOC_FREE(shadow_data
);
1132 return NT_STATUS_BUFFER_TOO_SMALL
;
1135 cur_pdata
= talloc_array(ctx
, char, *out_len
);
1136 if (cur_pdata
== NULL
) {
1137 TALLOC_FREE(shadow_data
);
1138 return NT_STATUS_NO_MEMORY
;
1141 *out_data
= cur_pdata
;
1143 /* num_volumes 4 bytes */
1144 SIVAL(cur_pdata
, 0, shadow_data
->num_volumes
);
1147 /* num_labels 4 bytes */
1148 SIVAL(cur_pdata
, 4, shadow_data
->num_volumes
);
1151 /* needed_data_count 4 bytes */
1152 SIVAL(cur_pdata
, 8, labels_data_count
+ 4);
1156 DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
1157 shadow_data
->num_volumes
, fsp_str_dbg(fsp
)));
1158 if (labels
&& shadow_data
->labels
) {
1159 for (i
=0; i
<shadow_data
->num_volumes
; i
++) {
1160 srvstr_push(cur_pdata
, req_flags
,
1161 cur_pdata
, shadow_data
->labels
[i
],
1162 2 * sizeof(SHADOW_COPY_LABEL
),
1163 STR_UNICODE
|STR_TERMINATE
);
1164 cur_pdata
+= 2 * sizeof(SHADOW_COPY_LABEL
);
1165 DEBUGADD(10,("Label[%u]: '%s'\n",i
,shadow_data
->labels
[i
]));
1169 TALLOC_FREE(shadow_data
);
1171 return NT_STATUS_OK
;
1174 case FSCTL_FIND_FILES_BY_SID
:
1176 /* pretend this succeeded -
1178 * we have to send back a list with all files owned by this SID
1180 * but I have to check that --metze
1186 DEBUG(10, ("FSCTL_FIND_FILES_BY_SID: called on %s\n",
1187 fsp_fnum_dbg(fsp
)));
1190 /* NT_STATUS_BUFFER_TOO_SMALL maybe? */
1191 return NT_STATUS_INVALID_PARAMETER
;
1194 sid_len
= MIN(in_len
- 4,SID_MAX_SIZE
);
1196 /* unknown 4 bytes: this is not the length of the sid :-( */
1197 /*unknown = IVAL(pdata,0);*/
1199 if (!sid_parse(in_data
+ 4, sid_len
, &sid
)) {
1200 return NT_STATUS_INVALID_PARAMETER
;
1202 DEBUGADD(10, ("for SID: %s\n", sid_string_dbg(&sid
)));
1204 if (!sid_to_uid(&sid
, &uid
)) {
1205 DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
1206 sid_string_dbg(&sid
),
1207 (unsigned long)sid_len
));
1211 /* we can take a look at the find source :-)
1213 * find ./ -uid $uid -name '*' is what we need here
1216 * and send 4bytes len and then NULL terminated unicode strings
1219 * but I don't know how to deal with the paged results
1220 * (maybe we can hang the result anywhere in the fsp struct)
1222 * but I don't know how to deal with the paged results
1223 * (maybe we can hang the result anywhere in the fsp struct)
1225 * we don't send all files at once
1226 * and at the next we should *not* start from the beginning,
1227 * so we have to cache the result
1232 /* this works for now... */
1233 return NT_STATUS_OK
;
1236 case FSCTL_QUERY_ALLOCATED_RANGES
:
1238 /* FIXME: This is just a dummy reply, telling that all of the
1239 * file is allocated. MKS cp needs that.
1240 * Adding the real allocated ranges via FIEMAP on Linux
1241 * and SEEK_DATA/SEEK_HOLE on Solaris is needed to make
1242 * this FSCTL correct for sparse files.
1245 uint64_t offset
, length
;
1246 char *out_data_tmp
= NULL
;
1249 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: data_count(%u) != 16 is invalid!\n",
1251 return NT_STATUS_INVALID_PARAMETER
;
1254 if (max_out_len
< 16) {
1255 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: max_out_len (%u) < 16 is invalid!\n",
1257 return NT_STATUS_INVALID_PARAMETER
;
1260 offset
= BVAL(in_data
,0);
1261 length
= BVAL(in_data
,8);
1263 if (offset
+ length
< offset
) {
1264 /* No 64-bit integer wrap. */
1265 return NT_STATUS_INVALID_PARAMETER
;
1268 /* Shouldn't this be SMB_VFS_STAT ... ? */
1269 status
= vfs_stat_fsp(fsp
);
1270 if (!NT_STATUS_IS_OK(status
)) {
1275 out_data_tmp
= talloc_array(ctx
, char, *out_len
);
1276 if (out_data_tmp
== NULL
) {
1277 DEBUG(10, ("unable to allocate memory for response\n"));
1278 return NT_STATUS_NO_MEMORY
;
1281 if (offset
> fsp
->fsp_name
->st
.st_ex_size
||
1282 fsp
->fsp_name
->st
.st_ex_size
== 0 ||
1284 memset(out_data_tmp
, 0, *out_len
);
1286 uint64_t end
= offset
+ length
;
1287 end
= MIN(end
, fsp
->fsp_name
->st
.st_ex_size
);
1288 SBVAL(out_data_tmp
, 0, 0);
1289 SBVAL(out_data_tmp
, 8, end
);
1292 *out_data
= out_data_tmp
;
1294 return NT_STATUS_OK
;
1297 case FSCTL_IS_VOLUME_DIRTY
:
1299 DEBUG(10,("FSCTL_IS_VOLUME_DIRTY: called on %s "
1300 "(but remotely not supported)\n", fsp_fnum_dbg(fsp
)));
1302 * http://msdn.microsoft.com/en-us/library/cc232128%28PROT.10%29.aspx
1303 * says we have to respond with NT_STATUS_INVALID_PARAMETER
1305 return NT_STATUS_INVALID_PARAMETER
;
1310 * Only print once ... unfortunately there could be lots of
1311 * different FSCTLs that are called.
1313 if (!vfswrap_logged_ioctl_message
) {
1314 vfswrap_logged_ioctl_message
= true;
1315 DEBUG(2, ("%s (0x%x): Currently not implemented.\n",
1316 __func__
, function
));
1320 return NT_STATUS_NOT_SUPPORTED
;
1323 struct vfs_cc_state
{
1328 static struct tevent_req
*vfswrap_copy_chunk_send(struct vfs_handle_struct
*handle
,
1329 TALLOC_CTX
*mem_ctx
,
1330 struct tevent_context
*ev
,
1331 struct files_struct
*src_fsp
,
1333 struct files_struct
*dest_fsp
,
1337 struct tevent_req
*req
;
1338 struct vfs_cc_state
*vfs_cc_state
;
1341 DEBUG(10, ("performing server side copy chunk of length %lu\n",
1342 (unsigned long)num
));
1344 req
= tevent_req_create(mem_ctx
, &vfs_cc_state
, struct vfs_cc_state
);
1349 status
= vfs_stat_fsp(src_fsp
);
1350 if (tevent_req_nterror(req
, status
)) {
1351 return tevent_req_post(req
, ev
);
1354 if (src_fsp
->fsp_name
->st
.st_ex_size
< src_off
+ num
) {
1356 * [MS-SMB2] 3.3.5.15.6 Handling a Server-Side Data Copy Request
1357 * If the SourceOffset or SourceOffset + Length extends beyond
1358 * the end of file, the server SHOULD<240> treat this as a
1359 * STATUS_END_OF_FILE error.
1361 * <240> Section 3.3.5.15.6: Windows servers will return
1362 * STATUS_INVALID_VIEW_SIZE instead of STATUS_END_OF_FILE.
1364 tevent_req_nterror(req
, NT_STATUS_INVALID_VIEW_SIZE
);
1365 return tevent_req_post(req
, ev
);
1368 /* could use 2.6.33+ sendfile here to do this in kernel */
1369 while (vfs_cc_state
->copied
< num
) {
1371 struct lock_struct lck
;
1374 off_t this_num
= MIN(sizeof(vfs_cc_state
->buf
),
1375 num
- vfs_cc_state
->copied
);
1377 init_strict_lock_struct(src_fsp
,
1378 src_fsp
->op
->global
->open_persistent_id
,
1384 if (!SMB_VFS_STRICT_LOCK(src_fsp
->conn
, src_fsp
, &lck
)) {
1385 tevent_req_nterror(req
, NT_STATUS_FILE_LOCK_CONFLICT
);
1386 return tevent_req_post(req
, ev
);
1389 ret
= SMB_VFS_PREAD(src_fsp
, vfs_cc_state
->buf
,
1392 saved_errno
= errno
;
1395 SMB_VFS_STRICT_UNLOCK(src_fsp
->conn
, src_fsp
, &lck
);
1398 errno
= saved_errno
;
1399 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
1400 return tevent_req_post(req
, ev
);
1402 if (ret
!= this_num
) {
1403 /* zero tolerance for short reads */
1404 tevent_req_nterror(req
, NT_STATUS_IO_DEVICE_ERROR
);
1405 return tevent_req_post(req
, ev
);
1410 init_strict_lock_struct(dest_fsp
,
1411 dest_fsp
->op
->global
->open_persistent_id
,
1417 if (!SMB_VFS_STRICT_LOCK(dest_fsp
->conn
, dest_fsp
, &lck
)) {
1418 tevent_req_nterror(req
, NT_STATUS_FILE_LOCK_CONFLICT
);
1419 return tevent_req_post(req
, ev
);
1422 ret
= SMB_VFS_PWRITE(dest_fsp
, vfs_cc_state
->buf
,
1423 this_num
, dest_off
);
1425 saved_errno
= errno
;
1428 SMB_VFS_STRICT_UNLOCK(src_fsp
->conn
, src_fsp
, &lck
);
1431 errno
= saved_errno
;
1432 tevent_req_nterror(req
, map_nt_error_from_unix(errno
));
1433 return tevent_req_post(req
, ev
);
1435 if (ret
!= this_num
) {
1436 /* zero tolerance for short writes */
1437 tevent_req_nterror(req
, NT_STATUS_IO_DEVICE_ERROR
);
1438 return tevent_req_post(req
, ev
);
1442 vfs_cc_state
->copied
+= this_num
;
1445 tevent_req_done(req
);
1446 return tevent_req_post(req
, ev
);
1449 static NTSTATUS
vfswrap_copy_chunk_recv(struct vfs_handle_struct
*handle
,
1450 struct tevent_req
*req
,
1453 struct vfs_cc_state
*vfs_cc_state
= tevent_req_data(req
,
1454 struct vfs_cc_state
);
1457 if (tevent_req_is_nterror(req
, &status
)) {
1458 DEBUG(2, ("server side copy chunk failed: %s\n",
1459 nt_errstr(status
)));
1461 tevent_req_received(req
);
1465 *copied
= vfs_cc_state
->copied
;
1466 DEBUG(10, ("server side copy chunk copied %lu\n",
1467 (unsigned long)*copied
));
1468 tevent_req_received(req
);
1470 return NT_STATUS_OK
;
1473 /********************************************************************
1474 Given a stat buffer return the allocated size on disk, taking into
1475 account sparse files.
1476 ********************************************************************/
1477 static uint64_t vfswrap_get_alloc_size(vfs_handle_struct
*handle
,
1478 struct files_struct
*fsp
,
1479 const SMB_STRUCT_STAT
*sbuf
)
1483 START_PROFILE(syscall_get_alloc_size
);
1485 if(S_ISDIR(sbuf
->st_ex_mode
)) {
1490 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
1491 /* The type of st_blocksize is blkcnt_t which *MUST* be
1492 signed (according to POSIX) and can be less than 64-bits.
1493 Ensure when we're converting to 64 bits wide we don't
1495 #if defined(SIZEOF_BLKCNT_T_8)
1496 result
= (uint64_t)STAT_ST_BLOCKSIZE
* (uint64_t)sbuf
->st_ex_blocks
;
1497 #elif defined(SIZEOF_BLKCNT_T_4)
1499 uint64_t bs
= ((uint64_t)sbuf
->st_ex_blocks
) & 0xFFFFFFFFLL
;
1500 result
= (uint64_t)STAT_ST_BLOCKSIZE
* bs
;
1503 #error SIZEOF_BLKCNT_T_NOT_A_SUPPORTED_VALUE
1506 result
= get_file_size_stat(sbuf
);
1509 if (fsp
&& fsp
->initial_allocation_size
)
1510 result
= MAX(result
,fsp
->initial_allocation_size
);
1512 result
= smb_roundup(handle
->conn
, result
);
1515 END_PROFILE(syscall_get_alloc_size
);
1519 static int vfswrap_unlink(vfs_handle_struct
*handle
,
1520 const struct smb_filename
*smb_fname
)
1524 START_PROFILE(syscall_unlink
);
1526 if (smb_fname
->stream_name
) {
1530 result
= unlink(smb_fname
->base_name
);
1533 END_PROFILE(syscall_unlink
);
1537 static int vfswrap_chmod(vfs_handle_struct
*handle
, const char *path
, mode_t mode
)
1541 START_PROFILE(syscall_chmod
);
1544 * We need to do this due to the fact that the default POSIX ACL
1545 * chmod modifies the ACL *mask* for the group owner, not the
1546 * group owner bits directly. JRA.
1551 int saved_errno
= errno
; /* We might get ENOSYS */
1552 if ((result
= SMB_VFS_CHMOD_ACL(handle
->conn
, path
, mode
)) == 0) {
1553 END_PROFILE(syscall_chmod
);
1556 /* Error - return the old errno. */
1557 errno
= saved_errno
;
1560 result
= chmod(path
, mode
);
1561 END_PROFILE(syscall_chmod
);
1565 static int vfswrap_fchmod(vfs_handle_struct
*handle
, files_struct
*fsp
, mode_t mode
)
1569 START_PROFILE(syscall_fchmod
);
1572 * We need to do this due to the fact that the default POSIX ACL
1573 * chmod modifies the ACL *mask* for the group owner, not the
1574 * group owner bits directly. JRA.
1578 int saved_errno
= errno
; /* We might get ENOSYS */
1579 if ((result
= SMB_VFS_FCHMOD_ACL(fsp
, mode
)) == 0) {
1580 END_PROFILE(syscall_fchmod
);
1583 /* Error - return the old errno. */
1584 errno
= saved_errno
;
1587 #if defined(HAVE_FCHMOD)
1588 result
= fchmod(fsp
->fh
->fd
, mode
);
1594 END_PROFILE(syscall_fchmod
);
1598 static int vfswrap_chown(vfs_handle_struct
*handle
, const char *path
, uid_t uid
, gid_t gid
)
1602 START_PROFILE(syscall_chown
);
1603 result
= chown(path
, uid
, gid
);
1604 END_PROFILE(syscall_chown
);
1608 static int vfswrap_fchown(vfs_handle_struct
*handle
, files_struct
*fsp
, uid_t uid
, gid_t gid
)
1613 START_PROFILE(syscall_fchown
);
1614 result
= fchown(fsp
->fh
->fd
, uid
, gid
);
1615 END_PROFILE(syscall_fchown
);
1623 static int vfswrap_lchown(vfs_handle_struct
*handle
, const char *path
, uid_t uid
, gid_t gid
)
1627 START_PROFILE(syscall_lchown
);
1628 result
= lchown(path
, uid
, gid
);
1629 END_PROFILE(syscall_lchown
);
1633 static int vfswrap_chdir(vfs_handle_struct
*handle
, const char *path
)
1637 START_PROFILE(syscall_chdir
);
1638 result
= chdir(path
);
1639 END_PROFILE(syscall_chdir
);
1643 static char *vfswrap_getwd(vfs_handle_struct
*handle
)
1647 START_PROFILE(syscall_getwd
);
1648 result
= sys_getwd();
1649 END_PROFILE(syscall_getwd
);
1653 /*********************************************************************
1654 nsec timestamp resolution call. Convert down to whatever the underlying
1655 system will support.
1656 **********************************************************************/
1658 static int vfswrap_ntimes(vfs_handle_struct
*handle
,
1659 const struct smb_filename
*smb_fname
,
1660 struct smb_file_time
*ft
)
1664 START_PROFILE(syscall_ntimes
);
1666 if (smb_fname
->stream_name
) {
1672 if (null_timespec(ft
->atime
)) {
1673 ft
->atime
= smb_fname
->st
.st_ex_atime
;
1676 if (null_timespec(ft
->mtime
)) {
1677 ft
->mtime
= smb_fname
->st
.st_ex_mtime
;
1680 if (!null_timespec(ft
->create_time
)) {
1681 set_create_timespec_ea(handle
->conn
,
1686 if ((timespec_compare(&ft
->atime
,
1687 &smb_fname
->st
.st_ex_atime
) == 0) &&
1688 (timespec_compare(&ft
->mtime
,
1689 &smb_fname
->st
.st_ex_mtime
) == 0)) {
1694 #if defined(HAVE_UTIMENSAT)
1696 struct timespec ts
[2];
1699 result
= utimensat(AT_FDCWD
, smb_fname
->base_name
, ts
, 0);
1701 result
= utimensat(AT_FDCWD
, smb_fname
->base_name
, NULL
, 0);
1703 if (!((result
== -1) && (errno
== ENOSYS
))) {
1707 #if defined(HAVE_UTIMES)
1709 struct timeval tv
[2];
1710 tv
[0] = convert_timespec_to_timeval(ft
->atime
);
1711 tv
[1] = convert_timespec_to_timeval(ft
->mtime
);
1712 result
= utimes(smb_fname
->base_name
, tv
);
1714 result
= utimes(smb_fname
->base_name
, NULL
);
1716 if (!((result
== -1) && (errno
== ENOSYS
))) {
1720 #if defined(HAVE_UTIME)
1722 struct utimbuf times
;
1723 times
.actime
= convert_timespec_to_time_t(ft
->atime
);
1724 times
.modtime
= convert_timespec_to_time_t(ft
->mtime
);
1725 result
= utime(smb_fname
->base_name
, ×
);
1727 result
= utime(smb_fname
->base_name
, NULL
);
1729 if (!((result
== -1) && (errno
== ENOSYS
))) {
1737 END_PROFILE(syscall_ntimes
);
1741 /*********************************************************************
1742 A version of ftruncate that will write the space on disk if strict
1744 **********************************************************************/
1746 static int strict_allocate_ftruncate(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t len
)
1748 off_t space_to_write
;
1749 uint64_t space_avail
;
1750 uint64_t bsize
,dfree
,dsize
;
1753 SMB_STRUCT_STAT
*pst
;
1755 status
= vfs_stat_fsp(fsp
);
1756 if (!NT_STATUS_IS_OK(status
)) {
1759 pst
= &fsp
->fsp_name
->st
;
1762 if (S_ISFIFO(pst
->st_ex_mode
))
1766 if (pst
->st_ex_size
== len
)
1769 /* Shrink - just ftruncate. */
1770 if (pst
->st_ex_size
> len
)
1771 return ftruncate(fsp
->fh
->fd
, len
);
1773 space_to_write
= len
- pst
->st_ex_size
;
1775 /* for allocation try fallocate first. This can fail on some
1776 platforms e.g. when the filesystem doesn't support it and no
1777 emulation is being done by the libc (like on AIX with JFS1). In that
1778 case we do our own emulation. fallocate implementations can
1779 return ENOTSUP or EINVAL in cases like that. */
1780 ret
= SMB_VFS_FALLOCATE(fsp
, VFS_FALLOCATE_EXTEND_SIZE
,
1781 pst
->st_ex_size
, space_to_write
);
1782 if (ret
== ENOSPC
) {
1789 DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with "
1790 "error %d. Falling back to slow manual allocation\n", ret
));
1792 /* available disk space is enough or not? */
1793 space_avail
= get_dfree_info(fsp
->conn
,
1794 fsp
->fsp_name
->base_name
, false,
1795 &bsize
,&dfree
,&dsize
);
1796 /* space_avail is 1k blocks */
1797 if (space_avail
== (uint64_t)-1 ||
1798 ((uint64_t)space_to_write
/1024 > space_avail
) ) {
1803 /* Write out the real space on disk. */
1804 ret
= vfs_slow_fallocate(fsp
, pst
->st_ex_size
, space_to_write
);
1813 static int vfswrap_ftruncate(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t len
)
1816 SMB_STRUCT_STAT
*pst
;
1820 START_PROFILE(syscall_ftruncate
);
1822 if (lp_strict_allocate(SNUM(fsp
->conn
)) && !fsp
->is_sparse
) {
1823 result
= strict_allocate_ftruncate(handle
, fsp
, len
);
1824 END_PROFILE(syscall_ftruncate
);
1828 /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
1829 ftruncate if the system supports it. Then I discovered that
1830 you can have some filesystems that support ftruncate
1831 expansion and some that don't! On Linux fat can't do
1832 ftruncate extend but ext2 can. */
1834 result
= ftruncate(fsp
->fh
->fd
, len
);
1838 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
1839 extend a file with ftruncate. Provide alternate implementation
1842 /* Do an fstat to see if the file is longer than the requested
1843 size in which case the ftruncate above should have
1844 succeeded or shorter, in which case seek to len - 1 and
1845 write 1 byte of zero */
1846 status
= vfs_stat_fsp(fsp
);
1847 if (!NT_STATUS_IS_OK(status
)) {
1850 pst
= &fsp
->fsp_name
->st
;
1853 if (S_ISFIFO(pst
->st_ex_mode
)) {
1859 if (pst
->st_ex_size
== len
) {
1864 if (pst
->st_ex_size
> len
) {
1865 /* the ftruncate should have worked */
1869 if (SMB_VFS_PWRITE(fsp
, &c
, 1, len
-1)!=1) {
1877 END_PROFILE(syscall_ftruncate
);
1881 static int vfswrap_fallocate(vfs_handle_struct
*handle
,
1883 enum vfs_fallocate_mode mode
,
1889 START_PROFILE(syscall_fallocate
);
1890 if (mode
== VFS_FALLOCATE_EXTEND_SIZE
) {
1891 result
= sys_posix_fallocate(fsp
->fh
->fd
, offset
, len
);
1892 } else if (mode
== VFS_FALLOCATE_KEEP_SIZE
) {
1893 result
= sys_fallocate(fsp
->fh
->fd
, mode
, offset
, len
);
1898 END_PROFILE(syscall_fallocate
);
1902 static bool vfswrap_lock(vfs_handle_struct
*handle
, files_struct
*fsp
, int op
, off_t offset
, off_t count
, int type
)
1906 START_PROFILE(syscall_fcntl_lock
);
1907 result
= fcntl_lock(fsp
->fh
->fd
, op
, offset
, count
, type
);
1908 END_PROFILE(syscall_fcntl_lock
);
1912 static int vfswrap_kernel_flock(vfs_handle_struct
*handle
, files_struct
*fsp
,
1913 uint32 share_mode
, uint32 access_mask
)
1915 START_PROFILE(syscall_kernel_flock
);
1916 kernel_flock(fsp
->fh
->fd
, share_mode
, access_mask
);
1917 END_PROFILE(syscall_kernel_flock
);
1921 static bool vfswrap_getlock(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t
*poffset
, off_t
*pcount
, int *ptype
, pid_t
*ppid
)
1925 START_PROFILE(syscall_fcntl_getlock
);
1926 result
= fcntl_getlock(fsp
->fh
->fd
, poffset
, pcount
, ptype
, ppid
);
1927 END_PROFILE(syscall_fcntl_getlock
);
1931 static int vfswrap_linux_setlease(vfs_handle_struct
*handle
, files_struct
*fsp
,
1936 START_PROFILE(syscall_linux_setlease
);
1938 #ifdef HAVE_KERNEL_OPLOCKS_LINUX
1939 result
= linux_setlease(fsp
->fh
->fd
, leasetype
);
1943 END_PROFILE(syscall_linux_setlease
);
1947 static int vfswrap_symlink(vfs_handle_struct
*handle
, const char *oldpath
, const char *newpath
)
1951 START_PROFILE(syscall_symlink
);
1952 result
= symlink(oldpath
, newpath
);
1953 END_PROFILE(syscall_symlink
);
1957 static int vfswrap_readlink(vfs_handle_struct
*handle
, const char *path
, char *buf
, size_t bufsiz
)
1961 START_PROFILE(syscall_readlink
);
1962 result
= readlink(path
, buf
, bufsiz
);
1963 END_PROFILE(syscall_readlink
);
1967 static int vfswrap_link(vfs_handle_struct
*handle
, const char *oldpath
, const char *newpath
)
1971 START_PROFILE(syscall_link
);
1972 result
= link(oldpath
, newpath
);
1973 END_PROFILE(syscall_link
);
1977 static int vfswrap_mknod(vfs_handle_struct
*handle
, const char *pathname
, mode_t mode
, SMB_DEV_T dev
)
1981 START_PROFILE(syscall_mknod
);
1982 result
= sys_mknod(pathname
, mode
, dev
);
1983 END_PROFILE(syscall_mknod
);
1987 static char *vfswrap_realpath(vfs_handle_struct
*handle
, const char *path
)
1991 START_PROFILE(syscall_realpath
);
1992 #ifdef REALPATH_TAKES_NULL
1993 result
= realpath(path
, NULL
);
1995 result
= SMB_MALLOC_ARRAY(char, PATH_MAX
+1);
1997 char *resolved_path
= realpath(path
, result
);
1998 if (!resolved_path
) {
2001 /* SMB_ASSERT(result == resolved_path) ? */
2002 result
= resolved_path
;
2006 END_PROFILE(syscall_realpath
);
2010 static NTSTATUS
vfswrap_notify_watch(vfs_handle_struct
*vfs_handle
,
2011 struct sys_notify_context
*ctx
,
2014 uint32_t *subdir_filter
,
2015 void (*callback
)(struct sys_notify_context
*ctx
,
2017 struct notify_event
*ev
),
2018 void *private_data
, void *handle
)
2021 * So far inotify is the only supported default notify mechanism. If
2022 * another platform like the the BSD's or a proprietary Unix comes
2023 * along and wants another default, we can play the same trick we
2024 * played with Posix ACLs.
2026 * Until that is the case, hard-code inotify here.
2029 if (lp_kernel_change_notify(vfs_handle
->conn
->params
)) {
2030 return inotify_watch(ctx
, path
, filter
, subdir_filter
,
2031 callback
, private_data
, handle
);
2035 * Do nothing, leave everything to notify_internal.c
2037 return NT_STATUS_OK
;
2040 static int vfswrap_chflags(vfs_handle_struct
*handle
, const char *path
,
2044 return chflags(path
, flags
);
2051 static struct file_id
vfswrap_file_id_create(struct vfs_handle_struct
*handle
,
2052 const SMB_STRUCT_STAT
*sbuf
)
2056 /* the ZERO_STRUCT ensures padding doesn't break using the key as a
2060 key
.devid
= sbuf
->st_ex_dev
;
2061 key
.inode
= sbuf
->st_ex_ino
;
2062 /* key.extid is unused by default. */
2067 static NTSTATUS
vfswrap_streaminfo(vfs_handle_struct
*handle
,
2068 struct files_struct
*fsp
,
2070 TALLOC_CTX
*mem_ctx
,
2071 unsigned int *pnum_streams
,
2072 struct stream_struct
**pstreams
)
2074 SMB_STRUCT_STAT sbuf
;
2075 struct stream_struct
*tmp_streams
= NULL
;
2078 if ((fsp
!= NULL
) && (fsp
->is_directory
)) {
2080 * No default streams on directories
2085 if ((fsp
!= NULL
) && (fsp
->fh
->fd
!= -1)) {
2086 ret
= SMB_VFS_FSTAT(fsp
, &sbuf
);
2089 struct smb_filename smb_fname
;
2091 ZERO_STRUCT(smb_fname
);
2092 smb_fname
.base_name
= discard_const_p(char, fname
);
2094 if (lp_posix_pathnames()) {
2095 ret
= SMB_VFS_LSTAT(handle
->conn
, &smb_fname
);
2097 ret
= SMB_VFS_STAT(handle
->conn
, &smb_fname
);
2099 sbuf
= smb_fname
.st
;
2103 return map_nt_error_from_unix(errno
);
2106 if (S_ISDIR(sbuf
.st_ex_mode
)) {
2110 tmp_streams
= talloc_realloc(mem_ctx
, *pstreams
, struct stream_struct
,
2111 (*pnum_streams
) + 1);
2112 if (tmp_streams
== NULL
) {
2113 return NT_STATUS_NO_MEMORY
;
2115 tmp_streams
[*pnum_streams
].name
= talloc_strdup(tmp_streams
, "::$DATA");
2116 if (tmp_streams
[*pnum_streams
].name
== NULL
) {
2117 return NT_STATUS_NO_MEMORY
;
2119 tmp_streams
[*pnum_streams
].size
= sbuf
.st_ex_size
;
2120 tmp_streams
[*pnum_streams
].alloc_size
= SMB_VFS_GET_ALLOC_SIZE(handle
->conn
, fsp
, &sbuf
);
2123 *pstreams
= tmp_streams
;
2125 return NT_STATUS_OK
;
2128 static int vfswrap_get_real_filename(struct vfs_handle_struct
*handle
,
2131 TALLOC_CTX
*mem_ctx
,
2135 * Don't fall back to get_real_filename so callers can differentiate
2136 * between a full directory scan and an actual case-insensitive stat.
2142 static const char *vfswrap_connectpath(struct vfs_handle_struct
*handle
,
2145 return handle
->conn
->connectpath
;
2148 static NTSTATUS
vfswrap_brl_lock_windows(struct vfs_handle_struct
*handle
,
2149 struct byte_range_lock
*br_lck
,
2150 struct lock_struct
*plock
,
2152 struct blocking_lock_record
*blr
)
2154 SMB_ASSERT(plock
->lock_flav
== WINDOWS_LOCK
);
2156 /* Note: blr is not used in the default implementation. */
2157 return brl_lock_windows_default(br_lck
, plock
, blocking_lock
);
2160 static bool vfswrap_brl_unlock_windows(struct vfs_handle_struct
*handle
,
2161 struct messaging_context
*msg_ctx
,
2162 struct byte_range_lock
*br_lck
,
2163 const struct lock_struct
*plock
)
2165 SMB_ASSERT(plock
->lock_flav
== WINDOWS_LOCK
);
2167 return brl_unlock_windows_default(msg_ctx
, br_lck
, plock
);
2170 static bool vfswrap_brl_cancel_windows(struct vfs_handle_struct
*handle
,
2171 struct byte_range_lock
*br_lck
,
2172 struct lock_struct
*plock
,
2173 struct blocking_lock_record
*blr
)
2175 SMB_ASSERT(plock
->lock_flav
== WINDOWS_LOCK
);
2177 /* Note: blr is not used in the default implementation. */
2178 return brl_lock_cancel_default(br_lck
, plock
);
2181 static bool vfswrap_strict_lock(struct vfs_handle_struct
*handle
,
2183 struct lock_struct
*plock
)
2185 SMB_ASSERT(plock
->lock_type
== READ_LOCK
||
2186 plock
->lock_type
== WRITE_LOCK
);
2188 return strict_lock_default(fsp
, plock
);
2191 static void vfswrap_strict_unlock(struct vfs_handle_struct
*handle
,
2193 struct lock_struct
*plock
)
2195 SMB_ASSERT(plock
->lock_type
== READ_LOCK
||
2196 plock
->lock_type
== WRITE_LOCK
);
2198 strict_unlock_default(fsp
, plock
);
2201 /* NT ACL operations. */
2203 static NTSTATUS
vfswrap_fget_nt_acl(vfs_handle_struct
*handle
,
2205 uint32 security_info
,
2206 TALLOC_CTX
*mem_ctx
,
2207 struct security_descriptor
**ppdesc
)
2211 START_PROFILE(fget_nt_acl
);
2212 result
= posix_fget_nt_acl(fsp
, security_info
,
2214 END_PROFILE(fget_nt_acl
);
2218 static NTSTATUS
vfswrap_get_nt_acl(vfs_handle_struct
*handle
,
2220 uint32 security_info
,
2221 TALLOC_CTX
*mem_ctx
,
2222 struct security_descriptor
**ppdesc
)
2226 START_PROFILE(get_nt_acl
);
2227 result
= posix_get_nt_acl(handle
->conn
, name
, security_info
,
2229 END_PROFILE(get_nt_acl
);
2233 static NTSTATUS
vfswrap_fset_nt_acl(vfs_handle_struct
*handle
, files_struct
*fsp
, uint32 security_info_sent
, const struct security_descriptor
*psd
)
2237 START_PROFILE(fset_nt_acl
);
2238 result
= set_nt_acl(fsp
, security_info_sent
, psd
);
2239 END_PROFILE(fset_nt_acl
);
2243 static NTSTATUS
vfswrap_audit_file(struct vfs_handle_struct
*handle
,
2244 struct smb_filename
*file
,
2245 struct security_acl
*sacl
,
2246 uint32_t access_requested
,
2247 uint32_t access_denied
)
2249 return NT_STATUS_OK
; /* Nothing to do here ... */
2252 static int vfswrap_chmod_acl(vfs_handle_struct
*handle
, const char *name
, mode_t mode
)
2260 START_PROFILE(chmod_acl
);
2261 result
= chmod_acl(handle
->conn
, name
, mode
);
2262 END_PROFILE(chmod_acl
);
2267 static int vfswrap_fchmod_acl(vfs_handle_struct
*handle
, files_struct
*fsp
, mode_t mode
)
2275 START_PROFILE(fchmod_acl
);
2276 result
= fchmod_acl(fsp
, mode
);
2277 END_PROFILE(fchmod_acl
);
2282 static SMB_ACL_T
vfswrap_sys_acl_get_file(vfs_handle_struct
*handle
,
2284 SMB_ACL_TYPE_T type
,
2285 TALLOC_CTX
*mem_ctx
)
2287 return sys_acl_get_file(handle
, path_p
, type
, mem_ctx
);
2290 static SMB_ACL_T
vfswrap_sys_acl_get_fd(vfs_handle_struct
*handle
,
2292 TALLOC_CTX
*mem_ctx
)
2294 return sys_acl_get_fd(handle
, fsp
, mem_ctx
);
2297 static int vfswrap_sys_acl_set_file(vfs_handle_struct
*handle
, const char *name
, SMB_ACL_TYPE_T acltype
, SMB_ACL_T theacl
)
2299 return sys_acl_set_file(handle
, name
, acltype
, theacl
);
2302 static int vfswrap_sys_acl_set_fd(vfs_handle_struct
*handle
, files_struct
*fsp
, SMB_ACL_T theacl
)
2304 return sys_acl_set_fd(handle
, fsp
, theacl
);
2307 static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct
*handle
, const char *path
)
2309 return sys_acl_delete_def_file(handle
, path
);
2312 /****************************************************************
2313 Extended attribute operations.
2314 *****************************************************************/
2316 static ssize_t
vfswrap_getxattr(struct vfs_handle_struct
*handle
,const char *path
, const char *name
, void *value
, size_t size
)
2318 return getxattr(path
, name
, value
, size
);
2321 static ssize_t
vfswrap_fgetxattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, const char *name
, void *value
, size_t size
)
2323 return fgetxattr(fsp
->fh
->fd
, name
, value
, size
);
2326 static ssize_t
vfswrap_listxattr(struct vfs_handle_struct
*handle
, const char *path
, char *list
, size_t size
)
2328 return listxattr(path
, list
, size
);
2331 static ssize_t
vfswrap_flistxattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, char *list
, size_t size
)
2333 return flistxattr(fsp
->fh
->fd
, list
, size
);
2336 static int vfswrap_removexattr(struct vfs_handle_struct
*handle
, const char *path
, const char *name
)
2338 return removexattr(path
, name
);
2341 static int vfswrap_fremovexattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, const char *name
)
2343 return fremovexattr(fsp
->fh
->fd
, name
);
2346 static int vfswrap_setxattr(struct vfs_handle_struct
*handle
, const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
2348 return setxattr(path
, name
, value
, size
, flags
);
2351 static int vfswrap_fsetxattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, const char *name
, const void *value
, size_t size
, int flags
)
2353 return fsetxattr(fsp
->fh
->fd
, name
, value
, size
, flags
);
2356 static bool vfswrap_aio_force(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
)
2361 static bool vfswrap_is_offline(struct vfs_handle_struct
*handle
,
2362 const struct smb_filename
*fname
,
2363 SMB_STRUCT_STAT
*sbuf
)
2367 bool offline
= false;
2369 if (ISDOT(fname
->base_name
) || ISDOTDOT(fname
->base_name
)) {
2373 if (!lp_dmapi_support(SNUM(handle
->conn
)) || !dmapi_have_session()) {
2374 #if defined(ENOTSUP)
2380 status
= get_full_smb_filename(talloc_tos(), fname
, &path
);
2381 if (!NT_STATUS_IS_OK(status
)) {
2382 errno
= map_errno_from_nt_status(status
);
2386 offline
= (dmapi_file_flags(path
) & FILE_ATTRIBUTE_OFFLINE
) != 0;
2393 static int vfswrap_set_offline(struct vfs_handle_struct
*handle
,
2394 const struct smb_filename
*fname
)
2396 /* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */
2397 #if defined(ENOTSUP)
2403 static NTSTATUS
vfswrap_durable_cookie(struct vfs_handle_struct
*handle
,
2404 struct files_struct
*fsp
,
2405 TALLOC_CTX
*mem_ctx
,
2408 return vfs_default_durable_cookie(fsp
, mem_ctx
, cookie
);
2411 static NTSTATUS
vfswrap_durable_disconnect(struct vfs_handle_struct
*handle
,
2412 struct files_struct
*fsp
,
2413 const DATA_BLOB old_cookie
,
2414 TALLOC_CTX
*mem_ctx
,
2415 DATA_BLOB
*new_cookie
)
2417 return vfs_default_durable_disconnect(fsp
, old_cookie
, mem_ctx
,
2421 static NTSTATUS
vfswrap_durable_reconnect(struct vfs_handle_struct
*handle
,
2422 struct smb_request
*smb1req
,
2423 struct smbXsrv_open
*op
,
2424 const DATA_BLOB old_cookie
,
2425 TALLOC_CTX
*mem_ctx
,
2426 struct files_struct
**fsp
,
2427 DATA_BLOB
*new_cookie
)
2429 return vfs_default_durable_reconnect(handle
->conn
, smb1req
, op
,
2430 old_cookie
, mem_ctx
,
2434 static struct vfs_fn_pointers vfs_default_fns
= {
2435 /* Disk operations */
2437 .connect_fn
= vfswrap_connect
,
2438 .disconnect_fn
= vfswrap_disconnect
,
2439 .disk_free_fn
= vfswrap_disk_free
,
2440 .get_quota_fn
= vfswrap_get_quota
,
2441 .set_quota_fn
= vfswrap_set_quota
,
2442 .get_shadow_copy_data_fn
= vfswrap_get_shadow_copy_data
,
2443 .statvfs_fn
= vfswrap_statvfs
,
2444 .fs_capabilities_fn
= vfswrap_fs_capabilities
,
2445 .get_dfs_referrals_fn
= vfswrap_get_dfs_referrals
,
2447 /* Directory operations */
2449 .opendir_fn
= vfswrap_opendir
,
2450 .fdopendir_fn
= vfswrap_fdopendir
,
2451 .readdir_fn
= vfswrap_readdir
,
2452 .seekdir_fn
= vfswrap_seekdir
,
2453 .telldir_fn
= vfswrap_telldir
,
2454 .rewind_dir_fn
= vfswrap_rewinddir
,
2455 .mkdir_fn
= vfswrap_mkdir
,
2456 .rmdir_fn
= vfswrap_rmdir
,
2457 .closedir_fn
= vfswrap_closedir
,
2458 .init_search_op_fn
= vfswrap_init_search_op
,
2460 /* File operations */
2462 .open_fn
= vfswrap_open
,
2463 .create_file_fn
= vfswrap_create_file
,
2464 .close_fn
= vfswrap_close
,
2465 .read_fn
= vfswrap_read
,
2466 .pread_fn
= vfswrap_pread
,
2467 .pread_send_fn
= vfswrap_pread_send
,
2468 .pread_recv_fn
= vfswrap_asys_ssize_t_recv
,
2469 .write_fn
= vfswrap_write
,
2470 .pwrite_fn
= vfswrap_pwrite
,
2471 .pwrite_send_fn
= vfswrap_pwrite_send
,
2472 .pwrite_recv_fn
= vfswrap_asys_ssize_t_recv
,
2473 .lseek_fn
= vfswrap_lseek
,
2474 .sendfile_fn
= vfswrap_sendfile
,
2475 .recvfile_fn
= vfswrap_recvfile
,
2476 .rename_fn
= vfswrap_rename
,
2477 .fsync_fn
= vfswrap_fsync
,
2478 .fsync_send_fn
= vfswrap_fsync_send
,
2479 .fsync_recv_fn
= vfswrap_asys_int_recv
,
2480 .stat_fn
= vfswrap_stat
,
2481 .fstat_fn
= vfswrap_fstat
,
2482 .lstat_fn
= vfswrap_lstat
,
2483 .get_alloc_size_fn
= vfswrap_get_alloc_size
,
2484 .unlink_fn
= vfswrap_unlink
,
2485 .chmod_fn
= vfswrap_chmod
,
2486 .fchmod_fn
= vfswrap_fchmod
,
2487 .chown_fn
= vfswrap_chown
,
2488 .fchown_fn
= vfswrap_fchown
,
2489 .lchown_fn
= vfswrap_lchown
,
2490 .chdir_fn
= vfswrap_chdir
,
2491 .getwd_fn
= vfswrap_getwd
,
2492 .ntimes_fn
= vfswrap_ntimes
,
2493 .ftruncate_fn
= vfswrap_ftruncate
,
2494 .fallocate_fn
= vfswrap_fallocate
,
2495 .lock_fn
= vfswrap_lock
,
2496 .kernel_flock_fn
= vfswrap_kernel_flock
,
2497 .linux_setlease_fn
= vfswrap_linux_setlease
,
2498 .getlock_fn
= vfswrap_getlock
,
2499 .symlink_fn
= vfswrap_symlink
,
2500 .readlink_fn
= vfswrap_readlink
,
2501 .link_fn
= vfswrap_link
,
2502 .mknod_fn
= vfswrap_mknod
,
2503 .realpath_fn
= vfswrap_realpath
,
2504 .notify_watch_fn
= vfswrap_notify_watch
,
2505 .chflags_fn
= vfswrap_chflags
,
2506 .file_id_create_fn
= vfswrap_file_id_create
,
2507 .streaminfo_fn
= vfswrap_streaminfo
,
2508 .get_real_filename_fn
= vfswrap_get_real_filename
,
2509 .connectpath_fn
= vfswrap_connectpath
,
2510 .brl_lock_windows_fn
= vfswrap_brl_lock_windows
,
2511 .brl_unlock_windows_fn
= vfswrap_brl_unlock_windows
,
2512 .brl_cancel_windows_fn
= vfswrap_brl_cancel_windows
,
2513 .strict_lock_fn
= vfswrap_strict_lock
,
2514 .strict_unlock_fn
= vfswrap_strict_unlock
,
2515 .translate_name_fn
= vfswrap_translate_name
,
2516 .fsctl_fn
= vfswrap_fsctl
,
2517 .copy_chunk_send_fn
= vfswrap_copy_chunk_send
,
2518 .copy_chunk_recv_fn
= vfswrap_copy_chunk_recv
,
2520 /* NT ACL operations. */
2522 .fget_nt_acl_fn
= vfswrap_fget_nt_acl
,
2523 .get_nt_acl_fn
= vfswrap_get_nt_acl
,
2524 .fset_nt_acl_fn
= vfswrap_fset_nt_acl
,
2525 .audit_file_fn
= vfswrap_audit_file
,
2527 /* POSIX ACL operations. */
2529 .chmod_acl_fn
= vfswrap_chmod_acl
,
2530 .fchmod_acl_fn
= vfswrap_fchmod_acl
,
2532 .sys_acl_get_file_fn
= vfswrap_sys_acl_get_file
,
2533 .sys_acl_get_fd_fn
= vfswrap_sys_acl_get_fd
,
2534 .sys_acl_blob_get_file_fn
= posix_sys_acl_blob_get_file
,
2535 .sys_acl_blob_get_fd_fn
= posix_sys_acl_blob_get_fd
,
2536 .sys_acl_set_file_fn
= vfswrap_sys_acl_set_file
,
2537 .sys_acl_set_fd_fn
= vfswrap_sys_acl_set_fd
,
2538 .sys_acl_delete_def_file_fn
= vfswrap_sys_acl_delete_def_file
,
2540 /* EA operations. */
2541 .getxattr_fn
= vfswrap_getxattr
,
2542 .fgetxattr_fn
= vfswrap_fgetxattr
,
2543 .listxattr_fn
= vfswrap_listxattr
,
2544 .flistxattr_fn
= vfswrap_flistxattr
,
2545 .removexattr_fn
= vfswrap_removexattr
,
2546 .fremovexattr_fn
= vfswrap_fremovexattr
,
2547 .setxattr_fn
= vfswrap_setxattr
,
2548 .fsetxattr_fn
= vfswrap_fsetxattr
,
2550 /* aio operations */
2551 .aio_force_fn
= vfswrap_aio_force
,
2553 /* offline operations */
2554 .is_offline_fn
= vfswrap_is_offline
,
2555 .set_offline_fn
= vfswrap_set_offline
,
2557 /* durable handle operations */
2558 .durable_cookie_fn
= vfswrap_durable_cookie
,
2559 .durable_disconnect_fn
= vfswrap_durable_disconnect
,
2560 .durable_reconnect_fn
= vfswrap_durable_reconnect
,
2563 NTSTATUS
vfs_default_init(void);
2564 NTSTATUS
vfs_default_init(void)
2566 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION
,
2567 DEFAULT_VFS_MODULE_NAME
, &vfs_default_fns
);