s3:smbd: change blocking.c to use fsp_fnum_dbg() for fsp->fnum logging.
[Samba/gebeck_regimport.git] / source3 / modules / vfs_default.c
blobb387cce109fdcbe640f427f82de8e51cae0c8c85
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 %s\n",
823 fsp_fnum_dbg(fsp)));
825 *out_len = (max_out_len >= 64) ? 64 : max_out_len;
826 /* Hmmm, will this cause problems if less data asked for? */
827 return_data = talloc_array(ctx, char, 64);
828 if (return_data == NULL) {
829 return NT_STATUS_NO_MEMORY;
832 /* For backwards compatibility only store the dev/inode. */
833 push_file_id_16(return_data, &fsp->file_id);
834 memcpy(return_data+16,create_volume_objectid(fsp->conn,objid),16);
835 push_file_id_16(return_data+32, &fsp->file_id);
836 *out_data = return_data;
837 return NT_STATUS_OK;
840 case FSCTL_GET_REPARSE_POINT:
842 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
843 DEBUG(10, ("FSCTL_GET_REPARSE_POINT: called on %s. "
844 "Status: NOT_IMPLEMENTED\n", fsp_fnum_dbg(fsp)));
845 return NT_STATUS_NOT_A_REPARSE_POINT;
848 case FSCTL_SET_REPARSE_POINT:
850 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
851 DEBUG(10, ("FSCTL_SET_REPARSE_POINT: called on %s. "
852 "Status: NOT_IMPLEMENTED\n", fsp_fnum_dbg(fsp)));
853 return NT_STATUS_NOT_A_REPARSE_POINT;
856 case FSCTL_GET_SHADOW_COPY_DATA:
859 * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
860 * and return their volume names. If max_data_count is 16, then it is just
861 * asking for the number of volumes and length of the combined names.
863 * pdata is the data allocated by our caller, but that uses
864 * total_data_count (which is 0 in our case) rather than max_data_count.
865 * Allocate the correct amount and return the pointer to let
866 * it be deallocated when we return.
868 struct shadow_copy_data *shadow_data = NULL;
869 bool labels = False;
870 uint32 labels_data_count = 0;
871 uint32 i;
872 char *cur_pdata = NULL;
874 if (max_out_len < 16) {
875 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
876 max_out_len));
877 return NT_STATUS_INVALID_PARAMETER;
880 if (max_out_len > 16) {
881 labels = True;
884 shadow_data = talloc_zero(ctx, struct shadow_copy_data);
885 if (shadow_data == NULL) {
886 DEBUG(0,("TALLOC_ZERO() failed!\n"));
887 return NT_STATUS_NO_MEMORY;
891 * Call the VFS routine to actually do the work.
893 if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) {
894 TALLOC_FREE(shadow_data);
895 if (errno == ENOSYS) {
896 DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n",
897 fsp->conn->connectpath));
898 return NT_STATUS_NOT_SUPPORTED;
899 } else {
900 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n",
901 fsp->conn->connectpath));
902 return NT_STATUS_UNSUCCESSFUL;
906 labels_data_count = (shadow_data->num_volumes * 2 *
907 sizeof(SHADOW_COPY_LABEL)) + 2;
909 if (!labels) {
910 *out_len = 16;
911 } else {
912 *out_len = 12 + labels_data_count + 4;
915 if (max_out_len < *out_len) {
916 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
917 max_out_len, *out_len));
918 TALLOC_FREE(shadow_data);
919 return NT_STATUS_BUFFER_TOO_SMALL;
922 cur_pdata = talloc_array(ctx, char, *out_len);
923 if (cur_pdata == NULL) {
924 TALLOC_FREE(shadow_data);
925 return NT_STATUS_NO_MEMORY;
928 *out_data = cur_pdata;
930 /* num_volumes 4 bytes */
931 SIVAL(cur_pdata, 0, shadow_data->num_volumes);
933 if (labels) {
934 /* num_labels 4 bytes */
935 SIVAL(cur_pdata, 4, shadow_data->num_volumes);
938 /* needed_data_count 4 bytes */
939 SIVAL(cur_pdata, 8, labels_data_count + 4);
941 cur_pdata += 12;
943 DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
944 shadow_data->num_volumes, fsp_str_dbg(fsp)));
945 if (labels && shadow_data->labels) {
946 for (i=0; i<shadow_data->num_volumes; i++) {
947 srvstr_push(cur_pdata, req_flags,
948 cur_pdata, shadow_data->labels[i],
949 2 * sizeof(SHADOW_COPY_LABEL),
950 STR_UNICODE|STR_TERMINATE);
951 cur_pdata += 2 * sizeof(SHADOW_COPY_LABEL);
952 DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i]));
956 TALLOC_FREE(shadow_data);
958 return NT_STATUS_OK;
961 case FSCTL_FIND_FILES_BY_SID:
963 /* pretend this succeeded -
965 * we have to send back a list with all files owned by this SID
967 * but I have to check that --metze
969 struct dom_sid sid;
970 uid_t uid;
971 size_t sid_len;
973 DEBUG(10, ("FSCTL_FIND_FILES_BY_SID: called on %s\n",
974 fsp_fnum_dbg(fsp)));
976 if (in_len < 8) {
977 /* NT_STATUS_BUFFER_TOO_SMALL maybe? */
978 return NT_STATUS_INVALID_PARAMETER;
981 sid_len = MIN(in_len - 4,SID_MAX_SIZE);
983 /* unknown 4 bytes: this is not the length of the sid :-( */
984 /*unknown = IVAL(pdata,0);*/
986 if (!sid_parse(in_data + 4, sid_len, &sid)) {
987 return NT_STATUS_INVALID_PARAMETER;
989 DEBUGADD(10, ("for SID: %s\n", sid_string_dbg(&sid)));
991 if (!sid_to_uid(&sid, &uid)) {
992 DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
993 sid_string_dbg(&sid),
994 (unsigned long)sid_len));
995 uid = (-1);
998 /* we can take a look at the find source :-)
1000 * find ./ -uid $uid -name '*' is what we need here
1003 * and send 4bytes len and then NULL terminated unicode strings
1004 * for each file
1006 * but I don't know how to deal with the paged results
1007 * (maybe we can hang the result anywhere in the fsp struct)
1009 * but I don't know how to deal with the paged results
1010 * (maybe we can hang the result anywhere in the fsp struct)
1012 * we don't send all files at once
1013 * and at the next we should *not* start from the beginning,
1014 * so we have to cache the result
1016 * --metze
1019 /* this works for now... */
1020 return NT_STATUS_OK;
1023 case FSCTL_QUERY_ALLOCATED_RANGES:
1025 /* FIXME: This is just a dummy reply, telling that all of the
1026 * file is allocated. MKS cp needs that.
1027 * Adding the real allocated ranges via FIEMAP on Linux
1028 * and SEEK_DATA/SEEK_HOLE on Solaris is needed to make
1029 * this FSCTL correct for sparse files.
1031 NTSTATUS status;
1032 uint64_t offset, length;
1033 char *out_data_tmp = NULL;
1035 if (in_len != 16) {
1036 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: data_count(%u) != 16 is invalid!\n",
1037 in_len));
1038 return NT_STATUS_INVALID_PARAMETER;
1041 if (max_out_len < 16) {
1042 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: max_out_len (%u) < 16 is invalid!\n",
1043 max_out_len));
1044 return NT_STATUS_INVALID_PARAMETER;
1047 offset = BVAL(in_data,0);
1048 length = BVAL(in_data,8);
1050 if (offset + length < offset) {
1051 /* No 64-bit integer wrap. */
1052 return NT_STATUS_INVALID_PARAMETER;
1055 /* Shouldn't this be SMB_VFS_STAT ... ? */
1056 status = vfs_stat_fsp(fsp);
1057 if (!NT_STATUS_IS_OK(status)) {
1058 return status;
1061 *out_len = 16;
1062 out_data_tmp = talloc_array(ctx, char, *out_len);
1063 if (out_data_tmp == NULL) {
1064 DEBUG(10, ("unable to allocate memory for response\n"));
1065 return NT_STATUS_NO_MEMORY;
1068 if (offset > fsp->fsp_name->st.st_ex_size ||
1069 fsp->fsp_name->st.st_ex_size == 0 ||
1070 length == 0) {
1071 memset(out_data_tmp, 0, *out_len);
1072 } else {
1073 uint64_t end = offset + length;
1074 end = MIN(end, fsp->fsp_name->st.st_ex_size);
1075 SBVAL(out_data_tmp, 0, 0);
1076 SBVAL(out_data_tmp, 8, end);
1079 *out_data = out_data_tmp;
1081 return NT_STATUS_OK;
1084 case FSCTL_IS_VOLUME_DIRTY:
1086 DEBUG(10,("FSCTL_IS_VOLUME_DIRTY: called on %s "
1087 "(but not implemented)\n", fsp_fnum_dbg(fsp)));
1089 * http://msdn.microsoft.com/en-us/library/cc232128%28PROT.10%29.aspx
1090 * says we have to respond with NT_STATUS_INVALID_PARAMETER
1092 return NT_STATUS_INVALID_PARAMETER;
1095 default:
1097 * Only print once ... unfortunately there could be lots of
1098 * different FSCTLs that are called.
1100 if (!vfswrap_logged_ioctl_message) {
1101 vfswrap_logged_ioctl_message = true;
1102 DEBUG(2, ("%s (0x%x): Currently not implemented.\n",
1103 __func__, function));
1107 return NT_STATUS_NOT_SUPPORTED;
1110 /********************************************************************
1111 Given a stat buffer return the allocated size on disk, taking into
1112 account sparse files.
1113 ********************************************************************/
1114 static uint64_t vfswrap_get_alloc_size(vfs_handle_struct *handle,
1115 struct files_struct *fsp,
1116 const SMB_STRUCT_STAT *sbuf)
1118 uint64_t result;
1120 START_PROFILE(syscall_get_alloc_size);
1122 if(S_ISDIR(sbuf->st_ex_mode)) {
1123 result = 0;
1124 goto out;
1127 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
1128 /* The type of st_blocksize is blkcnt_t which *MUST* be
1129 signed (according to POSIX) and can be less than 64-bits.
1130 Ensure when we're converting to 64 bits wide we don't
1131 sign extend. */
1132 #if defined(SIZEOF_BLKCNT_T_8)
1133 result = (uint64_t)STAT_ST_BLOCKSIZE * (uint64_t)sbuf->st_ex_blocks;
1134 #elif defined(SIZEOF_BLKCNT_T_4)
1136 uint64_t bs = ((uint64_t)sbuf->st_ex_blocks) & 0xFFFFFFFFLL;
1137 result = (uint64_t)STAT_ST_BLOCKSIZE * bs;
1139 #else
1140 #error SIZEOF_BLKCNT_T_NOT_A_SUPPORTED_VALUE
1141 #endif
1142 #else
1143 result = get_file_size_stat(sbuf);
1144 #endif
1146 if (fsp && fsp->initial_allocation_size)
1147 result = MAX(result,fsp->initial_allocation_size);
1149 result = smb_roundup(handle->conn, result);
1151 out:
1152 END_PROFILE(syscall_get_alloc_size);
1153 return result;
1156 static int vfswrap_unlink(vfs_handle_struct *handle,
1157 const struct smb_filename *smb_fname)
1159 int result = -1;
1161 START_PROFILE(syscall_unlink);
1163 if (smb_fname->stream_name) {
1164 errno = ENOENT;
1165 goto out;
1167 result = unlink(smb_fname->base_name);
1169 out:
1170 END_PROFILE(syscall_unlink);
1171 return result;
1174 static int vfswrap_chmod(vfs_handle_struct *handle, const char *path, mode_t mode)
1176 int result;
1178 START_PROFILE(syscall_chmod);
1181 * We need to do this due to the fact that the default POSIX ACL
1182 * chmod modifies the ACL *mask* for the group owner, not the
1183 * group owner bits directly. JRA.
1188 int saved_errno = errno; /* We might get ENOSYS */
1189 if ((result = SMB_VFS_CHMOD_ACL(handle->conn, path, mode)) == 0) {
1190 END_PROFILE(syscall_chmod);
1191 return result;
1193 /* Error - return the old errno. */
1194 errno = saved_errno;
1197 result = chmod(path, mode);
1198 END_PROFILE(syscall_chmod);
1199 return result;
1202 static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
1204 int result;
1206 START_PROFILE(syscall_fchmod);
1209 * We need to do this due to the fact that the default POSIX ACL
1210 * chmod modifies the ACL *mask* for the group owner, not the
1211 * group owner bits directly. JRA.
1215 int saved_errno = errno; /* We might get ENOSYS */
1216 if ((result = SMB_VFS_FCHMOD_ACL(fsp, mode)) == 0) {
1217 END_PROFILE(syscall_fchmod);
1218 return result;
1220 /* Error - return the old errno. */
1221 errno = saved_errno;
1224 #if defined(HAVE_FCHMOD)
1225 result = fchmod(fsp->fh->fd, mode);
1226 #else
1227 result = -1;
1228 errno = ENOSYS;
1229 #endif
1231 END_PROFILE(syscall_fchmod);
1232 return result;
1235 static int vfswrap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
1237 int result;
1239 START_PROFILE(syscall_chown);
1240 result = chown(path, uid, gid);
1241 END_PROFILE(syscall_chown);
1242 return result;
1245 static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t uid, gid_t gid)
1247 #ifdef HAVE_FCHOWN
1248 int result;
1250 START_PROFILE(syscall_fchown);
1251 result = fchown(fsp->fh->fd, uid, gid);
1252 END_PROFILE(syscall_fchown);
1253 return result;
1254 #else
1255 errno = ENOSYS;
1256 return -1;
1257 #endif
1260 static int vfswrap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
1262 int result;
1264 START_PROFILE(syscall_lchown);
1265 result = lchown(path, uid, gid);
1266 END_PROFILE(syscall_lchown);
1267 return result;
1270 static int vfswrap_chdir(vfs_handle_struct *handle, const char *path)
1272 int result;
1274 START_PROFILE(syscall_chdir);
1275 result = chdir(path);
1276 END_PROFILE(syscall_chdir);
1277 return result;
1280 static char *vfswrap_getwd(vfs_handle_struct *handle)
1282 char *result;
1284 START_PROFILE(syscall_getwd);
1285 result = sys_getwd();
1286 END_PROFILE(syscall_getwd);
1287 return result;
1290 /*********************************************************************
1291 nsec timestamp resolution call. Convert down to whatever the underlying
1292 system will support.
1293 **********************************************************************/
1295 static int vfswrap_ntimes(vfs_handle_struct *handle,
1296 const struct smb_filename *smb_fname,
1297 struct smb_file_time *ft)
1299 int result = -1;
1301 START_PROFILE(syscall_ntimes);
1303 if (smb_fname->stream_name) {
1304 errno = ENOENT;
1305 goto out;
1308 if (ft != NULL) {
1309 if (null_timespec(ft->atime)) {
1310 ft->atime= smb_fname->st.st_ex_atime;
1313 if (null_timespec(ft->mtime)) {
1314 ft->mtime = smb_fname->st.st_ex_mtime;
1317 if (!null_timespec(ft->create_time)) {
1318 set_create_timespec_ea(handle->conn,
1319 smb_fname,
1320 ft->create_time);
1323 if ((timespec_compare(&ft->atime,
1324 &smb_fname->st.st_ex_atime) == 0) &&
1325 (timespec_compare(&ft->mtime,
1326 &smb_fname->st.st_ex_mtime) == 0)) {
1327 return 0;
1331 #if defined(HAVE_UTIMENSAT)
1332 if (ft != NULL) {
1333 struct timespec ts[2];
1334 ts[0] = ft->atime;
1335 ts[1] = ft->mtime;
1336 result = utimensat(AT_FDCWD, smb_fname->base_name, ts, 0);
1337 } else {
1338 result = utimensat(AT_FDCWD, smb_fname->base_name, NULL, 0);
1340 if (!((result == -1) && (errno == ENOSYS))) {
1341 goto out;
1343 #endif
1344 #if defined(HAVE_UTIMES)
1345 if (ft != NULL) {
1346 struct timeval tv[2];
1347 tv[0] = convert_timespec_to_timeval(ft->atime);
1348 tv[1] = convert_timespec_to_timeval(ft->mtime);
1349 result = utimes(smb_fname->base_name, tv);
1350 } else {
1351 result = utimes(smb_fname->base_name, NULL);
1353 if (!((result == -1) && (errno == ENOSYS))) {
1354 goto out;
1356 #endif
1357 #if defined(HAVE_UTIME)
1358 if (ft != NULL) {
1359 struct utimbuf times;
1360 times.actime = convert_timespec_to_time_t(ft->atime);
1361 times.modtime = convert_timespec_to_time_t(ft->mtime);
1362 result = utime(smb_fname->base_name, &times);
1363 } else {
1364 result = utime(smb_fname->base_name, NULL);
1366 if (!((result == -1) && (errno == ENOSYS))) {
1367 goto out;
1369 #endif
1370 errno = ENOSYS;
1371 result = -1;
1373 out:
1374 END_PROFILE(syscall_ntimes);
1375 return result;
1378 /*********************************************************************
1379 A version of ftruncate that will write the space on disk if strict
1380 allocate is set.
1381 **********************************************************************/
1383 static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, off_t len)
1385 off_t space_to_write;
1386 uint64_t space_avail;
1387 uint64_t bsize,dfree,dsize;
1388 int ret;
1389 NTSTATUS status;
1390 SMB_STRUCT_STAT *pst;
1392 status = vfs_stat_fsp(fsp);
1393 if (!NT_STATUS_IS_OK(status)) {
1394 return -1;
1396 pst = &fsp->fsp_name->st;
1398 #ifdef S_ISFIFO
1399 if (S_ISFIFO(pst->st_ex_mode))
1400 return 0;
1401 #endif
1403 if (pst->st_ex_size == len)
1404 return 0;
1406 /* Shrink - just ftruncate. */
1407 if (pst->st_ex_size > len)
1408 return ftruncate(fsp->fh->fd, len);
1410 space_to_write = len - pst->st_ex_size;
1412 /* for allocation try fallocate first. This can fail on some
1413 platforms e.g. when the filesystem doesn't support it and no
1414 emulation is being done by the libc (like on AIX with JFS1). In that
1415 case we do our own emulation. fallocate implementations can
1416 return ENOTSUP or EINVAL in cases like that. */
1417 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
1418 pst->st_ex_size, space_to_write);
1419 if (ret == ENOSPC) {
1420 errno = ENOSPC;
1421 return -1;
1423 if (ret == 0) {
1424 return 0;
1426 DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with "
1427 "error %d. Falling back to slow manual allocation\n", ret));
1429 /* available disk space is enough or not? */
1430 space_avail = get_dfree_info(fsp->conn,
1431 fsp->fsp_name->base_name, false,
1432 &bsize,&dfree,&dsize);
1433 /* space_avail is 1k blocks */
1434 if (space_avail == (uint64_t)-1 ||
1435 ((uint64_t)space_to_write/1024 > space_avail) ) {
1436 errno = ENOSPC;
1437 return -1;
1440 /* Write out the real space on disk. */
1441 ret = vfs_slow_fallocate(fsp, pst->st_ex_size, space_to_write);
1442 if (ret != 0) {
1443 errno = ret;
1444 ret = -1;
1447 return 0;
1450 static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, off_t len)
1452 int result = -1;
1453 SMB_STRUCT_STAT *pst;
1454 NTSTATUS status;
1455 char c = 0;
1457 START_PROFILE(syscall_ftruncate);
1459 if (lp_strict_allocate(SNUM(fsp->conn)) && !fsp->is_sparse) {
1460 result = strict_allocate_ftruncate(handle, fsp, len);
1461 END_PROFILE(syscall_ftruncate);
1462 return result;
1465 /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
1466 ftruncate if the system supports it. Then I discovered that
1467 you can have some filesystems that support ftruncate
1468 expansion and some that don't! On Linux fat can't do
1469 ftruncate extend but ext2 can. */
1471 result = ftruncate(fsp->fh->fd, len);
1472 if (result == 0)
1473 goto done;
1475 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
1476 extend a file with ftruncate. Provide alternate implementation
1477 for this */
1479 /* Do an fstat to see if the file is longer than the requested
1480 size in which case the ftruncate above should have
1481 succeeded or shorter, in which case seek to len - 1 and
1482 write 1 byte of zero */
1483 status = vfs_stat_fsp(fsp);
1484 if (!NT_STATUS_IS_OK(status)) {
1485 goto done;
1487 pst = &fsp->fsp_name->st;
1489 #ifdef S_ISFIFO
1490 if (S_ISFIFO(pst->st_ex_mode)) {
1491 result = 0;
1492 goto done;
1494 #endif
1496 if (pst->st_ex_size == len) {
1497 result = 0;
1498 goto done;
1501 if (pst->st_ex_size > len) {
1502 /* the ftruncate should have worked */
1503 goto done;
1506 if (SMB_VFS_PWRITE(fsp, &c, 1, len-1)!=1) {
1507 goto done;
1510 result = 0;
1512 done:
1514 END_PROFILE(syscall_ftruncate);
1515 return result;
1518 static int vfswrap_fallocate(vfs_handle_struct *handle,
1519 files_struct *fsp,
1520 enum vfs_fallocate_mode mode,
1521 off_t offset,
1522 off_t len)
1524 int result;
1526 START_PROFILE(syscall_fallocate);
1527 if (mode == VFS_FALLOCATE_EXTEND_SIZE) {
1528 result = sys_posix_fallocate(fsp->fh->fd, offset, len);
1529 } else if (mode == VFS_FALLOCATE_KEEP_SIZE) {
1530 result = sys_fallocate(fsp->fh->fd, mode, offset, len);
1531 } else {
1532 errno = EINVAL;
1533 result = -1;
1535 END_PROFILE(syscall_fallocate);
1536 return result;
1539 static bool vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int op, off_t offset, off_t count, int type)
1541 bool result;
1543 START_PROFILE(syscall_fcntl_lock);
1544 result = fcntl_lock(fsp->fh->fd, op, offset, count, type);
1545 END_PROFILE(syscall_fcntl_lock);
1546 return result;
1549 static int vfswrap_kernel_flock(vfs_handle_struct *handle, files_struct *fsp,
1550 uint32 share_mode, uint32 access_mask)
1552 START_PROFILE(syscall_kernel_flock);
1553 kernel_flock(fsp->fh->fd, share_mode, access_mask);
1554 END_PROFILE(syscall_kernel_flock);
1555 return 0;
1558 static bool vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid)
1560 bool result;
1562 START_PROFILE(syscall_fcntl_getlock);
1563 result = fcntl_getlock(fsp->fh->fd, poffset, pcount, ptype, ppid);
1564 END_PROFILE(syscall_fcntl_getlock);
1565 return result;
1568 static int vfswrap_linux_setlease(vfs_handle_struct *handle, files_struct *fsp,
1569 int leasetype)
1571 int result = -1;
1573 START_PROFILE(syscall_linux_setlease);
1575 #ifdef HAVE_KERNEL_OPLOCKS_LINUX
1576 /* first set the signal handler */
1577 if(linux_set_lease_sighandler(fsp->fh->fd) == -1) {
1578 return -1;
1581 result = linux_setlease(fsp->fh->fd, leasetype);
1582 #else
1583 errno = ENOSYS;
1584 #endif
1585 END_PROFILE(syscall_linux_setlease);
1586 return result;
1589 static int vfswrap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
1591 int result;
1593 START_PROFILE(syscall_symlink);
1594 result = symlink(oldpath, newpath);
1595 END_PROFILE(syscall_symlink);
1596 return result;
1599 static int vfswrap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz)
1601 int result;
1603 START_PROFILE(syscall_readlink);
1604 result = readlink(path, buf, bufsiz);
1605 END_PROFILE(syscall_readlink);
1606 return result;
1609 static int vfswrap_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
1611 int result;
1613 START_PROFILE(syscall_link);
1614 result = link(oldpath, newpath);
1615 END_PROFILE(syscall_link);
1616 return result;
1619 static int vfswrap_mknod(vfs_handle_struct *handle, const char *pathname, mode_t mode, SMB_DEV_T dev)
1621 int result;
1623 START_PROFILE(syscall_mknod);
1624 result = sys_mknod(pathname, mode, dev);
1625 END_PROFILE(syscall_mknod);
1626 return result;
1629 static char *vfswrap_realpath(vfs_handle_struct *handle, const char *path)
1631 char *result;
1633 START_PROFILE(syscall_realpath);
1634 #ifdef REALPATH_TAKES_NULL
1635 result = realpath(path, NULL);
1636 #else
1637 result = SMB_MALLOC_ARRAY(char, PATH_MAX+1);
1638 if (result) {
1639 char *resolved_path = realpath(path, result);
1640 if (!resolved_path) {
1641 SAFE_FREE(result);
1642 } else {
1643 /* SMB_ASSERT(result == resolved_path) ? */
1644 result = resolved_path;
1647 #endif
1648 END_PROFILE(syscall_realpath);
1649 return result;
1652 static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle,
1653 struct sys_notify_context *ctx,
1654 const char *path,
1655 uint32_t *filter,
1656 uint32_t *subdir_filter,
1657 void (*callback)(struct sys_notify_context *ctx,
1658 void *private_data,
1659 struct notify_event *ev),
1660 void *private_data, void *handle)
1663 * So far inotify is the only supported default notify mechanism. If
1664 * another platform like the the BSD's or a proprietary Unix comes
1665 * along and wants another default, we can play the same trick we
1666 * played with Posix ACLs.
1668 * Until that is the case, hard-code inotify here.
1670 #ifdef HAVE_INOTIFY
1671 if (lp_kernel_change_notify(vfs_handle->conn->params)) {
1672 return inotify_watch(ctx, path, filter, subdir_filter,
1673 callback, private_data, handle);
1675 #endif
1677 * Do nothing, leave everything to notify_internal.c
1679 return NT_STATUS_OK;
1682 static int vfswrap_chflags(vfs_handle_struct *handle, const char *path,
1683 unsigned int flags)
1685 #ifdef HAVE_CHFLAGS
1686 return chflags(path, flags);
1687 #else
1688 errno = ENOSYS;
1689 return -1;
1690 #endif
1693 static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle,
1694 const SMB_STRUCT_STAT *sbuf)
1696 struct file_id key;
1698 /* the ZERO_STRUCT ensures padding doesn't break using the key as a
1699 * blob */
1700 ZERO_STRUCT(key);
1702 key.devid = sbuf->st_ex_dev;
1703 key.inode = sbuf->st_ex_ino;
1704 /* key.extid is unused by default. */
1706 return key;
1709 static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
1710 struct files_struct *fsp,
1711 const char *fname,
1712 TALLOC_CTX *mem_ctx,
1713 unsigned int *pnum_streams,
1714 struct stream_struct **pstreams)
1716 SMB_STRUCT_STAT sbuf;
1717 struct stream_struct *tmp_streams = NULL;
1718 int ret;
1720 if ((fsp != NULL) && (fsp->is_directory)) {
1722 * No default streams on directories
1724 goto done;
1727 if ((fsp != NULL) && (fsp->fh->fd != -1)) {
1728 ret = SMB_VFS_FSTAT(fsp, &sbuf);
1730 else {
1731 struct smb_filename smb_fname;
1733 ZERO_STRUCT(smb_fname);
1734 smb_fname.base_name = discard_const_p(char, fname);
1736 if (lp_posix_pathnames()) {
1737 ret = SMB_VFS_LSTAT(handle->conn, &smb_fname);
1738 } else {
1739 ret = SMB_VFS_STAT(handle->conn, &smb_fname);
1741 sbuf = smb_fname.st;
1744 if (ret == -1) {
1745 return map_nt_error_from_unix(errno);
1748 if (S_ISDIR(sbuf.st_ex_mode)) {
1749 goto done;
1752 tmp_streams = talloc_realloc(mem_ctx, *pstreams, struct stream_struct,
1753 (*pnum_streams) + 1);
1754 if (tmp_streams == NULL) {
1755 return NT_STATUS_NO_MEMORY;
1757 tmp_streams[*pnum_streams].name = talloc_strdup(tmp_streams, "::$DATA");
1758 if (tmp_streams[*pnum_streams].name == NULL) {
1759 return NT_STATUS_NO_MEMORY;
1761 tmp_streams[*pnum_streams].size = sbuf.st_ex_size;
1762 tmp_streams[*pnum_streams].alloc_size = SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp, &sbuf);
1764 *pnum_streams += 1;
1765 *pstreams = tmp_streams;
1766 done:
1767 return NT_STATUS_OK;
1770 static int vfswrap_get_real_filename(struct vfs_handle_struct *handle,
1771 const char *path,
1772 const char *name,
1773 TALLOC_CTX *mem_ctx,
1774 char **found_name)
1777 * Don't fall back to get_real_filename so callers can differentiate
1778 * between a full directory scan and an actual case-insensitive stat.
1780 errno = EOPNOTSUPP;
1781 return -1;
1784 static const char *vfswrap_connectpath(struct vfs_handle_struct *handle,
1785 const char *fname)
1787 return handle->conn->connectpath;
1790 static NTSTATUS vfswrap_brl_lock_windows(struct vfs_handle_struct *handle,
1791 struct byte_range_lock *br_lck,
1792 struct lock_struct *plock,
1793 bool blocking_lock,
1794 struct blocking_lock_record *blr)
1796 SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1798 /* Note: blr is not used in the default implementation. */
1799 return brl_lock_windows_default(br_lck, plock, blocking_lock);
1802 static bool vfswrap_brl_unlock_windows(struct vfs_handle_struct *handle,
1803 struct messaging_context *msg_ctx,
1804 struct byte_range_lock *br_lck,
1805 const struct lock_struct *plock)
1807 SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1809 return brl_unlock_windows_default(msg_ctx, br_lck, plock);
1812 static bool vfswrap_brl_cancel_windows(struct vfs_handle_struct *handle,
1813 struct byte_range_lock *br_lck,
1814 struct lock_struct *plock,
1815 struct blocking_lock_record *blr)
1817 SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1819 /* Note: blr is not used in the default implementation. */
1820 return brl_lock_cancel_default(br_lck, plock);
1823 static bool vfswrap_strict_lock(struct vfs_handle_struct *handle,
1824 files_struct *fsp,
1825 struct lock_struct *plock)
1827 SMB_ASSERT(plock->lock_type == READ_LOCK ||
1828 plock->lock_type == WRITE_LOCK);
1830 return strict_lock_default(fsp, plock);
1833 static void vfswrap_strict_unlock(struct vfs_handle_struct *handle,
1834 files_struct *fsp,
1835 struct lock_struct *plock)
1837 SMB_ASSERT(plock->lock_type == READ_LOCK ||
1838 plock->lock_type == WRITE_LOCK);
1840 strict_unlock_default(fsp, plock);
1843 /* NT ACL operations. */
1845 static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle,
1846 files_struct *fsp,
1847 uint32 security_info,
1848 struct security_descriptor **ppdesc)
1850 NTSTATUS result;
1852 START_PROFILE(fget_nt_acl);
1853 result = posix_fget_nt_acl(fsp, security_info, ppdesc);
1854 END_PROFILE(fget_nt_acl);
1855 return result;
1858 static NTSTATUS vfswrap_get_nt_acl(vfs_handle_struct *handle,
1859 const char *name,
1860 uint32 security_info,
1861 struct security_descriptor **ppdesc)
1863 NTSTATUS result;
1865 START_PROFILE(get_nt_acl);
1866 result = posix_get_nt_acl(handle->conn, name, security_info, ppdesc);
1867 END_PROFILE(get_nt_acl);
1868 return result;
1871 static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, const struct security_descriptor *psd)
1873 NTSTATUS result;
1875 START_PROFILE(fset_nt_acl);
1876 result = set_nt_acl(fsp, security_info_sent, psd);
1877 END_PROFILE(fset_nt_acl);
1878 return result;
1881 static NTSTATUS vfswrap_audit_file(struct vfs_handle_struct *handle,
1882 struct smb_filename *file,
1883 struct security_acl *sacl,
1884 uint32_t access_requested,
1885 uint32_t access_denied)
1887 return NT_STATUS_OK; /* Nothing to do here ... */
1890 static int vfswrap_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode)
1892 #ifdef HAVE_NO_ACL
1893 errno = ENOSYS;
1894 return -1;
1895 #else
1896 int result;
1898 START_PROFILE(chmod_acl);
1899 result = chmod_acl(handle->conn, name, mode);
1900 END_PROFILE(chmod_acl);
1901 return result;
1902 #endif
1905 static int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
1907 #ifdef HAVE_NO_ACL
1908 errno = ENOSYS;
1909 return -1;
1910 #else
1911 int result;
1913 START_PROFILE(fchmod_acl);
1914 result = fchmod_acl(fsp, mode);
1915 END_PROFILE(fchmod_acl);
1916 return result;
1917 #endif
1920 static int vfswrap_sys_acl_get_entry(vfs_handle_struct *handle, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1922 return sys_acl_get_entry(theacl, entry_id, entry_p);
1925 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)
1927 return sys_acl_get_tag_type(entry_d, tag_type_p);
1930 static int vfswrap_sys_acl_get_permset(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1932 return sys_acl_get_permset(entry_d, permset_p);
1935 static void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d)
1937 return sys_acl_get_qualifier(entry_d);
1940 static SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, SMB_ACL_TYPE_T type)
1942 return sys_acl_get_file(handle, path_p, type);
1945 static SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp)
1947 return sys_acl_get_fd(handle, fsp);
1950 static int vfswrap_sys_acl_clear_perms(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset)
1952 return sys_acl_clear_perms(permset);
1955 static int vfswrap_sys_acl_add_perm(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1957 return sys_acl_add_perm(permset, perm);
1960 static char * vfswrap_sys_acl_to_text(vfs_handle_struct *handle, SMB_ACL_T theacl, ssize_t *plen)
1962 return sys_acl_to_text(theacl, plen);
1965 static SMB_ACL_T vfswrap_sys_acl_init(vfs_handle_struct *handle, int count)
1967 return sys_acl_init(count);
1970 static int vfswrap_sys_acl_create_entry(vfs_handle_struct *handle, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
1972 return sys_acl_create_entry(pacl, pentry);
1975 static int vfswrap_sys_acl_set_tag_type(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
1977 return sys_acl_set_tag_type(entry, tagtype);
1980 static int vfswrap_sys_acl_set_qualifier(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, void *qual)
1982 return sys_acl_set_qualifier(entry, qual);
1985 static int vfswrap_sys_acl_set_permset(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
1987 return sys_acl_set_permset(entry, permset);
1990 static int vfswrap_sys_acl_valid(vfs_handle_struct *handle, SMB_ACL_T theacl )
1992 return sys_acl_valid(theacl );
1995 static int vfswrap_sys_acl_set_file(vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
1997 return sys_acl_set_file(handle, name, acltype, theacl);
2000 static int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_T theacl)
2002 return sys_acl_set_fd(handle, fsp, theacl);
2005 static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle, const char *path)
2007 return sys_acl_delete_def_file(handle, path);
2010 static int vfswrap_sys_acl_get_perm(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2012 return sys_acl_get_perm(permset, perm);
2015 static int vfswrap_sys_acl_free_text(vfs_handle_struct *handle, char *text)
2017 return sys_acl_free_text(text);
2020 static int vfswrap_sys_acl_free_acl(vfs_handle_struct *handle, SMB_ACL_T posix_acl)
2022 return sys_acl_free_acl(posix_acl);
2025 static int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle, void *qualifier, SMB_ACL_TAG_T tagtype)
2027 return sys_acl_free_qualifier(qualifier, tagtype);
2030 /****************************************************************
2031 Extended attribute operations.
2032 *****************************************************************/
2034 static ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
2036 return getxattr(path, name, value, size);
2039 static ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, void *value, size_t size)
2041 return fgetxattr(fsp->fh->fd, name, value, size);
2044 static ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
2046 return listxattr(path, list, size);
2049 static ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size)
2051 return flistxattr(fsp->fh->fd, list, size);
2054 static int vfswrap_removexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
2056 return removexattr(path, name);
2059 static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name)
2061 return fremovexattr(fsp->fh->fd, name);
2064 static int vfswrap_setxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
2066 return setxattr(path, name, value, size, flags);
2069 static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, const void *value, size_t size, int flags)
2071 return fsetxattr(fsp->fh->fd, name, value, size, flags);
2074 static int vfswrap_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2076 int ret;
2077 if (!initialize_async_io_handler()) {
2078 errno = ENOSYS;
2079 return -1;
2082 * aio_read must be done as root, because in the glibc aio
2083 * implementation the helper thread needs to be able to send a signal
2084 * to the main thread, even when it has done a seteuid() to a
2085 * different user.
2087 become_root();
2088 ret = sys_aio_read(aiocb);
2089 unbecome_root();
2090 return ret;
2093 static int vfswrap_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2095 int ret;
2096 if (!initialize_async_io_handler()) {
2097 errno = ENOSYS;
2098 return -1;
2101 * aio_write must be done as root, because in the glibc aio
2102 * implementation the helper thread needs to be able to send a signal
2103 * to the main thread, even when it has done a seteuid() to a
2104 * different user.
2106 become_root();
2107 ret = sys_aio_write(aiocb);
2108 unbecome_root();
2109 return ret;
2112 static ssize_t vfswrap_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2114 return sys_aio_return(aiocb);
2117 static int vfswrap_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2119 return sys_aio_cancel(fsp->fh->fd, aiocb);
2122 static int vfswrap_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2124 return sys_aio_error(aiocb);
2127 static int vfswrap_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb)
2129 return sys_aio_fsync(op, aiocb);
2132 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)
2134 return sys_aio_suspend(aiocb, n, timeout);
2137 static bool vfswrap_aio_force(struct vfs_handle_struct *handle, struct files_struct *fsp)
2139 return false;
2142 static bool vfswrap_is_offline(struct vfs_handle_struct *handle,
2143 const struct smb_filename *fname,
2144 SMB_STRUCT_STAT *sbuf)
2146 NTSTATUS status;
2147 char *path;
2148 bool offline = false;
2150 if (ISDOT(fname->base_name) || ISDOTDOT(fname->base_name)) {
2151 return false;
2154 if (!lp_dmapi_support(SNUM(handle->conn)) || !dmapi_have_session()) {
2155 #if defined(ENOTSUP)
2156 errno = ENOTSUP;
2157 #endif
2158 return false;
2161 status = get_full_smb_filename(talloc_tos(), fname, &path);
2162 if (!NT_STATUS_IS_OK(status)) {
2163 errno = map_errno_from_nt_status(status);
2164 return false;
2167 offline = (dmapi_file_flags(path) & FILE_ATTRIBUTE_OFFLINE) != 0;
2169 TALLOC_FREE(path);
2171 return offline;
2174 static int vfswrap_set_offline(struct vfs_handle_struct *handle,
2175 const struct smb_filename *fname)
2177 /* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */
2178 #if defined(ENOTSUP)
2179 errno = ENOTSUP;
2180 #endif
2181 return -1;
2184 static struct vfs_fn_pointers vfs_default_fns = {
2185 /* Disk operations */
2187 .connect_fn = vfswrap_connect,
2188 .disconnect_fn = vfswrap_disconnect,
2189 .disk_free_fn = vfswrap_disk_free,
2190 .get_quota_fn = vfswrap_get_quota,
2191 .set_quota_fn = vfswrap_set_quota,
2192 .get_shadow_copy_data_fn = vfswrap_get_shadow_copy_data,
2193 .statvfs_fn = vfswrap_statvfs,
2194 .fs_capabilities_fn = vfswrap_fs_capabilities,
2195 .get_dfs_referrals_fn = vfswrap_get_dfs_referrals,
2197 /* Directory operations */
2199 .opendir_fn = vfswrap_opendir,
2200 .fdopendir_fn = vfswrap_fdopendir,
2201 .readdir_fn = vfswrap_readdir,
2202 .seekdir_fn = vfswrap_seekdir,
2203 .telldir_fn = vfswrap_telldir,
2204 .rewind_dir_fn = vfswrap_rewinddir,
2205 .mkdir_fn = vfswrap_mkdir,
2206 .rmdir_fn = vfswrap_rmdir,
2207 .closedir_fn = vfswrap_closedir,
2208 .init_search_op_fn = vfswrap_init_search_op,
2210 /* File operations */
2212 .open_fn = vfswrap_open,
2213 .create_file_fn = vfswrap_create_file,
2214 .close_fn = vfswrap_close,
2215 .read_fn = vfswrap_read,
2216 .pread_fn = vfswrap_pread,
2217 .write_fn = vfswrap_write,
2218 .pwrite_fn = vfswrap_pwrite,
2219 .lseek_fn = vfswrap_lseek,
2220 .sendfile_fn = vfswrap_sendfile,
2221 .recvfile_fn = vfswrap_recvfile,
2222 .rename_fn = vfswrap_rename,
2223 .fsync_fn = vfswrap_fsync,
2224 .stat_fn = vfswrap_stat,
2225 .fstat_fn = vfswrap_fstat,
2226 .lstat_fn = vfswrap_lstat,
2227 .get_alloc_size_fn = vfswrap_get_alloc_size,
2228 .unlink_fn = vfswrap_unlink,
2229 .chmod_fn = vfswrap_chmod,
2230 .fchmod_fn = vfswrap_fchmod,
2231 .chown_fn = vfswrap_chown,
2232 .fchown_fn = vfswrap_fchown,
2233 .lchown_fn = vfswrap_lchown,
2234 .chdir_fn = vfswrap_chdir,
2235 .getwd_fn = vfswrap_getwd,
2236 .ntimes_fn = vfswrap_ntimes,
2237 .ftruncate_fn = vfswrap_ftruncate,
2238 .fallocate_fn = vfswrap_fallocate,
2239 .lock_fn = vfswrap_lock,
2240 .kernel_flock_fn = vfswrap_kernel_flock,
2241 .linux_setlease_fn = vfswrap_linux_setlease,
2242 .getlock_fn = vfswrap_getlock,
2243 .symlink_fn = vfswrap_symlink,
2244 .readlink_fn = vfswrap_readlink,
2245 .link_fn = vfswrap_link,
2246 .mknod_fn = vfswrap_mknod,
2247 .realpath_fn = vfswrap_realpath,
2248 .notify_watch_fn = vfswrap_notify_watch,
2249 .chflags_fn = vfswrap_chflags,
2250 .file_id_create_fn = vfswrap_file_id_create,
2251 .streaminfo_fn = vfswrap_streaminfo,
2252 .get_real_filename_fn = vfswrap_get_real_filename,
2253 .connectpath_fn = vfswrap_connectpath,
2254 .brl_lock_windows_fn = vfswrap_brl_lock_windows,
2255 .brl_unlock_windows_fn = vfswrap_brl_unlock_windows,
2256 .brl_cancel_windows_fn = vfswrap_brl_cancel_windows,
2257 .strict_lock_fn = vfswrap_strict_lock,
2258 .strict_unlock_fn = vfswrap_strict_unlock,
2259 .translate_name_fn = vfswrap_translate_name,
2260 .fsctl_fn = vfswrap_fsctl,
2262 /* NT ACL operations. */
2264 .fget_nt_acl_fn = vfswrap_fget_nt_acl,
2265 .get_nt_acl_fn = vfswrap_get_nt_acl,
2266 .fset_nt_acl_fn = vfswrap_fset_nt_acl,
2267 .audit_file_fn = vfswrap_audit_file,
2269 /* POSIX ACL operations. */
2271 .chmod_acl_fn = vfswrap_chmod_acl,
2272 .fchmod_acl_fn = vfswrap_fchmod_acl,
2274 .sys_acl_get_entry_fn = vfswrap_sys_acl_get_entry,
2275 .sys_acl_get_tag_type_fn = vfswrap_sys_acl_get_tag_type,
2276 .sys_acl_get_permset_fn = vfswrap_sys_acl_get_permset,
2277 .sys_acl_get_qualifier_fn = vfswrap_sys_acl_get_qualifier,
2278 .sys_acl_get_file_fn = vfswrap_sys_acl_get_file,
2279 .sys_acl_get_fd_fn = vfswrap_sys_acl_get_fd,
2280 .sys_acl_clear_perms_fn = vfswrap_sys_acl_clear_perms,
2281 .sys_acl_add_perm_fn = vfswrap_sys_acl_add_perm,
2282 .sys_acl_to_text_fn = vfswrap_sys_acl_to_text,
2283 .sys_acl_init_fn = vfswrap_sys_acl_init,
2284 .sys_acl_create_entry_fn = vfswrap_sys_acl_create_entry,
2285 .sys_acl_set_tag_type_fn = vfswrap_sys_acl_set_tag_type,
2286 .sys_acl_set_qualifier_fn = vfswrap_sys_acl_set_qualifier,
2287 .sys_acl_set_permset_fn = vfswrap_sys_acl_set_permset,
2288 .sys_acl_valid_fn = vfswrap_sys_acl_valid,
2289 .sys_acl_set_file_fn = vfswrap_sys_acl_set_file,
2290 .sys_acl_set_fd_fn = vfswrap_sys_acl_set_fd,
2291 .sys_acl_delete_def_file_fn = vfswrap_sys_acl_delete_def_file,
2292 .sys_acl_get_perm_fn = vfswrap_sys_acl_get_perm,
2293 .sys_acl_free_text_fn = vfswrap_sys_acl_free_text,
2294 .sys_acl_free_acl_fn = vfswrap_sys_acl_free_acl,
2295 .sys_acl_free_qualifier_fn = vfswrap_sys_acl_free_qualifier,
2297 /* EA operations. */
2298 .getxattr_fn = vfswrap_getxattr,
2299 .fgetxattr_fn = vfswrap_fgetxattr,
2300 .listxattr_fn = vfswrap_listxattr,
2301 .flistxattr_fn = vfswrap_flistxattr,
2302 .removexattr_fn = vfswrap_removexattr,
2303 .fremovexattr_fn = vfswrap_fremovexattr,
2304 .setxattr_fn = vfswrap_setxattr,
2305 .fsetxattr_fn = vfswrap_fsetxattr,
2307 /* aio operations */
2308 .aio_read_fn = vfswrap_aio_read,
2309 .aio_write_fn = vfswrap_aio_write,
2310 .aio_return_fn = vfswrap_aio_return,
2311 .aio_cancel_fn = vfswrap_aio_cancel,
2312 .aio_error_fn = vfswrap_aio_error,
2313 .aio_fsync_fn = vfswrap_aio_fsync,
2314 .aio_suspend_fn = vfswrap_aio_suspend,
2315 .aio_force_fn = vfswrap_aio_force,
2317 /* offline operations */
2318 .is_offline_fn = vfswrap_is_offline,
2319 .set_offline_fn = vfswrap_set_offline
2322 NTSTATUS vfs_default_init(void);
2323 NTSTATUS vfs_default_init(void)
2325 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
2326 DEFAULT_VFS_MODULE_NAME, &vfs_default_fns);