s3:smb2_flush: make use of file_fsp_smb2()
[Samba/gebeck_regimport.git] / source3 / modules / vfs_default.c
blob9745a733be496cffe844993130cc6f7ac8c0e8c1
1 /*
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/>.
21 #include "includes.h"
22 #include "system/time.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
26 #include "ntioctl.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"
33 #undef DBGC_CLASS
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
40 this possibility. */
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)
51 /* Disk operations */
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)
56 uint64_t result;
58 result = sys_disk_free(handle->conn, path, small_query, bsize, dfree, dsize);
59 return result;
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
65 int result;
67 START_PROFILE(syscall_get_quota);
68 result = sys_get_quota(handle->conn->connectpath, qtype, id, qt);
69 END_PROFILE(syscall_get_quota);
70 return result;
71 #else
72 errno = ENOSYS;
73 return -1;
74 #endif
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
80 int result;
82 START_PROFILE(syscall_set_quota);
83 result = sys_set_quota(handle->conn->connectpath, qtype, id, qt);
84 END_PROFILE(syscall_set_quota);
85 return result;
86 #else
87 errno = ENOSYS;
88 return -1;
89 #endif
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,
95 bool labels)
97 errno = ENOSYS;
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;
113 NTSTATUS status;
114 int ret;
116 ZERO_STRUCT(statbuf);
117 ret = sys_statvfs(conn->connectpath, &statbuf);
118 if (ret == 0) {
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(),
128 conn->connectpath,
129 NULL,
130 NULL,
131 &smb_fname_cpath);
132 if (!NT_STATUS_IS_OK(status)) {
133 return caps;
136 ret = SMB_VFS_STAT(conn, smb_fname_cpath);
137 if (ret == -1) {
138 TALLOC_FREE(smb_fname_cpath);
139 return caps;
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;
158 #endif
160 DEBUG(10,("vfswrap_fs_capabilities: timestamp "
161 "resolution of %s "
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);
168 return caps;
171 static NTSTATUS vfswrap_get_dfs_referrals(struct vfs_handle_struct *handle,
172 struct dfs_GetDFSReferral *r)
174 struct junction_map *junction = NULL;
175 int consumedcnt = 0;
176 bool self_referral = false;
177 char *pathnamep = NULL;
178 char *local_dfs_path = NULL;
179 NTSTATUS status;
180 int i;
181 uint16_t max_referral_level = r->in.req.max_referral_level;
183 if (DEBUGLVL(10)) {
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])) {
204 pathnamep++;
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);
218 return status;
220 vfs_ChDir(handle->conn, handle->conn->connectpath);
222 if (!self_referral) {
223 pathnamep[consumedcnt] = '\0';
225 if (DEBUGLVL(3)) {
226 dbgtext("setup_dfs_referral: Path %s to "
227 "alternate path(s):",
228 pathnamep);
229 for (i=0; i < junction->referral_count; i++) {
230 dbgtext(" %s",
231 junction->referral_list[i].alternate_path);
233 dbgtext(".\n");
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;
253 if (self_referral) {
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) {
265 case 2:
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;
273 t->version = 2;
274 v2->size = VERSION2_REFERRAL_SIZE;
275 if (self_referral) {
276 v2->server_type = DFS_SERVER_ROOT;
277 } else {
278 v2->server_type = DFS_SERVER_NON_ROOT;
280 v2->entry_flags = 0;
281 v2->proximity = ref->proximity;
282 v2->ttl = ref->ttl;
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;
298 break;
299 case 3:
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;
308 t->version = 3;
309 v3->size = VERSION3_REFERRAL_SIZE;
310 if (self_referral) {
311 v3->server_type = DFS_SERVER_ROOT;
312 } else {
313 v3->server_type = DFS_SERVER_NON_ROOT;
315 v3->entry_flags = 0;
316 v3->ttl = ref->ttl;
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;
331 break;
332 default:
333 DEBUG(0,("setup_dfs_referral: Invalid dfs referral "
334 "version: %d\n",
335 max_referral_level));
336 return NT_STATUS_INVALID_LEVEL;
339 if (DEBUGLVL(10)) {
340 NDR_PRINT_OUT_DEBUG(dfs_GetDFSReferral, r);
343 return NT_STATUS_OK;
346 /* Directory operations */
348 static DIR *vfswrap_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr)
350 DIR *result;
352 START_PROFILE(syscall_opendir);
353 result = opendir(fname);
354 END_PROFILE(syscall_opendir);
355 return result;
358 static DIR *vfswrap_fdopendir(vfs_handle_struct *handle,
359 files_struct *fsp,
360 const char *mask,
361 uint32 attr)
363 DIR *result;
365 START_PROFILE(syscall_fdopendir);
366 result = sys_fdopendir(fsp->fh->fd);
367 END_PROFILE(syscall_fdopendir);
368 return result;
372 static struct dirent *vfswrap_readdir(vfs_handle_struct *handle,
373 DIR *dirp,
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. */
382 if (sbuf)
383 SET_STAT_INVALID(*sbuf);
384 END_PROFILE(syscall_readdir);
385 return result;
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)
397 long result;
398 START_PROFILE(syscall_telldir);
399 result = telldir(dirp);
400 END_PROFILE(syscall_telldir);
401 return result;
404 static void vfswrap_rewinddir(vfs_handle_struct *handle, DIR *dirp)
406 START_PROFILE(syscall_rewinddir);
407 rewinddir(dirp);
408 END_PROFILE(syscall_rewinddir);
411 static int vfswrap_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode)
413 int result;
414 bool has_dacl = False;
415 char *parent = NULL;
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)));
424 TALLOC_FREE(parent);
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))
438 errno = saved_errno;
441 END_PROFILE(syscall_mkdir);
442 return result;
445 static int vfswrap_rmdir(vfs_handle_struct *handle, const char *path)
447 int result;
449 START_PROFILE(syscall_rmdir);
450 result = rmdir(path);
451 END_PROFILE(syscall_rmdir);
452 return result;
455 static int vfswrap_closedir(vfs_handle_struct *handle, DIR *dirp)
457 int result;
459 START_PROFILE(syscall_closedir);
460 result = closedir(dirp);
461 END_PROFILE(syscall_closedir);
462 return result;
465 static void vfswrap_init_search_op(vfs_handle_struct *handle,
466 DIR *dirp)
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)
477 int result = -1;
479 START_PROFILE(syscall_open);
481 if (smb_fname->stream_name) {
482 errno = ENOENT;
483 goto out;
486 result = open(smb_fname->base_name, flags, mode);
487 out:
488 END_PROFILE(syscall_open);
489 return result;
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,
507 int *pinfo)
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,
514 sd, ea_list, result,
515 pinfo);
518 static int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp)
520 int result;
522 START_PROFILE(syscall_close);
523 result = fd_close_posix(fsp);
524 END_PROFILE(syscall_close);
525 return result;
528 static ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, void *data, size_t n)
530 ssize_t result;
532 START_PROFILE_BYTES(syscall_read, n);
533 result = sys_read(fsp->fh->fd, data, n);
534 END_PROFILE(syscall_read);
535 return result;
538 static ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, void *data,
539 size_t n, off_t offset)
541 ssize_t result;
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);
551 fsp->fh->pos = 0;
554 #else /* HAVE_PREAD */
555 off_t curr;
556 int lerrno;
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);
562 fsp->fh->pos = 0;
563 return result;
566 if (SMB_VFS_LSEEK(fsp, offset, SEEK_SET) == -1) {
567 return -1;
570 errno = 0;
571 result = SMB_VFS_READ(fsp, data, n);
572 lerrno = errno;
574 SMB_VFS_LSEEK(fsp, curr, SEEK_SET);
575 errno = lerrno;
577 #endif /* HAVE_PREAD */
579 return result;
582 static ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n)
584 ssize_t result;
586 START_PROFILE_BYTES(syscall_write, n);
587 result = sys_write(fsp->fh->fd, data, n);
588 END_PROFILE(syscall_write);
589 return result;
592 static ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, const void *data,
593 size_t n, off_t offset)
595 ssize_t result;
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 */
608 off_t curr;
609 int lerrno;
611 curr = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
612 if (curr == -1) {
613 return -1;
616 if (SMB_VFS_LSEEK(fsp, offset, SEEK_SET) == -1) {
617 return -1;
620 result = SMB_VFS_WRITE(fsp, data, n);
621 lerrno = errno;
623 SMB_VFS_LSEEK(fsp, curr, SEEK_SET);
624 errno = lerrno;
626 #endif /* HAVE_PWRITE */
628 return result;
631 static off_t vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, off_t offset, int whence)
633 off_t result = 0;
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
645 * applications. JRA.
648 if((result == -1) && (errno == ESPIPE)) {
649 result = 0;
650 errno = 0;
653 END_PROFILE(syscall_lseek);
654 return result;
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)
660 ssize_t result;
662 START_PROFILE_BYTES(syscall_sendfile, n);
663 result = sys_sendfile(tofd, fromfsp->fh->fd, hdr, offset, n);
664 END_PROFILE(syscall_sendfile);
665 return result;
668 static ssize_t vfswrap_recvfile(vfs_handle_struct *handle,
669 int fromfd,
670 files_struct *tofsp,
671 off_t offset,
672 size_t n)
674 ssize_t result;
676 START_PROFILE_BYTES(syscall_recvfile, n);
677 result = sys_recvfile(fromfd, tofsp->fh->fd, offset, n);
678 END_PROFILE(syscall_recvfile);
679 return result;
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)
686 int result = -1;
688 START_PROFILE(syscall_rename);
690 if (smb_fname_src->stream_name || smb_fname_dst->stream_name) {
691 errno = ENOENT;
692 goto out;
695 result = rename(smb_fname_src->base_name, smb_fname_dst->base_name);
697 out:
698 END_PROFILE(syscall_rename);
699 return result;
702 static int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp)
704 #ifdef HAVE_FSYNC
705 int result;
707 START_PROFILE(syscall_fsync);
708 result = fsync(fsp->fh->fd);
709 END_PROFILE(syscall_fsync);
710 return result;
711 #else
712 return 0;
713 #endif
716 static int vfswrap_stat(vfs_handle_struct *handle,
717 struct smb_filename *smb_fname)
719 int result = -1;
721 START_PROFILE(syscall_stat);
723 if (smb_fname->stream_name) {
724 errno = ENOENT;
725 goto out;
728 result = sys_stat(smb_fname->base_name, &smb_fname->st,
729 lp_fake_dir_create_times(SNUM(handle->conn)));
730 out:
731 END_PROFILE(syscall_stat);
732 return result;
735 static int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
737 int result;
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);
743 return result;
746 static int vfswrap_lstat(vfs_handle_struct *handle,
747 struct smb_filename *smb_fname)
749 int result = -1;
751 START_PROFILE(syscall_lstat);
753 if (smb_fname->stream_name) {
754 errno = ENOENT;
755 goto out;
758 result = sys_lstat(smb_fname->base_name, &smb_fname->st,
759 lp_fake_dir_create_times(SNUM(handle->conn)));
760 out:
761 END_PROFILE(syscall_lstat);
762 return result;
765 static NTSTATUS vfswrap_translate_name(struct vfs_handle_struct *handle,
766 const char *name,
767 enum vfs_translate_direction direction,
768 TALLOC_CTX *mem_ctx,
769 char **mapped_name)
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,
781 TALLOC_CTX *ctx,
782 uint32_t function,
783 uint16_t req_flags, /* Needed for UNICODE ... */
784 const uint8_t *_in_data,
785 uint32_t in_len,
786 uint8_t **_out_data,
787 uint32_t max_out_len,
788 uint32_t *out_len)
790 const char *in_data = (const char *)_in_data;
791 char **out_data = (char **)_out_data;
793 switch (function) {
794 case FSCTL_SET_SPARSE:
796 bool set_sparse = true;
797 NTSTATUS status;
799 if (in_len >= 1 && in_data[0] == 0) {
800 set_sparse = false;
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,
808 nt_errstr(status)));
810 return status;
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;
836 return NT_STATUS_OK;
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;
866 bool labels = False;
867 uint32 labels_data_count = 0;
868 uint32 i;
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",
873 max_out_len));
874 return NT_STATUS_INVALID_PARAMETER;
877 if (max_out_len > 16) {
878 labels = True;
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;
896 } else {
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;
906 if (!labels) {
907 *out_len = 16;
908 } else {
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);
930 if (labels) {
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);
938 cur_pdata += 12;
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);
955 return NT_STATUS_OK;
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
966 struct dom_sid sid;
967 uid_t uid;
968 size_t sid_len;
970 DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n", fsp->fnum));
972 if (in_len < 8) {
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));
991 uid = (-1);
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
1000 * for each file
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
1012 * --metze
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.
1027 NTSTATUS status;
1028 uint64_t offset, length;
1029 char *out_data_tmp = NULL;
1031 if (in_len != 16) {
1032 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: data_count(%u) != 16 is invalid!\n",
1033 in_len));
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",
1039 max_out_len));
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)) {
1054 return status;
1057 *out_len = 16;
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 ||
1066 length == 0) {
1067 memset(out_data_tmp, 0, *out_len);
1068 } else {
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;
1091 default:
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)
1114 uint64_t result;
1116 START_PROFILE(syscall_get_alloc_size);
1118 if(S_ISDIR(sbuf->st_ex_mode)) {
1119 result = 0;
1120 goto out;
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
1127 sign extend. */
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;
1135 #else
1136 #error SIZEOF_BLKCNT_T_NOT_A_SUPPORTED_VALUE
1137 #endif
1138 #else
1139 result = get_file_size_stat(sbuf);
1140 #endif
1142 if (fsp && fsp->initial_allocation_size)
1143 result = MAX(result,fsp->initial_allocation_size);
1145 result = smb_roundup(handle->conn, result);
1147 out:
1148 END_PROFILE(syscall_get_alloc_size);
1149 return result;
1152 static int vfswrap_unlink(vfs_handle_struct *handle,
1153 const struct smb_filename *smb_fname)
1155 int result = -1;
1157 START_PROFILE(syscall_unlink);
1159 if (smb_fname->stream_name) {
1160 errno = ENOENT;
1161 goto out;
1163 result = unlink(smb_fname->base_name);
1165 out:
1166 END_PROFILE(syscall_unlink);
1167 return result;
1170 static int vfswrap_chmod(vfs_handle_struct *handle, const char *path, mode_t mode)
1172 int result;
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);
1187 return result;
1189 /* Error - return the old errno. */
1190 errno = saved_errno;
1193 result = chmod(path, mode);
1194 END_PROFILE(syscall_chmod);
1195 return result;
1198 static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
1200 int result;
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);
1214 return result;
1216 /* Error - return the old errno. */
1217 errno = saved_errno;
1220 #if defined(HAVE_FCHMOD)
1221 result = fchmod(fsp->fh->fd, mode);
1222 #else
1223 result = -1;
1224 errno = ENOSYS;
1225 #endif
1227 END_PROFILE(syscall_fchmod);
1228 return result;
1231 static int vfswrap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
1233 int result;
1235 START_PROFILE(syscall_chown);
1236 result = chown(path, uid, gid);
1237 END_PROFILE(syscall_chown);
1238 return result;
1241 static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t uid, gid_t gid)
1243 #ifdef HAVE_FCHOWN
1244 int result;
1246 START_PROFILE(syscall_fchown);
1247 result = fchown(fsp->fh->fd, uid, gid);
1248 END_PROFILE(syscall_fchown);
1249 return result;
1250 #else
1251 errno = ENOSYS;
1252 return -1;
1253 #endif
1256 static int vfswrap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
1258 int result;
1260 START_PROFILE(syscall_lchown);
1261 result = lchown(path, uid, gid);
1262 END_PROFILE(syscall_lchown);
1263 return result;
1266 static int vfswrap_chdir(vfs_handle_struct *handle, const char *path)
1268 int result;
1270 START_PROFILE(syscall_chdir);
1271 result = chdir(path);
1272 END_PROFILE(syscall_chdir);
1273 return result;
1276 static char *vfswrap_getwd(vfs_handle_struct *handle)
1278 char *result;
1280 START_PROFILE(syscall_getwd);
1281 result = sys_getwd();
1282 END_PROFILE(syscall_getwd);
1283 return result;
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)
1295 int result = -1;
1297 START_PROFILE(syscall_ntimes);
1299 if (smb_fname->stream_name) {
1300 errno = ENOENT;
1301 goto out;
1304 if (ft != NULL) {
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,
1315 smb_fname,
1316 ft->create_time);
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)) {
1323 return 0;
1327 #if defined(HAVE_UTIMENSAT)
1328 if (ft != NULL) {
1329 struct timespec ts[2];
1330 ts[0] = ft->atime;
1331 ts[1] = ft->mtime;
1332 result = utimensat(AT_FDCWD, smb_fname->base_name, ts, 0);
1333 } else {
1334 result = utimensat(AT_FDCWD, smb_fname->base_name, NULL, 0);
1336 if (!((result == -1) && (errno == ENOSYS))) {
1337 goto out;
1339 #endif
1340 #if defined(HAVE_UTIMES)
1341 if (ft != NULL) {
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);
1346 } else {
1347 result = utimes(smb_fname->base_name, NULL);
1349 if (!((result == -1) && (errno == ENOSYS))) {
1350 goto out;
1352 #endif
1353 #if defined(HAVE_UTIME)
1354 if (ft != NULL) {
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, &times);
1359 } else {
1360 result = utime(smb_fname->base_name, NULL);
1362 if (!((result == -1) && (errno == ENOSYS))) {
1363 goto out;
1365 #endif
1366 errno = ENOSYS;
1367 result = -1;
1369 out:
1370 END_PROFILE(syscall_ntimes);
1371 return result;
1374 /*********************************************************************
1375 A version of ftruncate that will write the space on disk if strict
1376 allocate is set.
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;
1384 int ret;
1385 NTSTATUS status;
1386 SMB_STRUCT_STAT *pst;
1388 status = vfs_stat_fsp(fsp);
1389 if (!NT_STATUS_IS_OK(status)) {
1390 return -1;
1392 pst = &fsp->fsp_name->st;
1394 #ifdef S_ISFIFO
1395 if (S_ISFIFO(pst->st_ex_mode))
1396 return 0;
1397 #endif
1399 if (pst->st_ex_size == len)
1400 return 0;
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) {
1416 errno = ENOSPC;
1417 return -1;
1419 if (ret == 0) {
1420 return 0;
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) ) {
1432 errno = ENOSPC;
1433 return -1;
1436 /* Write out the real space on disk. */
1437 ret = vfs_slow_fallocate(fsp, pst->st_ex_size, space_to_write);
1438 if (ret != 0) {
1439 errno = ret;
1440 ret = -1;
1443 return 0;
1446 static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, off_t len)
1448 int result = -1;
1449 SMB_STRUCT_STAT *pst;
1450 NTSTATUS status;
1451 char c = 0;
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);
1458 return result;
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);
1468 if (result == 0)
1469 goto done;
1471 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
1472 extend a file with ftruncate. Provide alternate implementation
1473 for this */
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)) {
1481 goto done;
1483 pst = &fsp->fsp_name->st;
1485 #ifdef S_ISFIFO
1486 if (S_ISFIFO(pst->st_ex_mode)) {
1487 result = 0;
1488 goto done;
1490 #endif
1492 if (pst->st_ex_size == len) {
1493 result = 0;
1494 goto done;
1497 if (pst->st_ex_size > len) {
1498 /* the ftruncate should have worked */
1499 goto done;
1502 if (SMB_VFS_PWRITE(fsp, &c, 1, len-1)!=1) {
1503 goto done;
1506 result = 0;
1508 done:
1510 END_PROFILE(syscall_ftruncate);
1511 return result;
1514 static int vfswrap_fallocate(vfs_handle_struct *handle,
1515 files_struct *fsp,
1516 enum vfs_fallocate_mode mode,
1517 off_t offset,
1518 off_t len)
1520 int result;
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);
1527 } else {
1528 errno = EINVAL;
1529 result = -1;
1531 END_PROFILE(syscall_fallocate);
1532 return result;
1535 static bool vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int op, off_t offset, off_t count, int type)
1537 bool result;
1539 START_PROFILE(syscall_fcntl_lock);
1540 result = fcntl_lock(fsp->fh->fd, op, offset, count, type);
1541 END_PROFILE(syscall_fcntl_lock);
1542 return result;
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);
1551 return 0;
1554 static bool vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid)
1556 bool result;
1558 START_PROFILE(syscall_fcntl_getlock);
1559 result = fcntl_getlock(fsp->fh->fd, poffset, pcount, ptype, ppid);
1560 END_PROFILE(syscall_fcntl_getlock);
1561 return result;
1564 static int vfswrap_linux_setlease(vfs_handle_struct *handle, files_struct *fsp,
1565 int leasetype)
1567 int result = -1;
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) {
1574 return -1;
1577 result = linux_setlease(fsp->fh->fd, leasetype);
1578 #else
1579 errno = ENOSYS;
1580 #endif
1581 END_PROFILE(syscall_linux_setlease);
1582 return result;
1585 static int vfswrap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
1587 int result;
1589 START_PROFILE(syscall_symlink);
1590 result = symlink(oldpath, newpath);
1591 END_PROFILE(syscall_symlink);
1592 return result;
1595 static int vfswrap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz)
1597 int result;
1599 START_PROFILE(syscall_readlink);
1600 result = readlink(path, buf, bufsiz);
1601 END_PROFILE(syscall_readlink);
1602 return result;
1605 static int vfswrap_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
1607 int result;
1609 START_PROFILE(syscall_link);
1610 result = link(oldpath, newpath);
1611 END_PROFILE(syscall_link);
1612 return result;
1615 static int vfswrap_mknod(vfs_handle_struct *handle, const char *pathname, mode_t mode, SMB_DEV_T dev)
1617 int result;
1619 START_PROFILE(syscall_mknod);
1620 result = sys_mknod(pathname, mode, dev);
1621 END_PROFILE(syscall_mknod);
1622 return result;
1625 static char *vfswrap_realpath(vfs_handle_struct *handle, const char *path)
1627 char *result;
1629 START_PROFILE(syscall_realpath);
1630 #ifdef REALPATH_TAKES_NULL
1631 result = realpath(path, NULL);
1632 #else
1633 result = SMB_MALLOC_ARRAY(char, PATH_MAX+1);
1634 if (result) {
1635 char *resolved_path = realpath(path, result);
1636 if (!resolved_path) {
1637 SAFE_FREE(result);
1638 } else {
1639 /* SMB_ASSERT(result == resolved_path) ? */
1640 result = resolved_path;
1643 #endif
1644 END_PROFILE(syscall_realpath);
1645 return result;
1648 static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle,
1649 struct sys_notify_context *ctx,
1650 const char *path,
1651 uint32_t *filter,
1652 uint32_t *subdir_filter,
1653 void (*callback)(struct sys_notify_context *ctx,
1654 void *private_data,
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.
1666 #ifdef HAVE_INOTIFY
1667 if (lp_kernel_change_notify(vfs_handle->conn->params)) {
1668 return inotify_watch(ctx, path, filter, subdir_filter,
1669 callback, private_data, handle);
1671 #endif
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,
1679 unsigned int flags)
1681 #ifdef HAVE_CHFLAGS
1682 return chflags(path, flags);
1683 #else
1684 errno = ENOSYS;
1685 return -1;
1686 #endif
1689 static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle,
1690 const SMB_STRUCT_STAT *sbuf)
1692 struct file_id key;
1694 /* the ZERO_STRUCT ensures padding doesn't break using the key as a
1695 * blob */
1696 ZERO_STRUCT(key);
1698 key.devid = sbuf->st_ex_dev;
1699 key.inode = sbuf->st_ex_ino;
1700 /* key.extid is unused by default. */
1702 return key;
1705 static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
1706 struct files_struct *fsp,
1707 const char *fname,
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;
1714 int ret;
1716 if ((fsp != NULL) && (fsp->is_directory)) {
1718 * No default streams on directories
1720 goto done;
1723 if ((fsp != NULL) && (fsp->fh->fd != -1)) {
1724 ret = SMB_VFS_FSTAT(fsp, &sbuf);
1726 else {
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);
1734 } else {
1735 ret = SMB_VFS_STAT(handle->conn, &smb_fname);
1737 sbuf = smb_fname.st;
1740 if (ret == -1) {
1741 return map_nt_error_from_unix(errno);
1744 if (S_ISDIR(sbuf.st_ex_mode)) {
1745 goto done;
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);
1760 *pnum_streams += 1;
1761 *pstreams = tmp_streams;
1762 done:
1763 return NT_STATUS_OK;
1766 static int vfswrap_get_real_filename(struct vfs_handle_struct *handle,
1767 const char *path,
1768 const char *name,
1769 TALLOC_CTX *mem_ctx,
1770 char **found_name)
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.
1776 errno = EOPNOTSUPP;
1777 return -1;
1780 static const char *vfswrap_connectpath(struct vfs_handle_struct *handle,
1781 const char *fname)
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,
1789 bool blocking_lock,
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,
1820 files_struct *fsp,
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,
1830 files_struct *fsp,
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,
1842 files_struct *fsp,
1843 uint32 security_info,
1844 struct security_descriptor **ppdesc)
1846 NTSTATUS result;
1848 START_PROFILE(fget_nt_acl);
1849 result = posix_fget_nt_acl(fsp, security_info, ppdesc);
1850 END_PROFILE(fget_nt_acl);
1851 return result;
1854 static NTSTATUS vfswrap_get_nt_acl(vfs_handle_struct *handle,
1855 const char *name,
1856 uint32 security_info,
1857 struct security_descriptor **ppdesc)
1859 NTSTATUS result;
1861 START_PROFILE(get_nt_acl);
1862 result = posix_get_nt_acl(handle->conn, name, security_info, ppdesc);
1863 END_PROFILE(get_nt_acl);
1864 return result;
1867 static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, const struct security_descriptor *psd)
1869 NTSTATUS result;
1871 START_PROFILE(fset_nt_acl);
1872 result = set_nt_acl(fsp, security_info_sent, psd);
1873 END_PROFILE(fset_nt_acl);
1874 return result;
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)
1888 #ifdef HAVE_NO_ACL
1889 errno = ENOSYS;
1890 return -1;
1891 #else
1892 int result;
1894 START_PROFILE(chmod_acl);
1895 result = chmod_acl(handle->conn, name, mode);
1896 END_PROFILE(chmod_acl);
1897 return result;
1898 #endif
1901 static int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
1903 #ifdef HAVE_NO_ACL
1904 errno = ENOSYS;
1905 return -1;
1906 #else
1907 int result;
1909 START_PROFILE(fchmod_acl);
1910 result = fchmod_acl(fsp, mode);
1911 END_PROFILE(fchmod_acl);
1912 return result;
1913 #endif
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 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 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 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 flistxattr(fsp->fh->fd, list, size);
2050 static int vfswrap_removexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
2052 return removexattr(path, name);
2055 static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name)
2057 return 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 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 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)
2072 int ret;
2073 if (!initialize_async_io_handler()) {
2074 errno = ENOSYS;
2075 return -1;
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
2081 * different user.
2083 become_root();
2084 ret = sys_aio_read(aiocb);
2085 unbecome_root();
2086 return ret;
2089 static int vfswrap_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2091 int ret;
2092 if (!initialize_async_io_handler()) {
2093 errno = ENOSYS;
2094 return -1;
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
2100 * different user.
2102 become_root();
2103 ret = sys_aio_write(aiocb);
2104 unbecome_root();
2105 return ret;
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)
2135 return false;
2138 static bool vfswrap_is_offline(struct vfs_handle_struct *handle,
2139 const struct smb_filename *fname,
2140 SMB_STRUCT_STAT *sbuf)
2142 NTSTATUS status;
2143 char *path;
2144 bool offline = false;
2146 if (ISDOT(fname->base_name) || ISDOTDOT(fname->base_name)) {
2147 return false;
2150 if (!lp_dmapi_support(SNUM(handle->conn)) || !dmapi_have_session()) {
2151 #if defined(ENOTSUP)
2152 errno = ENOTSUP;
2153 #endif
2154 return false;
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);
2160 return false;
2163 offline = (dmapi_file_flags(path) & FILE_ATTRIBUTE_OFFLINE) != 0;
2165 TALLOC_FREE(path);
2167 return offline;
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)
2175 errno = ENOTSUP;
2176 #endif
2177 return -1;
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);