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"
34 #define DBGC_CLASS DBGC_VFS
36 /* Check for NULL pointer parameters in vfswrap_* functions */
38 /* We don't want to have NULL function pointers lying around. Someone
39 is sure to try and execute them. These stubs are used to prevent
42 static int vfswrap_connect(vfs_handle_struct
*handle
, const char *service
, const char *user
)
44 return 0; /* Return >= 0 for success */
47 static void vfswrap_disconnect(vfs_handle_struct
*handle
)
53 static uint64_t vfswrap_disk_free(vfs_handle_struct
*handle
, const char *path
, bool small_query
, uint64_t *bsize
,
54 uint64_t *dfree
, uint64_t *dsize
)
58 result
= sys_disk_free(handle
->conn
, path
, small_query
, bsize
, dfree
, dsize
);
62 static int vfswrap_get_quota(struct vfs_handle_struct
*handle
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*qt
)
64 #ifdef HAVE_SYS_QUOTAS
67 START_PROFILE(syscall_get_quota
);
68 result
= sys_get_quota(handle
->conn
->connectpath
, qtype
, id
, qt
);
69 END_PROFILE(syscall_get_quota
);
77 static int vfswrap_set_quota(struct vfs_handle_struct
*handle
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*qt
)
79 #ifdef HAVE_SYS_QUOTAS
82 START_PROFILE(syscall_set_quota
);
83 result
= sys_set_quota(handle
->conn
->connectpath
, qtype
, id
, qt
);
84 END_PROFILE(syscall_set_quota
);
92 static int vfswrap_get_shadow_copy_data(struct vfs_handle_struct
*handle
,
93 struct files_struct
*fsp
,
94 struct shadow_copy_data
*shadow_copy_data
,
98 return -1; /* Not implemented. */
101 static int vfswrap_statvfs(struct vfs_handle_struct
*handle
, const char *path
, vfs_statvfs_struct
*statbuf
)
103 return sys_statvfs(path
, statbuf
);
106 static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct
*handle
,
107 enum timestamp_set_resolution
*p_ts_res
)
109 connection_struct
*conn
= handle
->conn
;
110 uint32_t caps
= FILE_CASE_SENSITIVE_SEARCH
| FILE_CASE_PRESERVED_NAMES
;
111 struct smb_filename
*smb_fname_cpath
= NULL
;
112 struct vfs_statvfs_struct statbuf
;
116 ZERO_STRUCT(statbuf
);
117 ret
= sys_statvfs(conn
->connectpath
, &statbuf
);
119 caps
= statbuf
.FsCapabilities
;
122 *p_ts_res
= TIMESTAMP_SET_SECONDS
;
124 /* Work out what timestamp resolution we can
125 * use when setting a timestamp. */
127 status
= create_synthetic_smb_fname(talloc_tos(),
132 if (!NT_STATUS_IS_OK(status
)) {
136 ret
= SMB_VFS_STAT(conn
, smb_fname_cpath
);
138 TALLOC_FREE(smb_fname_cpath
);
142 if (smb_fname_cpath
->st
.st_ex_mtime
.tv_nsec
||
143 smb_fname_cpath
->st
.st_ex_atime
.tv_nsec
||
144 smb_fname_cpath
->st
.st_ex_ctime
.tv_nsec
) {
145 /* If any of the normal UNIX directory timestamps
146 * have a non-zero tv_nsec component assume
147 * we might be able to set sub-second timestamps.
148 * See what filetime set primitives we have.
150 #if defined(HAVE_UTIMENSAT)
151 *p_ts_res
= TIMESTAMP_SET_NT_OR_BETTER
;
152 #elif defined(HAVE_UTIMES)
153 /* utimes allows msec timestamps to be set. */
154 *p_ts_res
= TIMESTAMP_SET_MSEC
;
155 #elif defined(HAVE_UTIME)
156 /* utime only allows sec timestamps to be set. */
157 *p_ts_res
= TIMESTAMP_SET_SECONDS
;
160 DEBUG(10,("vfswrap_fs_capabilities: timestamp "
162 "available on share %s, directory %s\n",
163 *p_ts_res
== TIMESTAMP_SET_MSEC
? "msec" : "sec",
164 lp_servicename(conn
->params
->service
),
165 conn
->connectpath
));
167 TALLOC_FREE(smb_fname_cpath
);
171 static NTSTATUS
vfswrap_get_dfs_referrals(struct vfs_handle_struct
*handle
,
172 struct dfs_GetDFSReferral
*r
)
174 struct junction_map
*junction
= NULL
;
176 bool self_referral
= false;
177 char *pathnamep
= NULL
;
178 char *local_dfs_path
= NULL
;
181 uint16_t max_referral_level
= r
->in
.req
.max_referral_level
;
184 NDR_PRINT_IN_DEBUG(dfs_GetDFSReferral
, r
);
187 /* get the junction entry */
188 if (r
->in
.req
.servername
== NULL
) {
189 return NT_STATUS_NOT_FOUND
;
193 * Trim pathname sent by client so it begins with only one backslash.
194 * Two backslashes confuse some dfs clients
197 local_dfs_path
= talloc_strdup(r
, r
->in
.req
.servername
);
198 if (local_dfs_path
== NULL
) {
199 return NT_STATUS_NO_MEMORY
;
201 pathnamep
= local_dfs_path
;
202 while (IS_DIRECTORY_SEP(pathnamep
[0]) &&
203 IS_DIRECTORY_SEP(pathnamep
[1])) {
207 junction
= talloc_zero(r
, struct junction_map
);
208 if (junction
== NULL
) {
209 return NT_STATUS_NO_MEMORY
;
212 /* The following call can change cwd. */
213 status
= get_referred_path(r
, pathnamep
,
214 !handle
->conn
->sconn
->using_smb2
,
215 junction
, &consumedcnt
, &self_referral
);
216 if (!NT_STATUS_IS_OK(status
)) {
217 vfs_ChDir(handle
->conn
, handle
->conn
->connectpath
);
220 vfs_ChDir(handle
->conn
, handle
->conn
->connectpath
);
222 if (!self_referral
) {
223 pathnamep
[consumedcnt
] = '\0';
226 dbgtext("setup_dfs_referral: Path %s to "
227 "alternate path(s):",
229 for (i
=0; i
< junction
->referral_count
; i
++) {
231 junction
->referral_list
[i
].alternate_path
);
237 if (r
->in
.req
.max_referral_level
<= 2) {
238 max_referral_level
= 2;
240 if (r
->in
.req
.max_referral_level
>= 3) {
241 max_referral_level
= 3;
244 r
->out
.resp
= talloc_zero(r
, struct dfs_referral_resp
);
245 if (r
->out
.resp
== NULL
) {
246 return NT_STATUS_NO_MEMORY
;
249 r
->out
.resp
->path_consumed
= strlen_m(pathnamep
) * 2;
250 r
->out
.resp
->nb_referrals
= junction
->referral_count
;
252 r
->out
.resp
->header_flags
= DFS_HEADER_FLAG_STORAGE_SVR
;
254 r
->out
.resp
->header_flags
|= DFS_HEADER_FLAG_REFERAL_SVR
;
257 r
->out
.resp
->referral_entries
= talloc_zero_array(r
,
258 struct dfs_referral_type
,
259 r
->out
.resp
->nb_referrals
);
260 if (r
->out
.resp
->referral_entries
== NULL
) {
261 return NT_STATUS_NO_MEMORY
;
264 switch (max_referral_level
) {
266 for(i
=0; i
< junction
->referral_count
; i
++) {
267 struct referral
*ref
= &junction
->referral_list
[i
];
268 TALLOC_CTX
*mem_ctx
= r
->out
.resp
->referral_entries
;
269 struct dfs_referral_type
*t
=
270 &r
->out
.resp
->referral_entries
[i
];
271 struct dfs_referral_v2
*v2
= &t
->referral
.v2
;
274 v2
->size
= VERSION2_REFERRAL_SIZE
;
276 v2
->server_type
= DFS_SERVER_ROOT
;
278 v2
->server_type
= DFS_SERVER_NON_ROOT
;
281 v2
->proximity
= ref
->proximity
;
283 v2
->DFS_path
= talloc_strdup(mem_ctx
, pathnamep
);
284 if (v2
->DFS_path
== NULL
) {
285 return NT_STATUS_NO_MEMORY
;
287 v2
->DFS_alt_path
= talloc_strdup(mem_ctx
, pathnamep
);
288 if (v2
->DFS_alt_path
== NULL
) {
289 return NT_STATUS_NO_MEMORY
;
291 v2
->netw_address
= talloc_strdup(mem_ctx
,
292 ref
->alternate_path
);
293 if (v2
->netw_address
== NULL
) {
294 return NT_STATUS_NO_MEMORY
;
300 for(i
=0; i
< junction
->referral_count
; i
++) {
301 struct referral
*ref
= &junction
->referral_list
[i
];
302 TALLOC_CTX
*mem_ctx
= r
->out
.resp
->referral_entries
;
303 struct dfs_referral_type
*t
=
304 &r
->out
.resp
->referral_entries
[i
];
305 struct dfs_referral_v3
*v3
= &t
->referral
.v3
;
306 struct dfs_normal_referral
*r1
= &v3
->referrals
.r1
;
309 v3
->size
= VERSION3_REFERRAL_SIZE
;
311 v3
->server_type
= DFS_SERVER_ROOT
;
313 v3
->server_type
= DFS_SERVER_NON_ROOT
;
317 r1
->DFS_path
= talloc_strdup(mem_ctx
, pathnamep
);
318 if (r1
->DFS_path
== NULL
) {
319 return NT_STATUS_NO_MEMORY
;
321 r1
->DFS_alt_path
= talloc_strdup(mem_ctx
, pathnamep
);
322 if (r1
->DFS_alt_path
== NULL
) {
323 return NT_STATUS_NO_MEMORY
;
325 r1
->netw_address
= talloc_strdup(mem_ctx
,
326 ref
->alternate_path
);
327 if (r1
->netw_address
== NULL
) {
328 return NT_STATUS_NO_MEMORY
;
333 DEBUG(0,("setup_dfs_referral: Invalid dfs referral "
335 max_referral_level
));
336 return NT_STATUS_INVALID_LEVEL
;
340 NDR_PRINT_OUT_DEBUG(dfs_GetDFSReferral
, r
);
346 /* Directory operations */
348 static DIR *vfswrap_opendir(vfs_handle_struct
*handle
, const char *fname
, const char *mask
, uint32 attr
)
352 START_PROFILE(syscall_opendir
);
353 result
= opendir(fname
);
354 END_PROFILE(syscall_opendir
);
358 static DIR *vfswrap_fdopendir(vfs_handle_struct
*handle
,
365 START_PROFILE(syscall_fdopendir
);
366 result
= sys_fdopendir(fsp
->fh
->fd
);
367 END_PROFILE(syscall_fdopendir
);
372 static struct dirent
*vfswrap_readdir(vfs_handle_struct
*handle
,
374 SMB_STRUCT_STAT
*sbuf
)
376 struct dirent
*result
;
378 START_PROFILE(syscall_readdir
);
379 result
= readdir(dirp
);
380 /* Default Posix readdir() does not give us stat info.
381 * Set to invalid to indicate we didn't return this info. */
383 SET_STAT_INVALID(*sbuf
);
384 END_PROFILE(syscall_readdir
);
388 static void vfswrap_seekdir(vfs_handle_struct
*handle
, DIR *dirp
, long offset
)
390 START_PROFILE(syscall_seekdir
);
391 seekdir(dirp
, offset
);
392 END_PROFILE(syscall_seekdir
);
395 static long vfswrap_telldir(vfs_handle_struct
*handle
, DIR *dirp
)
398 START_PROFILE(syscall_telldir
);
399 result
= telldir(dirp
);
400 END_PROFILE(syscall_telldir
);
404 static void vfswrap_rewinddir(vfs_handle_struct
*handle
, DIR *dirp
)
406 START_PROFILE(syscall_rewinddir
);
408 END_PROFILE(syscall_rewinddir
);
411 static int vfswrap_mkdir(vfs_handle_struct
*handle
, const char *path
, mode_t mode
)
414 bool has_dacl
= False
;
417 START_PROFILE(syscall_mkdir
);
419 if (lp_inherit_acls(SNUM(handle
->conn
))
420 && parent_dirname(talloc_tos(), path
, &parent
, NULL
)
421 && (has_dacl
= directory_has_default_acl(handle
->conn
, parent
)))
422 mode
= (0777 & lp_dir_mask(SNUM(handle
->conn
)));
426 result
= mkdir(path
, mode
);
428 if (result
== 0 && !has_dacl
) {
430 * We need to do this as the default behavior of POSIX ACLs
431 * is to set the mask to be the requested group permission
432 * bits, not the group permission bits to be the requested
433 * group permission bits. This is not what we want, as it will
434 * mess up any inherited ACL bits that were set. JRA.
436 int saved_errno
= errno
; /* We may get ENOSYS */
437 if ((SMB_VFS_CHMOD_ACL(handle
->conn
, path
, mode
) == -1) && (errno
== ENOSYS
))
441 END_PROFILE(syscall_mkdir
);
445 static int vfswrap_rmdir(vfs_handle_struct
*handle
, const char *path
)
449 START_PROFILE(syscall_rmdir
);
450 result
= rmdir(path
);
451 END_PROFILE(syscall_rmdir
);
455 static int vfswrap_closedir(vfs_handle_struct
*handle
, DIR *dirp
)
459 START_PROFILE(syscall_closedir
);
460 result
= closedir(dirp
);
461 END_PROFILE(syscall_closedir
);
465 static void vfswrap_init_search_op(vfs_handle_struct
*handle
,
468 /* Default behavior is a NOOP */
471 /* File operations */
473 static int vfswrap_open(vfs_handle_struct
*handle
,
474 struct smb_filename
*smb_fname
,
475 files_struct
*fsp
, int flags
, mode_t mode
)
479 START_PROFILE(syscall_open
);
481 if (smb_fname
->stream_name
) {
486 result
= open(smb_fname
->base_name
, flags
, mode
);
488 END_PROFILE(syscall_open
);
492 static NTSTATUS
vfswrap_create_file(vfs_handle_struct
*handle
,
493 struct smb_request
*req
,
494 uint16_t root_dir_fid
,
495 struct smb_filename
*smb_fname
,
496 uint32_t access_mask
,
497 uint32_t share_access
,
498 uint32_t create_disposition
,
499 uint32_t create_options
,
500 uint32_t file_attributes
,
501 uint32_t oplock_request
,
502 uint64_t allocation_size
,
503 uint32_t private_flags
,
504 struct security_descriptor
*sd
,
505 struct ea_list
*ea_list
,
506 files_struct
**result
,
509 return create_file_default(handle
->conn
, req
, root_dir_fid
, smb_fname
,
510 access_mask
, share_access
,
511 create_disposition
, create_options
,
512 file_attributes
, oplock_request
,
513 allocation_size
, private_flags
,
518 static int vfswrap_close(vfs_handle_struct
*handle
, files_struct
*fsp
)
522 START_PROFILE(syscall_close
);
523 result
= fd_close_posix(fsp
);
524 END_PROFILE(syscall_close
);
528 static ssize_t
vfswrap_read(vfs_handle_struct
*handle
, files_struct
*fsp
, void *data
, size_t n
)
532 START_PROFILE_BYTES(syscall_read
, n
);
533 result
= sys_read(fsp
->fh
->fd
, data
, n
);
534 END_PROFILE(syscall_read
);
538 static ssize_t
vfswrap_pread(vfs_handle_struct
*handle
, files_struct
*fsp
, void *data
,
539 size_t n
, off_t offset
)
543 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
544 START_PROFILE_BYTES(syscall_pread
, n
);
545 result
= sys_pread(fsp
->fh
->fd
, data
, n
, offset
);
546 END_PROFILE(syscall_pread
);
548 if (result
== -1 && errno
== ESPIPE
) {
549 /* Maintain the fiction that pipes can be seeked (sought?) on. */
550 result
= SMB_VFS_READ(fsp
, data
, n
);
554 #else /* HAVE_PREAD */
558 curr
= SMB_VFS_LSEEK(fsp
, 0, SEEK_CUR
);
559 if (curr
== -1 && errno
== ESPIPE
) {
560 /* Maintain the fiction that pipes can be seeked (sought?) on. */
561 result
= SMB_VFS_READ(fsp
, data
, n
);
566 if (SMB_VFS_LSEEK(fsp
, offset
, SEEK_SET
) == -1) {
571 result
= SMB_VFS_READ(fsp
, data
, n
);
574 SMB_VFS_LSEEK(fsp
, curr
, SEEK_SET
);
577 #endif /* HAVE_PREAD */
582 static ssize_t
vfswrap_write(vfs_handle_struct
*handle
, files_struct
*fsp
, const void *data
, size_t n
)
586 START_PROFILE_BYTES(syscall_write
, n
);
587 result
= sys_write(fsp
->fh
->fd
, data
, n
);
588 END_PROFILE(syscall_write
);
592 static ssize_t
vfswrap_pwrite(vfs_handle_struct
*handle
, files_struct
*fsp
, const void *data
,
593 size_t n
, off_t offset
)
597 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
598 START_PROFILE_BYTES(syscall_pwrite
, n
);
599 result
= sys_pwrite(fsp
->fh
->fd
, data
, n
, offset
);
600 END_PROFILE(syscall_pwrite
);
602 if (result
== -1 && errno
== ESPIPE
) {
603 /* Maintain the fiction that pipes can be sought on. */
604 result
= SMB_VFS_WRITE(fsp
, data
, n
);
607 #else /* HAVE_PWRITE */
611 curr
= SMB_VFS_LSEEK(fsp
, 0, SEEK_CUR
);
616 if (SMB_VFS_LSEEK(fsp
, offset
, SEEK_SET
) == -1) {
620 result
= SMB_VFS_WRITE(fsp
, data
, n
);
623 SMB_VFS_LSEEK(fsp
, curr
, SEEK_SET
);
626 #endif /* HAVE_PWRITE */
631 static off_t
vfswrap_lseek(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t offset
, int whence
)
635 START_PROFILE(syscall_lseek
);
637 /* Cope with 'stat' file opens. */
638 if (fsp
->fh
->fd
!= -1)
639 result
= lseek(fsp
->fh
->fd
, offset
, whence
);
642 * We want to maintain the fiction that we can seek
643 * on a fifo for file system purposes. This allows
644 * people to set up UNIX fifo's that feed data to Windows
648 if((result
== -1) && (errno
== ESPIPE
)) {
653 END_PROFILE(syscall_lseek
);
657 static ssize_t
vfswrap_sendfile(vfs_handle_struct
*handle
, int tofd
, files_struct
*fromfsp
, const DATA_BLOB
*hdr
,
658 off_t offset
, size_t n
)
662 START_PROFILE_BYTES(syscall_sendfile
, n
);
663 result
= sys_sendfile(tofd
, fromfsp
->fh
->fd
, hdr
, offset
, n
);
664 END_PROFILE(syscall_sendfile
);
668 static ssize_t
vfswrap_recvfile(vfs_handle_struct
*handle
,
676 START_PROFILE_BYTES(syscall_recvfile
, n
);
677 result
= sys_recvfile(fromfd
, tofsp
->fh
->fd
, offset
, n
);
678 END_PROFILE(syscall_recvfile
);
682 static int vfswrap_rename(vfs_handle_struct
*handle
,
683 const struct smb_filename
*smb_fname_src
,
684 const struct smb_filename
*smb_fname_dst
)
688 START_PROFILE(syscall_rename
);
690 if (smb_fname_src
->stream_name
|| smb_fname_dst
->stream_name
) {
695 result
= rename(smb_fname_src
->base_name
, smb_fname_dst
->base_name
);
698 END_PROFILE(syscall_rename
);
702 static int vfswrap_fsync(vfs_handle_struct
*handle
, files_struct
*fsp
)
707 START_PROFILE(syscall_fsync
);
708 result
= fsync(fsp
->fh
->fd
);
709 END_PROFILE(syscall_fsync
);
716 static int vfswrap_stat(vfs_handle_struct
*handle
,
717 struct smb_filename
*smb_fname
)
721 START_PROFILE(syscall_stat
);
723 if (smb_fname
->stream_name
) {
728 result
= sys_stat(smb_fname
->base_name
, &smb_fname
->st
,
729 lp_fake_dir_create_times(SNUM(handle
->conn
)));
731 END_PROFILE(syscall_stat
);
735 static int vfswrap_fstat(vfs_handle_struct
*handle
, files_struct
*fsp
, SMB_STRUCT_STAT
*sbuf
)
739 START_PROFILE(syscall_fstat
);
740 result
= sys_fstat(fsp
->fh
->fd
,
741 sbuf
, lp_fake_dir_create_times(SNUM(handle
->conn
)));
742 END_PROFILE(syscall_fstat
);
746 static int vfswrap_lstat(vfs_handle_struct
*handle
,
747 struct smb_filename
*smb_fname
)
751 START_PROFILE(syscall_lstat
);
753 if (smb_fname
->stream_name
) {
758 result
= sys_lstat(smb_fname
->base_name
, &smb_fname
->st
,
759 lp_fake_dir_create_times(SNUM(handle
->conn
)));
761 END_PROFILE(syscall_lstat
);
765 static NTSTATUS
vfswrap_translate_name(struct vfs_handle_struct
*handle
,
767 enum vfs_translate_direction direction
,
771 return NT_STATUS_NONE_MAPPED
;
775 * Implement the default fsctl operation.
777 static bool vfswrap_logged_ioctl_message
= false;
779 static NTSTATUS
vfswrap_fsctl(struct vfs_handle_struct
*handle
,
780 struct files_struct
*fsp
,
783 uint16_t req_flags
, /* Needed for UNICODE ... */
784 const uint8_t *_in_data
,
787 uint32_t max_out_len
,
790 const char *in_data
= (const char *)_in_data
;
791 char **out_data
= (char **)_out_data
;
794 case FSCTL_SET_SPARSE
:
796 bool set_sparse
= true;
799 if (in_len
>= 1 && in_data
[0] == 0) {
803 status
= file_set_sparse(handle
->conn
, fsp
, set_sparse
);
805 DEBUG(NT_STATUS_IS_OK(status
) ? 10 : 9,
806 ("FSCTL_SET_SPARSE: fname[%s] set[%u] - %s\n",
807 smb_fname_str_dbg(fsp
->fsp_name
), set_sparse
,
813 case FSCTL_CREATE_OR_GET_OBJECT_ID
:
815 unsigned char objid
[16];
816 char *return_data
= NULL
;
818 /* This should return the object-id on this file.
819 * I think I'll make this be the inode+dev. JRA.
822 DEBUG(10,("FSCTL_CREATE_OR_GET_OBJECT_ID: called on FID[0x%04X]\n",fsp
->fnum
));
824 *out_len
= (max_out_len
>= 64) ? 64 : max_out_len
;
825 /* Hmmm, will this cause problems if less data asked for? */
826 return_data
= talloc_array(ctx
, char, 64);
827 if (return_data
== NULL
) {
828 return NT_STATUS_NO_MEMORY
;
831 /* For backwards compatibility only store the dev/inode. */
832 push_file_id_16(return_data
, &fsp
->file_id
);
833 memcpy(return_data
+16,create_volume_objectid(fsp
->conn
,objid
),16);
834 push_file_id_16(return_data
+32, &fsp
->file_id
);
835 *out_data
= return_data
;
839 case FSCTL_GET_REPARSE_POINT
:
841 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
842 DEBUG(10, ("FSCTL_GET_REPARSE_POINT: called on FID[0x%04X] Status: NOT_IMPLEMENTED\n", fsp
->fnum
));
843 return NT_STATUS_NOT_A_REPARSE_POINT
;
846 case FSCTL_SET_REPARSE_POINT
:
848 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
849 DEBUG(10, ("FSCTL_SET_REPARSE_POINT: called on FID[0x%04X] Status: NOT_IMPLEMENTED\n", fsp
->fnum
));
850 return NT_STATUS_NOT_A_REPARSE_POINT
;
853 case FSCTL_GET_SHADOW_COPY_DATA
:
856 * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
857 * and return their volume names. If max_data_count is 16, then it is just
858 * asking for the number of volumes and length of the combined names.
860 * pdata is the data allocated by our caller, but that uses
861 * total_data_count (which is 0 in our case) rather than max_data_count.
862 * Allocate the correct amount and return the pointer to let
863 * it be deallocated when we return.
865 struct shadow_copy_data
*shadow_data
= NULL
;
867 uint32 labels_data_count
= 0;
869 char *cur_pdata
= NULL
;
871 if (max_out_len
< 16) {
872 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
874 return NT_STATUS_INVALID_PARAMETER
;
877 if (max_out_len
> 16) {
881 shadow_data
= talloc_zero(ctx
, struct shadow_copy_data
);
882 if (shadow_data
== NULL
) {
883 DEBUG(0,("TALLOC_ZERO() failed!\n"));
884 return NT_STATUS_NO_MEMORY
;
888 * Call the VFS routine to actually do the work.
890 if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp
, shadow_data
, labels
)!=0) {
891 TALLOC_FREE(shadow_data
);
892 if (errno
== ENOSYS
) {
893 DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n",
894 fsp
->conn
->connectpath
));
895 return NT_STATUS_NOT_SUPPORTED
;
897 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n",
898 fsp
->conn
->connectpath
));
899 return NT_STATUS_UNSUCCESSFUL
;
903 labels_data_count
= (shadow_data
->num_volumes
* 2 *
904 sizeof(SHADOW_COPY_LABEL
)) + 2;
909 *out_len
= 12 + labels_data_count
+ 4;
912 if (max_out_len
< *out_len
) {
913 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
914 max_out_len
, *out_len
));
915 TALLOC_FREE(shadow_data
);
916 return NT_STATUS_BUFFER_TOO_SMALL
;
919 cur_pdata
= talloc_array(ctx
, char, *out_len
);
920 if (cur_pdata
== NULL
) {
921 TALLOC_FREE(shadow_data
);
922 return NT_STATUS_NO_MEMORY
;
925 *out_data
= cur_pdata
;
927 /* num_volumes 4 bytes */
928 SIVAL(cur_pdata
, 0, shadow_data
->num_volumes
);
931 /* num_labels 4 bytes */
932 SIVAL(cur_pdata
, 4, shadow_data
->num_volumes
);
935 /* needed_data_count 4 bytes */
936 SIVAL(cur_pdata
, 8, labels_data_count
+ 4);
940 DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
941 shadow_data
->num_volumes
, fsp_str_dbg(fsp
)));
942 if (labels
&& shadow_data
->labels
) {
943 for (i
=0; i
<shadow_data
->num_volumes
; i
++) {
944 srvstr_push(cur_pdata
, req_flags
,
945 cur_pdata
, shadow_data
->labels
[i
],
946 2 * sizeof(SHADOW_COPY_LABEL
),
947 STR_UNICODE
|STR_TERMINATE
);
948 cur_pdata
+= 2 * sizeof(SHADOW_COPY_LABEL
);
949 DEBUGADD(10,("Label[%u]: '%s'\n",i
,shadow_data
->labels
[i
]));
953 TALLOC_FREE(shadow_data
);
958 case FSCTL_FIND_FILES_BY_SID
:
960 /* pretend this succeeded -
962 * we have to send back a list with all files owned by this SID
964 * but I have to check that --metze
970 DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n", fsp
->fnum
));
973 /* NT_STATUS_BUFFER_TOO_SMALL maybe? */
974 return NT_STATUS_INVALID_PARAMETER
;
977 sid_len
= MIN(in_len
- 4,SID_MAX_SIZE
);
979 /* unknown 4 bytes: this is not the length of the sid :-( */
980 /*unknown = IVAL(pdata,0);*/
982 if (!sid_parse(in_data
+ 4, sid_len
, &sid
)) {
983 return NT_STATUS_INVALID_PARAMETER
;
985 DEBUGADD(10, ("for SID: %s\n", sid_string_dbg(&sid
)));
987 if (!sid_to_uid(&sid
, &uid
)) {
988 DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
989 sid_string_dbg(&sid
),
990 (unsigned long)sid_len
));
994 /* we can take a look at the find source :-)
996 * find ./ -uid $uid -name '*' is what we need here
999 * and send 4bytes len and then NULL terminated unicode strings
1002 * but I don't know how to deal with the paged results
1003 * (maybe we can hang the result anywhere in the fsp struct)
1005 * but I don't know how to deal with the paged results
1006 * (maybe we can hang the result anywhere in the fsp struct)
1008 * we don't send all files at once
1009 * and at the next we should *not* start from the beginning,
1010 * so we have to cache the result
1015 /* this works for now... */
1016 return NT_STATUS_OK
;
1019 case FSCTL_QUERY_ALLOCATED_RANGES
:
1021 /* FIXME: This is just a dummy reply, telling that all of the
1022 * file is allocated. MKS cp needs that.
1023 * Adding the real allocated ranges via FIEMAP on Linux
1024 * and SEEK_DATA/SEEK_HOLE on Solaris is needed to make
1025 * this FSCTL correct for sparse files.
1028 uint64_t offset
, length
;
1029 char *out_data_tmp
= NULL
;
1032 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: data_count(%u) != 16 is invalid!\n",
1034 return NT_STATUS_INVALID_PARAMETER
;
1037 if (max_out_len
< 16) {
1038 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: max_out_len (%u) < 16 is invalid!\n",
1040 return NT_STATUS_INVALID_PARAMETER
;
1043 offset
= BVAL(in_data
,0);
1044 length
= BVAL(in_data
,8);
1046 if (offset
+ length
< offset
) {
1047 /* No 64-bit integer wrap. */
1048 return NT_STATUS_INVALID_PARAMETER
;
1051 /* Shouldn't this be SMB_VFS_STAT ... ? */
1052 status
= vfs_stat_fsp(fsp
);
1053 if (!NT_STATUS_IS_OK(status
)) {
1058 out_data_tmp
= talloc_array(ctx
, char, *out_len
);
1059 if (out_data_tmp
== NULL
) {
1060 DEBUG(10, ("unable to allocate memory for response\n"));
1061 return NT_STATUS_NO_MEMORY
;
1064 if (offset
> fsp
->fsp_name
->st
.st_ex_size
||
1065 fsp
->fsp_name
->st
.st_ex_size
== 0 ||
1067 memset(out_data_tmp
, 0, *out_len
);
1069 uint64_t end
= offset
+ length
;
1070 end
= MIN(end
, fsp
->fsp_name
->st
.st_ex_size
);
1071 SBVAL(out_data_tmp
, 0, 0);
1072 SBVAL(out_data_tmp
, 8, end
);
1075 *out_data
= out_data_tmp
;
1077 return NT_STATUS_OK
;
1080 case FSCTL_IS_VOLUME_DIRTY
:
1082 DEBUG(10,("FSCTL_IS_VOLUME_DIRTY: called on FID[0x%04X] "
1083 "(but not implemented)\n", fsp
->fnum
));
1085 * http://msdn.microsoft.com/en-us/library/cc232128%28PROT.10%29.aspx
1086 * says we have to respond with NT_STATUS_INVALID_PARAMETER
1088 return NT_STATUS_INVALID_PARAMETER
;
1093 * Only print once ... unfortunately there could be lots of
1094 * different FSCTLs that are called.
1096 if (!vfswrap_logged_ioctl_message
) {
1097 vfswrap_logged_ioctl_message
= true;
1098 DEBUG(2, ("%s (0x%x): Currently not implemented.\n",
1099 __func__
, function
));
1103 return NT_STATUS_NOT_SUPPORTED
;
1106 /********************************************************************
1107 Given a stat buffer return the allocated size on disk, taking into
1108 account sparse files.
1109 ********************************************************************/
1110 static uint64_t vfswrap_get_alloc_size(vfs_handle_struct
*handle
,
1111 struct files_struct
*fsp
,
1112 const SMB_STRUCT_STAT
*sbuf
)
1116 START_PROFILE(syscall_get_alloc_size
);
1118 if(S_ISDIR(sbuf
->st_ex_mode
)) {
1123 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
1124 /* The type of st_blocksize is blkcnt_t which *MUST* be
1125 signed (according to POSIX) and can be less than 64-bits.
1126 Ensure when we're converting to 64 bits wide we don't
1128 #if defined(SIZEOF_BLKCNT_T_8)
1129 result
= (uint64_t)STAT_ST_BLOCKSIZE
* (uint64_t)sbuf
->st_ex_blocks
;
1130 #elif defined(SIZEOF_BLKCNT_T_4)
1132 uint64_t bs
= ((uint64_t)sbuf
->st_ex_blocks
) & 0xFFFFFFFFLL
;
1133 result
= (uint64_t)STAT_ST_BLOCKSIZE
* bs
;
1136 #error SIZEOF_BLKCNT_T_NOT_A_SUPPORTED_VALUE
1139 result
= get_file_size_stat(sbuf
);
1142 if (fsp
&& fsp
->initial_allocation_size
)
1143 result
= MAX(result
,fsp
->initial_allocation_size
);
1145 result
= smb_roundup(handle
->conn
, result
);
1148 END_PROFILE(syscall_get_alloc_size
);
1152 static int vfswrap_unlink(vfs_handle_struct
*handle
,
1153 const struct smb_filename
*smb_fname
)
1157 START_PROFILE(syscall_unlink
);
1159 if (smb_fname
->stream_name
) {
1163 result
= unlink(smb_fname
->base_name
);
1166 END_PROFILE(syscall_unlink
);
1170 static int vfswrap_chmod(vfs_handle_struct
*handle
, const char *path
, mode_t mode
)
1174 START_PROFILE(syscall_chmod
);
1177 * We need to do this due to the fact that the default POSIX ACL
1178 * chmod modifies the ACL *mask* for the group owner, not the
1179 * group owner bits directly. JRA.
1184 int saved_errno
= errno
; /* We might get ENOSYS */
1185 if ((result
= SMB_VFS_CHMOD_ACL(handle
->conn
, path
, mode
)) == 0) {
1186 END_PROFILE(syscall_chmod
);
1189 /* Error - return the old errno. */
1190 errno
= saved_errno
;
1193 result
= chmod(path
, mode
);
1194 END_PROFILE(syscall_chmod
);
1198 static int vfswrap_fchmod(vfs_handle_struct
*handle
, files_struct
*fsp
, mode_t mode
)
1202 START_PROFILE(syscall_fchmod
);
1205 * We need to do this due to the fact that the default POSIX ACL
1206 * chmod modifies the ACL *mask* for the group owner, not the
1207 * group owner bits directly. JRA.
1211 int saved_errno
= errno
; /* We might get ENOSYS */
1212 if ((result
= SMB_VFS_FCHMOD_ACL(fsp
, mode
)) == 0) {
1213 END_PROFILE(syscall_fchmod
);
1216 /* Error - return the old errno. */
1217 errno
= saved_errno
;
1220 #if defined(HAVE_FCHMOD)
1221 result
= fchmod(fsp
->fh
->fd
, mode
);
1227 END_PROFILE(syscall_fchmod
);
1231 static int vfswrap_chown(vfs_handle_struct
*handle
, const char *path
, uid_t uid
, gid_t gid
)
1235 START_PROFILE(syscall_chown
);
1236 result
= chown(path
, uid
, gid
);
1237 END_PROFILE(syscall_chown
);
1241 static int vfswrap_fchown(vfs_handle_struct
*handle
, files_struct
*fsp
, uid_t uid
, gid_t gid
)
1246 START_PROFILE(syscall_fchown
);
1247 result
= fchown(fsp
->fh
->fd
, uid
, gid
);
1248 END_PROFILE(syscall_fchown
);
1256 static int vfswrap_lchown(vfs_handle_struct
*handle
, const char *path
, uid_t uid
, gid_t gid
)
1260 START_PROFILE(syscall_lchown
);
1261 result
= lchown(path
, uid
, gid
);
1262 END_PROFILE(syscall_lchown
);
1266 static int vfswrap_chdir(vfs_handle_struct
*handle
, const char *path
)
1270 START_PROFILE(syscall_chdir
);
1271 result
= chdir(path
);
1272 END_PROFILE(syscall_chdir
);
1276 static char *vfswrap_getwd(vfs_handle_struct
*handle
)
1280 START_PROFILE(syscall_getwd
);
1281 result
= sys_getwd();
1282 END_PROFILE(syscall_getwd
);
1286 /*********************************************************************
1287 nsec timestamp resolution call. Convert down to whatever the underlying
1288 system will support.
1289 **********************************************************************/
1291 static int vfswrap_ntimes(vfs_handle_struct
*handle
,
1292 const struct smb_filename
*smb_fname
,
1293 struct smb_file_time
*ft
)
1297 START_PROFILE(syscall_ntimes
);
1299 if (smb_fname
->stream_name
) {
1305 if (null_timespec(ft
->atime
)) {
1306 ft
->atime
= smb_fname
->st
.st_ex_atime
;
1309 if (null_timespec(ft
->mtime
)) {
1310 ft
->mtime
= smb_fname
->st
.st_ex_mtime
;
1313 if (!null_timespec(ft
->create_time
)) {
1314 set_create_timespec_ea(handle
->conn
,
1319 if ((timespec_compare(&ft
->atime
,
1320 &smb_fname
->st
.st_ex_atime
) == 0) &&
1321 (timespec_compare(&ft
->mtime
,
1322 &smb_fname
->st
.st_ex_mtime
) == 0)) {
1327 #if defined(HAVE_UTIMENSAT)
1329 struct timespec ts
[2];
1332 result
= utimensat(AT_FDCWD
, smb_fname
->base_name
, ts
, 0);
1334 result
= utimensat(AT_FDCWD
, smb_fname
->base_name
, NULL
, 0);
1336 if (!((result
== -1) && (errno
== ENOSYS
))) {
1340 #if defined(HAVE_UTIMES)
1342 struct timeval tv
[2];
1343 tv
[0] = convert_timespec_to_timeval(ft
->atime
);
1344 tv
[1] = convert_timespec_to_timeval(ft
->mtime
);
1345 result
= utimes(smb_fname
->base_name
, tv
);
1347 result
= utimes(smb_fname
->base_name
, NULL
);
1349 if (!((result
== -1) && (errno
== ENOSYS
))) {
1353 #if defined(HAVE_UTIME)
1355 struct utimbuf times
;
1356 times
.actime
= convert_timespec_to_time_t(ft
->atime
);
1357 times
.modtime
= convert_timespec_to_time_t(ft
->mtime
);
1358 result
= utime(smb_fname
->base_name
, ×
);
1360 result
= utime(smb_fname
->base_name
, NULL
);
1362 if (!((result
== -1) && (errno
== ENOSYS
))) {
1370 END_PROFILE(syscall_ntimes
);
1374 /*********************************************************************
1375 A version of ftruncate that will write the space on disk if strict
1377 **********************************************************************/
1379 static int strict_allocate_ftruncate(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t len
)
1381 off_t space_to_write
;
1382 uint64_t space_avail
;
1383 uint64_t bsize
,dfree
,dsize
;
1386 SMB_STRUCT_STAT
*pst
;
1388 status
= vfs_stat_fsp(fsp
);
1389 if (!NT_STATUS_IS_OK(status
)) {
1392 pst
= &fsp
->fsp_name
->st
;
1395 if (S_ISFIFO(pst
->st_ex_mode
))
1399 if (pst
->st_ex_size
== len
)
1402 /* Shrink - just ftruncate. */
1403 if (pst
->st_ex_size
> len
)
1404 return ftruncate(fsp
->fh
->fd
, len
);
1406 space_to_write
= len
- pst
->st_ex_size
;
1408 /* for allocation try fallocate first. This can fail on some
1409 platforms e.g. when the filesystem doesn't support it and no
1410 emulation is being done by the libc (like on AIX with JFS1). In that
1411 case we do our own emulation. fallocate implementations can
1412 return ENOTSUP or EINVAL in cases like that. */
1413 ret
= SMB_VFS_FALLOCATE(fsp
, VFS_FALLOCATE_EXTEND_SIZE
,
1414 pst
->st_ex_size
, space_to_write
);
1415 if (ret
== ENOSPC
) {
1422 DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with "
1423 "error %d. Falling back to slow manual allocation\n", ret
));
1425 /* available disk space is enough or not? */
1426 space_avail
= get_dfree_info(fsp
->conn
,
1427 fsp
->fsp_name
->base_name
, false,
1428 &bsize
,&dfree
,&dsize
);
1429 /* space_avail is 1k blocks */
1430 if (space_avail
== (uint64_t)-1 ||
1431 ((uint64_t)space_to_write
/1024 > space_avail
) ) {
1436 /* Write out the real space on disk. */
1437 ret
= vfs_slow_fallocate(fsp
, pst
->st_ex_size
, space_to_write
);
1446 static int vfswrap_ftruncate(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t len
)
1449 SMB_STRUCT_STAT
*pst
;
1453 START_PROFILE(syscall_ftruncate
);
1455 if (lp_strict_allocate(SNUM(fsp
->conn
)) && !fsp
->is_sparse
) {
1456 result
= strict_allocate_ftruncate(handle
, fsp
, len
);
1457 END_PROFILE(syscall_ftruncate
);
1461 /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
1462 ftruncate if the system supports it. Then I discovered that
1463 you can have some filesystems that support ftruncate
1464 expansion and some that don't! On Linux fat can't do
1465 ftruncate extend but ext2 can. */
1467 result
= ftruncate(fsp
->fh
->fd
, len
);
1471 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
1472 extend a file with ftruncate. Provide alternate implementation
1475 /* Do an fstat to see if the file is longer than the requested
1476 size in which case the ftruncate above should have
1477 succeeded or shorter, in which case seek to len - 1 and
1478 write 1 byte of zero */
1479 status
= vfs_stat_fsp(fsp
);
1480 if (!NT_STATUS_IS_OK(status
)) {
1483 pst
= &fsp
->fsp_name
->st
;
1486 if (S_ISFIFO(pst
->st_ex_mode
)) {
1492 if (pst
->st_ex_size
== len
) {
1497 if (pst
->st_ex_size
> len
) {
1498 /* the ftruncate should have worked */
1502 if (SMB_VFS_PWRITE(fsp
, &c
, 1, len
-1)!=1) {
1510 END_PROFILE(syscall_ftruncate
);
1514 static int vfswrap_fallocate(vfs_handle_struct
*handle
,
1516 enum vfs_fallocate_mode mode
,
1522 START_PROFILE(syscall_fallocate
);
1523 if (mode
== VFS_FALLOCATE_EXTEND_SIZE
) {
1524 result
= sys_posix_fallocate(fsp
->fh
->fd
, offset
, len
);
1525 } else if (mode
== VFS_FALLOCATE_KEEP_SIZE
) {
1526 result
= sys_fallocate(fsp
->fh
->fd
, mode
, offset
, len
);
1531 END_PROFILE(syscall_fallocate
);
1535 static bool vfswrap_lock(vfs_handle_struct
*handle
, files_struct
*fsp
, int op
, off_t offset
, off_t count
, int type
)
1539 START_PROFILE(syscall_fcntl_lock
);
1540 result
= fcntl_lock(fsp
->fh
->fd
, op
, offset
, count
, type
);
1541 END_PROFILE(syscall_fcntl_lock
);
1545 static int vfswrap_kernel_flock(vfs_handle_struct
*handle
, files_struct
*fsp
,
1546 uint32 share_mode
, uint32 access_mask
)
1548 START_PROFILE(syscall_kernel_flock
);
1549 kernel_flock(fsp
->fh
->fd
, share_mode
, access_mask
);
1550 END_PROFILE(syscall_kernel_flock
);
1554 static bool vfswrap_getlock(vfs_handle_struct
*handle
, files_struct
*fsp
, off_t
*poffset
, off_t
*pcount
, int *ptype
, pid_t
*ppid
)
1558 START_PROFILE(syscall_fcntl_getlock
);
1559 result
= fcntl_getlock(fsp
->fh
->fd
, poffset
, pcount
, ptype
, ppid
);
1560 END_PROFILE(syscall_fcntl_getlock
);
1564 static int vfswrap_linux_setlease(vfs_handle_struct
*handle
, files_struct
*fsp
,
1569 START_PROFILE(syscall_linux_setlease
);
1571 #ifdef HAVE_KERNEL_OPLOCKS_LINUX
1572 /* first set the signal handler */
1573 if(linux_set_lease_sighandler(fsp
->fh
->fd
) == -1) {
1577 result
= linux_setlease(fsp
->fh
->fd
, leasetype
);
1581 END_PROFILE(syscall_linux_setlease
);
1585 static int vfswrap_symlink(vfs_handle_struct
*handle
, const char *oldpath
, const char *newpath
)
1589 START_PROFILE(syscall_symlink
);
1590 result
= symlink(oldpath
, newpath
);
1591 END_PROFILE(syscall_symlink
);
1595 static int vfswrap_readlink(vfs_handle_struct
*handle
, const char *path
, char *buf
, size_t bufsiz
)
1599 START_PROFILE(syscall_readlink
);
1600 result
= readlink(path
, buf
, bufsiz
);
1601 END_PROFILE(syscall_readlink
);
1605 static int vfswrap_link(vfs_handle_struct
*handle
, const char *oldpath
, const char *newpath
)
1609 START_PROFILE(syscall_link
);
1610 result
= link(oldpath
, newpath
);
1611 END_PROFILE(syscall_link
);
1615 static int vfswrap_mknod(vfs_handle_struct
*handle
, const char *pathname
, mode_t mode
, SMB_DEV_T dev
)
1619 START_PROFILE(syscall_mknod
);
1620 result
= sys_mknod(pathname
, mode
, dev
);
1621 END_PROFILE(syscall_mknod
);
1625 static char *vfswrap_realpath(vfs_handle_struct
*handle
, const char *path
)
1629 START_PROFILE(syscall_realpath
);
1630 #ifdef REALPATH_TAKES_NULL
1631 result
= realpath(path
, NULL
);
1633 result
= SMB_MALLOC_ARRAY(char, PATH_MAX
+1);
1635 char *resolved_path
= realpath(path
, result
);
1636 if (!resolved_path
) {
1639 /* SMB_ASSERT(result == resolved_path) ? */
1640 result
= resolved_path
;
1644 END_PROFILE(syscall_realpath
);
1648 static NTSTATUS
vfswrap_notify_watch(vfs_handle_struct
*vfs_handle
,
1649 struct sys_notify_context
*ctx
,
1652 uint32_t *subdir_filter
,
1653 void (*callback
)(struct sys_notify_context
*ctx
,
1655 struct notify_event
*ev
),
1656 void *private_data
, void *handle
)
1659 * So far inotify is the only supported default notify mechanism. If
1660 * another platform like the the BSD's or a proprietary Unix comes
1661 * along and wants another default, we can play the same trick we
1662 * played with Posix ACLs.
1664 * Until that is the case, hard-code inotify here.
1667 if (lp_kernel_change_notify(vfs_handle
->conn
->params
)) {
1668 return inotify_watch(ctx
, path
, filter
, subdir_filter
,
1669 callback
, private_data
, handle
);
1673 * Do nothing, leave everything to notify_internal.c
1675 return NT_STATUS_OK
;
1678 static int vfswrap_chflags(vfs_handle_struct
*handle
, const char *path
,
1682 return chflags(path
, flags
);
1689 static struct file_id
vfswrap_file_id_create(struct vfs_handle_struct
*handle
,
1690 const SMB_STRUCT_STAT
*sbuf
)
1694 /* the ZERO_STRUCT ensures padding doesn't break using the key as a
1698 key
.devid
= sbuf
->st_ex_dev
;
1699 key
.inode
= sbuf
->st_ex_ino
;
1700 /* key.extid is unused by default. */
1705 static NTSTATUS
vfswrap_streaminfo(vfs_handle_struct
*handle
,
1706 struct files_struct
*fsp
,
1708 TALLOC_CTX
*mem_ctx
,
1709 unsigned int *pnum_streams
,
1710 struct stream_struct
**pstreams
)
1712 SMB_STRUCT_STAT sbuf
;
1713 struct stream_struct
*tmp_streams
= NULL
;
1716 if ((fsp
!= NULL
) && (fsp
->is_directory
)) {
1718 * No default streams on directories
1723 if ((fsp
!= NULL
) && (fsp
->fh
->fd
!= -1)) {
1724 ret
= SMB_VFS_FSTAT(fsp
, &sbuf
);
1727 struct smb_filename smb_fname
;
1729 ZERO_STRUCT(smb_fname
);
1730 smb_fname
.base_name
= discard_const_p(char, fname
);
1732 if (lp_posix_pathnames()) {
1733 ret
= SMB_VFS_LSTAT(handle
->conn
, &smb_fname
);
1735 ret
= SMB_VFS_STAT(handle
->conn
, &smb_fname
);
1737 sbuf
= smb_fname
.st
;
1741 return map_nt_error_from_unix(errno
);
1744 if (S_ISDIR(sbuf
.st_ex_mode
)) {
1748 tmp_streams
= talloc_realloc(mem_ctx
, *pstreams
, struct stream_struct
,
1749 (*pnum_streams
) + 1);
1750 if (tmp_streams
== NULL
) {
1751 return NT_STATUS_NO_MEMORY
;
1753 tmp_streams
[*pnum_streams
].name
= talloc_strdup(tmp_streams
, "::$DATA");
1754 if (tmp_streams
[*pnum_streams
].name
== NULL
) {
1755 return NT_STATUS_NO_MEMORY
;
1757 tmp_streams
[*pnum_streams
].size
= sbuf
.st_ex_size
;
1758 tmp_streams
[*pnum_streams
].alloc_size
= SMB_VFS_GET_ALLOC_SIZE(handle
->conn
, fsp
, &sbuf
);
1761 *pstreams
= tmp_streams
;
1763 return NT_STATUS_OK
;
1766 static int vfswrap_get_real_filename(struct vfs_handle_struct
*handle
,
1769 TALLOC_CTX
*mem_ctx
,
1773 * Don't fall back to get_real_filename so callers can differentiate
1774 * between a full directory scan and an actual case-insensitive stat.
1780 static const char *vfswrap_connectpath(struct vfs_handle_struct
*handle
,
1783 return handle
->conn
->connectpath
;
1786 static NTSTATUS
vfswrap_brl_lock_windows(struct vfs_handle_struct
*handle
,
1787 struct byte_range_lock
*br_lck
,
1788 struct lock_struct
*plock
,
1790 struct blocking_lock_record
*blr
)
1792 SMB_ASSERT(plock
->lock_flav
== WINDOWS_LOCK
);
1794 /* Note: blr is not used in the default implementation. */
1795 return brl_lock_windows_default(br_lck
, plock
, blocking_lock
);
1798 static bool vfswrap_brl_unlock_windows(struct vfs_handle_struct
*handle
,
1799 struct messaging_context
*msg_ctx
,
1800 struct byte_range_lock
*br_lck
,
1801 const struct lock_struct
*plock
)
1803 SMB_ASSERT(plock
->lock_flav
== WINDOWS_LOCK
);
1805 return brl_unlock_windows_default(msg_ctx
, br_lck
, plock
);
1808 static bool vfswrap_brl_cancel_windows(struct vfs_handle_struct
*handle
,
1809 struct byte_range_lock
*br_lck
,
1810 struct lock_struct
*plock
,
1811 struct blocking_lock_record
*blr
)
1813 SMB_ASSERT(plock
->lock_flav
== WINDOWS_LOCK
);
1815 /* Note: blr is not used in the default implementation. */
1816 return brl_lock_cancel_default(br_lck
, plock
);
1819 static bool vfswrap_strict_lock(struct vfs_handle_struct
*handle
,
1821 struct lock_struct
*plock
)
1823 SMB_ASSERT(plock
->lock_type
== READ_LOCK
||
1824 plock
->lock_type
== WRITE_LOCK
);
1826 return strict_lock_default(fsp
, plock
);
1829 static void vfswrap_strict_unlock(struct vfs_handle_struct
*handle
,
1831 struct lock_struct
*plock
)
1833 SMB_ASSERT(plock
->lock_type
== READ_LOCK
||
1834 plock
->lock_type
== WRITE_LOCK
);
1836 strict_unlock_default(fsp
, plock
);
1839 /* NT ACL operations. */
1841 static NTSTATUS
vfswrap_fget_nt_acl(vfs_handle_struct
*handle
,
1843 uint32 security_info
,
1844 struct security_descriptor
**ppdesc
)
1848 START_PROFILE(fget_nt_acl
);
1849 result
= posix_fget_nt_acl(fsp
, security_info
, ppdesc
);
1850 END_PROFILE(fget_nt_acl
);
1854 static NTSTATUS
vfswrap_get_nt_acl(vfs_handle_struct
*handle
,
1856 uint32 security_info
,
1857 struct security_descriptor
**ppdesc
)
1861 START_PROFILE(get_nt_acl
);
1862 result
= posix_get_nt_acl(handle
->conn
, name
, security_info
, ppdesc
);
1863 END_PROFILE(get_nt_acl
);
1867 static NTSTATUS
vfswrap_fset_nt_acl(vfs_handle_struct
*handle
, files_struct
*fsp
, uint32 security_info_sent
, const struct security_descriptor
*psd
)
1871 START_PROFILE(fset_nt_acl
);
1872 result
= set_nt_acl(fsp
, security_info_sent
, psd
);
1873 END_PROFILE(fset_nt_acl
);
1877 NTSTATUS
vfswrap_audit_file(struct vfs_handle_struct
*handle
,
1878 struct smb_filename
*file
,
1879 struct security_acl
*sacl
,
1880 uint32_t access_requested
,
1881 uint32_t access_denied
)
1883 return NT_STATUS_OK
; /* Nothing to do here ... */
1886 static int vfswrap_chmod_acl(vfs_handle_struct
*handle
, const char *name
, mode_t mode
)
1894 START_PROFILE(chmod_acl
);
1895 result
= chmod_acl(handle
->conn
, name
, mode
);
1896 END_PROFILE(chmod_acl
);
1901 static int vfswrap_fchmod_acl(vfs_handle_struct
*handle
, files_struct
*fsp
, mode_t mode
)
1909 START_PROFILE(fchmod_acl
);
1910 result
= fchmod_acl(fsp
, mode
);
1911 END_PROFILE(fchmod_acl
);
1916 static int vfswrap_sys_acl_get_entry(vfs_handle_struct
*handle
, SMB_ACL_T theacl
, int entry_id
, SMB_ACL_ENTRY_T
*entry_p
)
1918 return sys_acl_get_entry(theacl
, entry_id
, entry_p
);
1921 static int vfswrap_sys_acl_get_tag_type(vfs_handle_struct
*handle
, SMB_ACL_ENTRY_T entry_d
, SMB_ACL_TAG_T
*tag_type_p
)
1923 return sys_acl_get_tag_type(entry_d
, tag_type_p
);
1926 static int vfswrap_sys_acl_get_permset(vfs_handle_struct
*handle
, SMB_ACL_ENTRY_T entry_d
, SMB_ACL_PERMSET_T
*permset_p
)
1928 return sys_acl_get_permset(entry_d
, permset_p
);
1931 static void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct
*handle
, SMB_ACL_ENTRY_T entry_d
)
1933 return sys_acl_get_qualifier(entry_d
);
1936 static SMB_ACL_T
vfswrap_sys_acl_get_file(vfs_handle_struct
*handle
, const char *path_p
, SMB_ACL_TYPE_T type
)
1938 return sys_acl_get_file(handle
, path_p
, type
);
1941 static SMB_ACL_T
vfswrap_sys_acl_get_fd(vfs_handle_struct
*handle
, files_struct
*fsp
)
1943 return sys_acl_get_fd(handle
, fsp
);
1946 static int vfswrap_sys_acl_clear_perms(vfs_handle_struct
*handle
, SMB_ACL_PERMSET_T permset
)
1948 return sys_acl_clear_perms(permset
);
1951 static int vfswrap_sys_acl_add_perm(vfs_handle_struct
*handle
, SMB_ACL_PERMSET_T permset
, SMB_ACL_PERM_T perm
)
1953 return sys_acl_add_perm(permset
, perm
);
1956 static char * vfswrap_sys_acl_to_text(vfs_handle_struct
*handle
, SMB_ACL_T theacl
, ssize_t
*plen
)
1958 return sys_acl_to_text(theacl
, plen
);
1961 static SMB_ACL_T
vfswrap_sys_acl_init(vfs_handle_struct
*handle
, int count
)
1963 return sys_acl_init(count
);
1966 static int vfswrap_sys_acl_create_entry(vfs_handle_struct
*handle
, SMB_ACL_T
*pacl
, SMB_ACL_ENTRY_T
*pentry
)
1968 return sys_acl_create_entry(pacl
, pentry
);
1971 static int vfswrap_sys_acl_set_tag_type(vfs_handle_struct
*handle
, SMB_ACL_ENTRY_T entry
, SMB_ACL_TAG_T tagtype
)
1973 return sys_acl_set_tag_type(entry
, tagtype
);
1976 static int vfswrap_sys_acl_set_qualifier(vfs_handle_struct
*handle
, SMB_ACL_ENTRY_T entry
, void *qual
)
1978 return sys_acl_set_qualifier(entry
, qual
);
1981 static int vfswrap_sys_acl_set_permset(vfs_handle_struct
*handle
, SMB_ACL_ENTRY_T entry
, SMB_ACL_PERMSET_T permset
)
1983 return sys_acl_set_permset(entry
, permset
);
1986 static int vfswrap_sys_acl_valid(vfs_handle_struct
*handle
, SMB_ACL_T theacl
)
1988 return sys_acl_valid(theacl
);
1991 static int vfswrap_sys_acl_set_file(vfs_handle_struct
*handle
, const char *name
, SMB_ACL_TYPE_T acltype
, SMB_ACL_T theacl
)
1993 return sys_acl_set_file(handle
, name
, acltype
, theacl
);
1996 static int vfswrap_sys_acl_set_fd(vfs_handle_struct
*handle
, files_struct
*fsp
, SMB_ACL_T theacl
)
1998 return sys_acl_set_fd(handle
, fsp
, theacl
);
2001 static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct
*handle
, const char *path
)
2003 return sys_acl_delete_def_file(handle
, path
);
2006 static int vfswrap_sys_acl_get_perm(vfs_handle_struct
*handle
, SMB_ACL_PERMSET_T permset
, SMB_ACL_PERM_T perm
)
2008 return sys_acl_get_perm(permset
, perm
);
2011 static int vfswrap_sys_acl_free_text(vfs_handle_struct
*handle
, char *text
)
2013 return sys_acl_free_text(text
);
2016 static int vfswrap_sys_acl_free_acl(vfs_handle_struct
*handle
, SMB_ACL_T posix_acl
)
2018 return sys_acl_free_acl(posix_acl
);
2021 static int vfswrap_sys_acl_free_qualifier(vfs_handle_struct
*handle
, void *qualifier
, SMB_ACL_TAG_T tagtype
)
2023 return sys_acl_free_qualifier(qualifier
, tagtype
);
2026 /****************************************************************
2027 Extended attribute operations.
2028 *****************************************************************/
2030 static ssize_t
vfswrap_getxattr(struct vfs_handle_struct
*handle
,const char *path
, const char *name
, void *value
, size_t size
)
2032 return sys_getxattr(path
, name
, value
, size
);
2035 static ssize_t
vfswrap_fgetxattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, const char *name
, void *value
, size_t size
)
2037 return sys_fgetxattr(fsp
->fh
->fd
, name
, value
, size
);
2040 static ssize_t
vfswrap_listxattr(struct vfs_handle_struct
*handle
, const char *path
, char *list
, size_t size
)
2042 return sys_listxattr(path
, list
, size
);
2045 static ssize_t
vfswrap_flistxattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, char *list
, size_t size
)
2047 return sys_flistxattr(fsp
->fh
->fd
, list
, size
);
2050 static int vfswrap_removexattr(struct vfs_handle_struct
*handle
, const char *path
, const char *name
)
2052 return sys_removexattr(path
, name
);
2055 static int vfswrap_fremovexattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, const char *name
)
2057 return sys_fremovexattr(fsp
->fh
->fd
, name
);
2060 static int vfswrap_setxattr(struct vfs_handle_struct
*handle
, const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
2062 return sys_setxattr(path
, name
, value
, size
, flags
);
2065 static int vfswrap_fsetxattr(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, const char *name
, const void *value
, size_t size
, int flags
)
2067 return sys_fsetxattr(fsp
->fh
->fd
, name
, value
, size
, flags
);
2070 static int vfswrap_aio_read(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, SMB_STRUCT_AIOCB
*aiocb
)
2073 if (!initialize_async_io_handler()) {
2078 * aio_read must be done as root, because in the glibc aio
2079 * implementation the helper thread needs to be able to send a signal
2080 * to the main thread, even when it has done a seteuid() to a
2084 ret
= sys_aio_read(aiocb
);
2089 static int vfswrap_aio_write(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, SMB_STRUCT_AIOCB
*aiocb
)
2092 if (!initialize_async_io_handler()) {
2097 * aio_write must be done as root, because in the glibc aio
2098 * implementation the helper thread needs to be able to send a signal
2099 * to the main thread, even when it has done a seteuid() to a
2103 ret
= sys_aio_write(aiocb
);
2108 static ssize_t
vfswrap_aio_return(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, SMB_STRUCT_AIOCB
*aiocb
)
2110 return sys_aio_return(aiocb
);
2113 static int vfswrap_aio_cancel(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, SMB_STRUCT_AIOCB
*aiocb
)
2115 return sys_aio_cancel(fsp
->fh
->fd
, aiocb
);
2118 static int vfswrap_aio_error(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, SMB_STRUCT_AIOCB
*aiocb
)
2120 return sys_aio_error(aiocb
);
2123 static int vfswrap_aio_fsync(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, int op
, SMB_STRUCT_AIOCB
*aiocb
)
2125 return sys_aio_fsync(op
, aiocb
);
2128 static int vfswrap_aio_suspend(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
, const SMB_STRUCT_AIOCB
* const aiocb
[], int n
, const struct timespec
*timeout
)
2130 return sys_aio_suspend(aiocb
, n
, timeout
);
2133 static bool vfswrap_aio_force(struct vfs_handle_struct
*handle
, struct files_struct
*fsp
)
2138 static bool vfswrap_is_offline(struct vfs_handle_struct
*handle
,
2139 const struct smb_filename
*fname
,
2140 SMB_STRUCT_STAT
*sbuf
)
2144 bool offline
= false;
2146 if (ISDOT(fname
->base_name
) || ISDOTDOT(fname
->base_name
)) {
2150 if (!lp_dmapi_support(SNUM(handle
->conn
)) || !dmapi_have_session()) {
2151 #if defined(ENOTSUP)
2157 status
= get_full_smb_filename(talloc_tos(), fname
, &path
);
2158 if (!NT_STATUS_IS_OK(status
)) {
2159 errno
= map_errno_from_nt_status(status
);
2163 offline
= (dmapi_file_flags(path
) & FILE_ATTRIBUTE_OFFLINE
) != 0;
2170 static int vfswrap_set_offline(struct vfs_handle_struct
*handle
,
2171 const struct smb_filename
*fname
)
2173 /* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */
2174 #if defined(ENOTSUP)
2180 static struct vfs_fn_pointers vfs_default_fns
= {
2181 /* Disk operations */
2183 .connect_fn
= vfswrap_connect
,
2184 .disconnect_fn
= vfswrap_disconnect
,
2185 .disk_free_fn
= vfswrap_disk_free
,
2186 .get_quota_fn
= vfswrap_get_quota
,
2187 .set_quota_fn
= vfswrap_set_quota
,
2188 .get_shadow_copy_data_fn
= vfswrap_get_shadow_copy_data
,
2189 .statvfs_fn
= vfswrap_statvfs
,
2190 .fs_capabilities_fn
= vfswrap_fs_capabilities
,
2191 .get_dfs_referrals_fn
= vfswrap_get_dfs_referrals
,
2193 /* Directory operations */
2195 .opendir_fn
= vfswrap_opendir
,
2196 .fdopendir_fn
= vfswrap_fdopendir
,
2197 .readdir_fn
= vfswrap_readdir
,
2198 .seekdir_fn
= vfswrap_seekdir
,
2199 .telldir_fn
= vfswrap_telldir
,
2200 .rewind_dir_fn
= vfswrap_rewinddir
,
2201 .mkdir_fn
= vfswrap_mkdir
,
2202 .rmdir_fn
= vfswrap_rmdir
,
2203 .closedir_fn
= vfswrap_closedir
,
2204 .init_search_op_fn
= vfswrap_init_search_op
,
2206 /* File operations */
2208 .open_fn
= vfswrap_open
,
2209 .create_file_fn
= vfswrap_create_file
,
2210 .close_fn
= vfswrap_close
,
2211 .read_fn
= vfswrap_read
,
2212 .pread_fn
= vfswrap_pread
,
2213 .write_fn
= vfswrap_write
,
2214 .pwrite_fn
= vfswrap_pwrite
,
2215 .lseek_fn
= vfswrap_lseek
,
2216 .sendfile_fn
= vfswrap_sendfile
,
2217 .recvfile_fn
= vfswrap_recvfile
,
2218 .rename_fn
= vfswrap_rename
,
2219 .fsync_fn
= vfswrap_fsync
,
2220 .stat_fn
= vfswrap_stat
,
2221 .fstat_fn
= vfswrap_fstat
,
2222 .lstat_fn
= vfswrap_lstat
,
2223 .get_alloc_size_fn
= vfswrap_get_alloc_size
,
2224 .unlink_fn
= vfswrap_unlink
,
2225 .chmod_fn
= vfswrap_chmod
,
2226 .fchmod_fn
= vfswrap_fchmod
,
2227 .chown_fn
= vfswrap_chown
,
2228 .fchown_fn
= vfswrap_fchown
,
2229 .lchown_fn
= vfswrap_lchown
,
2230 .chdir_fn
= vfswrap_chdir
,
2231 .getwd_fn
= vfswrap_getwd
,
2232 .ntimes_fn
= vfswrap_ntimes
,
2233 .ftruncate_fn
= vfswrap_ftruncate
,
2234 .fallocate_fn
= vfswrap_fallocate
,
2235 .lock_fn
= vfswrap_lock
,
2236 .kernel_flock_fn
= vfswrap_kernel_flock
,
2237 .linux_setlease_fn
= vfswrap_linux_setlease
,
2238 .getlock_fn
= vfswrap_getlock
,
2239 .symlink_fn
= vfswrap_symlink
,
2240 .readlink_fn
= vfswrap_readlink
,
2241 .link_fn
= vfswrap_link
,
2242 .mknod_fn
= vfswrap_mknod
,
2243 .realpath_fn
= vfswrap_realpath
,
2244 .notify_watch_fn
= vfswrap_notify_watch
,
2245 .chflags_fn
= vfswrap_chflags
,
2246 .file_id_create_fn
= vfswrap_file_id_create
,
2247 .streaminfo_fn
= vfswrap_streaminfo
,
2248 .get_real_filename_fn
= vfswrap_get_real_filename
,
2249 .connectpath_fn
= vfswrap_connectpath
,
2250 .brl_lock_windows_fn
= vfswrap_brl_lock_windows
,
2251 .brl_unlock_windows_fn
= vfswrap_brl_unlock_windows
,
2252 .brl_cancel_windows_fn
= vfswrap_brl_cancel_windows
,
2253 .strict_lock_fn
= vfswrap_strict_lock
,
2254 .strict_unlock_fn
= vfswrap_strict_unlock
,
2255 .translate_name_fn
= vfswrap_translate_name
,
2256 .fsctl_fn
= vfswrap_fsctl
,
2258 /* NT ACL operations. */
2260 .fget_nt_acl_fn
= vfswrap_fget_nt_acl
,
2261 .get_nt_acl_fn
= vfswrap_get_nt_acl
,
2262 .fset_nt_acl_fn
= vfswrap_fset_nt_acl
,
2263 .audit_file_fn
= vfswrap_audit_file
,
2265 /* POSIX ACL operations. */
2267 .chmod_acl_fn
= vfswrap_chmod_acl
,
2268 .fchmod_acl_fn
= vfswrap_fchmod_acl
,
2270 .sys_acl_get_entry_fn
= vfswrap_sys_acl_get_entry
,
2271 .sys_acl_get_tag_type_fn
= vfswrap_sys_acl_get_tag_type
,
2272 .sys_acl_get_permset_fn
= vfswrap_sys_acl_get_permset
,
2273 .sys_acl_get_qualifier_fn
= vfswrap_sys_acl_get_qualifier
,
2274 .sys_acl_get_file_fn
= vfswrap_sys_acl_get_file
,
2275 .sys_acl_get_fd_fn
= vfswrap_sys_acl_get_fd
,
2276 .sys_acl_clear_perms_fn
= vfswrap_sys_acl_clear_perms
,
2277 .sys_acl_add_perm_fn
= vfswrap_sys_acl_add_perm
,
2278 .sys_acl_to_text_fn
= vfswrap_sys_acl_to_text
,
2279 .sys_acl_init_fn
= vfswrap_sys_acl_init
,
2280 .sys_acl_create_entry_fn
= vfswrap_sys_acl_create_entry
,
2281 .sys_acl_set_tag_type_fn
= vfswrap_sys_acl_set_tag_type
,
2282 .sys_acl_set_qualifier_fn
= vfswrap_sys_acl_set_qualifier
,
2283 .sys_acl_set_permset_fn
= vfswrap_sys_acl_set_permset
,
2284 .sys_acl_valid_fn
= vfswrap_sys_acl_valid
,
2285 .sys_acl_set_file_fn
= vfswrap_sys_acl_set_file
,
2286 .sys_acl_set_fd_fn
= vfswrap_sys_acl_set_fd
,
2287 .sys_acl_delete_def_file_fn
= vfswrap_sys_acl_delete_def_file
,
2288 .sys_acl_get_perm_fn
= vfswrap_sys_acl_get_perm
,
2289 .sys_acl_free_text_fn
= vfswrap_sys_acl_free_text
,
2290 .sys_acl_free_acl_fn
= vfswrap_sys_acl_free_acl
,
2291 .sys_acl_free_qualifier_fn
= vfswrap_sys_acl_free_qualifier
,
2293 /* EA operations. */
2294 .getxattr_fn
= vfswrap_getxattr
,
2295 .fgetxattr_fn
= vfswrap_fgetxattr
,
2296 .listxattr_fn
= vfswrap_listxattr
,
2297 .flistxattr_fn
= vfswrap_flistxattr
,
2298 .removexattr_fn
= vfswrap_removexattr
,
2299 .fremovexattr_fn
= vfswrap_fremovexattr
,
2300 .setxattr_fn
= vfswrap_setxattr
,
2301 .fsetxattr_fn
= vfswrap_fsetxattr
,
2303 /* aio operations */
2304 .aio_read_fn
= vfswrap_aio_read
,
2305 .aio_write_fn
= vfswrap_aio_write
,
2306 .aio_return_fn
= vfswrap_aio_return
,
2307 .aio_cancel_fn
= vfswrap_aio_cancel
,
2308 .aio_error_fn
= vfswrap_aio_error
,
2309 .aio_fsync_fn
= vfswrap_aio_fsync
,
2310 .aio_suspend_fn
= vfswrap_aio_suspend
,
2311 .aio_force_fn
= vfswrap_aio_force
,
2313 /* offline operations */
2314 .is_offline_fn
= vfswrap_is_offline
,
2315 .set_offline_fn
= vfswrap_set_offline
2318 NTSTATUS
vfs_default_init(void);
2319 NTSTATUS
vfs_default_init(void)
2321 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION
,
2322 DEFAULT_VFS_MODULE_NAME
, &vfs_default_fns
);