2 Unix SMB/CIFS implementation.
3 Wrap disk only vfs functions to sidestep dodgy compilers.
4 Copyright (C) Tim Potter 1998
5 Copyright (C) Jeremy Allison 2007
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "system/time.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "smbd/globals.h"
27 #include "smbprofile.h"
28 #include "../libcli/security/security.h"
29 #include "passdb/lookup_sid.h"
30 #include "source3/include/msdfs.h"
31 #include "librpc/gen_ndr/ndr_dfsblobs.h"
32 #include "lib/util/tevent_unix.h"
35 #define DBGC_CLASS DBGC_VFS
37 /* Check for NULL pointer parameters in vfswrap_* functions */
39 /* We don't want to have NULL function pointers lying around. Someone
40 is sure to try and execute them. These stubs are used to prevent
43 static int vfswrap_connect(vfs_handle_struct *handle, const char *service, const char *user)
45 return 0; /* Return >= 0 for success */
48 static void vfswrap_disconnect(vfs_handle_struct *handle)
54 static uint64_t vfswrap_disk_free(vfs_handle_struct *handle, const char *path, bool small_query, uint64_t *bsize,
55 uint64_t *dfree, uint64_t *dsize)
59 result = sys_disk_free(handle->conn, path, small_query, bsize, dfree, dsize);
63 static int vfswrap_get_quota(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
65 #ifdef HAVE_SYS_QUOTAS
68 START_PROFILE(syscall_get_quota);
69 result = sys_get_quota(handle->conn->connectpath, qtype, id, qt);
70 END_PROFILE(syscall_get_quota);
78 static int vfswrap_set_quota(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
80 #ifdef HAVE_SYS_QUOTAS
83 START_PROFILE(syscall_set_quota);
84 result = sys_set_quota(handle->conn->connectpath, qtype, id, qt);
85 END_PROFILE(syscall_set_quota);
93 static int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle,
94 struct files_struct *fsp,
95 struct shadow_copy_data *shadow_copy_data,
99 return -1; /* Not implemented. */
102 static int vfswrap_statvfs(struct vfs_handle_struct *handle, const char *path, vfs_statvfs_struct *statbuf)
104 return sys_statvfs(path, statbuf);
107 static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle,
108 enum timestamp_set_resolution *p_ts_res)
110 connection_struct *conn = handle->conn;
111 uint32_t caps = FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
112 struct smb_filename *smb_fname_cpath = NULL;
113 struct vfs_statvfs_struct statbuf;
117 ZERO_STRUCT(statbuf);
118 ret = sys_statvfs(conn->connectpath, &statbuf);
120 caps = statbuf.FsCapabilities;
123 *p_ts_res = TIMESTAMP_SET_SECONDS;
125 /* Work out what timestamp resolution we can
126 * use when setting a timestamp. */
128 status = create_synthetic_smb_fname(talloc_tos(),
133 if (!NT_STATUS_IS_OK(status)) {
137 ret = SMB_VFS_STAT(conn, smb_fname_cpath);
139 TALLOC_FREE(smb_fname_cpath);
143 if (smb_fname_cpath->st.st_ex_mtime.tv_nsec ||
144 smb_fname_cpath->st.st_ex_atime.tv_nsec ||
145 smb_fname_cpath->st.st_ex_ctime.tv_nsec) {
146 /* If any of the normal UNIX directory timestamps
147 * have a non-zero tv_nsec component assume
148 * we might be able to set sub-second timestamps.
149 * See what filetime set primitives we have.
151 #if defined(HAVE_UTIMENSAT)
152 *p_ts_res = TIMESTAMP_SET_NT_OR_BETTER;
153 #elif defined(HAVE_UTIMES)
154 /* utimes allows msec timestamps to be set. */
155 *p_ts_res = TIMESTAMP_SET_MSEC;
156 #elif defined(HAVE_UTIME)
157 /* utime only allows sec timestamps to be set. */
158 *p_ts_res = TIMESTAMP_SET_SECONDS;
161 DEBUG(10,("vfswrap_fs_capabilities: timestamp "
163 "available on share %s, directory %s\n",
164 *p_ts_res == TIMESTAMP_SET_MSEC ? "msec" : "sec",
165 lp_servicename(talloc_tos(), conn->params->service),
166 conn->connectpath ));
168 TALLOC_FREE(smb_fname_cpath);
172 static NTSTATUS vfswrap_get_dfs_referrals(struct vfs_handle_struct *handle,
173 struct dfs_GetDFSReferral *r)
175 struct junction_map *junction = NULL;
177 bool self_referral = false;
178 char *pathnamep = NULL;
179 char *local_dfs_path = NULL;
182 uint16_t max_referral_level = r->in.req.max_referral_level;
185 NDR_PRINT_IN_DEBUG(dfs_GetDFSReferral, r);
188 /* get the junction entry */
189 if (r->in.req.servername == NULL) {
190 return NT_STATUS_NOT_FOUND;
194 * Trim pathname sent by client so it begins with only one backslash.
195 * Two backslashes confuse some dfs clients
198 local_dfs_path = talloc_strdup(r, r->in.req.servername);
199 if (local_dfs_path == NULL) {
200 return NT_STATUS_NO_MEMORY;
202 pathnamep = local_dfs_path;
203 while (IS_DIRECTORY_SEP(pathnamep[0]) &&
204 IS_DIRECTORY_SEP(pathnamep[1])) {
208 junction = talloc_zero(r, struct junction_map);
209 if (junction == NULL) {
210 return NT_STATUS_NO_MEMORY;
213 /* The following call can change cwd. */
214 status = get_referred_path(r, pathnamep,
215 !handle->conn->sconn->using_smb2,
216 junction, &consumedcnt, &self_referral);
217 if (!NT_STATUS_IS_OK(status)) {
218 vfs_ChDir(handle->conn, handle->conn->connectpath);
221 vfs_ChDir(handle->conn, handle->conn->connectpath);
223 if (!self_referral) {
224 pathnamep[consumedcnt] = '\0';
227 dbgtext("setup_dfs_referral: Path %s to "
228 "alternate path(s):",
230 for (i=0; i < junction->referral_count; i++) {
232 junction->referral_list[i].alternate_path);
238 if (r->in.req.max_referral_level <= 2) {
239 max_referral_level = 2;
241 if (r->in.req.max_referral_level >= 3) {
242 max_referral_level = 3;
245 r->out.resp = talloc_zero(r, struct dfs_referral_resp);
246 if (r->out.resp == NULL) {
247 return NT_STATUS_NO_MEMORY;
250 r->out.resp->path_consumed = strlen_m(pathnamep) * 2;
251 r->out.resp->nb_referrals = junction->referral_count;
253 r->out.resp->header_flags = DFS_HEADER_FLAG_STORAGE_SVR;
255 r->out.resp->header_flags |= DFS_HEADER_FLAG_REFERAL_SVR;
258 r->out.resp->referral_entries = talloc_zero_array(r,
259 struct dfs_referral_type,
260 r->out.resp->nb_referrals);
261 if (r->out.resp->referral_entries == NULL) {
262 return NT_STATUS_NO_MEMORY;
265 switch (max_referral_level) {
267 for(i=0; i < junction->referral_count; i++) {
268 struct referral *ref = &junction->referral_list[i];
269 TALLOC_CTX *mem_ctx = r->out.resp->referral_entries;
270 struct dfs_referral_type *t =
271 &r->out.resp->referral_entries[i];
272 struct dfs_referral_v2 *v2 = &t->referral.v2;
275 v2->size = VERSION2_REFERRAL_SIZE;
277 v2->server_type = DFS_SERVER_ROOT;
279 v2->server_type = DFS_SERVER_NON_ROOT;
282 v2->proximity = ref->proximity;
284 v2->DFS_path = talloc_strdup(mem_ctx, pathnamep);
285 if (v2->DFS_path == NULL) {
286 return NT_STATUS_NO_MEMORY;
288 v2->DFS_alt_path = talloc_strdup(mem_ctx, pathnamep);
289 if (v2->DFS_alt_path == NULL) {
290 return NT_STATUS_NO_MEMORY;
292 v2->netw_address = talloc_strdup(mem_ctx,
293 ref->alternate_path);
294 if (v2->netw_address == NULL) {
295 return NT_STATUS_NO_MEMORY;
301 for(i=0; i < junction->referral_count; i++) {
302 struct referral *ref = &junction->referral_list[i];
303 TALLOC_CTX *mem_ctx = r->out.resp->referral_entries;
304 struct dfs_referral_type *t =
305 &r->out.resp->referral_entries[i];
306 struct dfs_referral_v3 *v3 = &t->referral.v3;
307 struct dfs_normal_referral *r1 = &v3->referrals.r1;
310 v3->size = VERSION3_REFERRAL_SIZE;
312 v3->server_type = DFS_SERVER_ROOT;
314 v3->server_type = DFS_SERVER_NON_ROOT;
318 r1->DFS_path = talloc_strdup(mem_ctx, pathnamep);
319 if (r1->DFS_path == NULL) {
320 return NT_STATUS_NO_MEMORY;
322 r1->DFS_alt_path = talloc_strdup(mem_ctx, pathnamep);
323 if (r1->DFS_alt_path == NULL) {
324 return NT_STATUS_NO_MEMORY;
326 r1->netw_address = talloc_strdup(mem_ctx,
327 ref->alternate_path);
328 if (r1->netw_address == NULL) {
329 return NT_STATUS_NO_MEMORY;
334 DEBUG(0,("setup_dfs_referral: Invalid dfs referral "
336 max_referral_level));
337 return NT_STATUS_INVALID_LEVEL;
341 NDR_PRINT_OUT_DEBUG(dfs_GetDFSReferral, r);
347 /* Directory operations */
349 static DIR *vfswrap_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr)
353 START_PROFILE(syscall_opendir);
354 result = opendir(fname);
355 END_PROFILE(syscall_opendir);
359 static DIR *vfswrap_fdopendir(vfs_handle_struct *handle,
366 START_PROFILE(syscall_fdopendir);
367 result = sys_fdopendir(fsp->fh->fd);
368 END_PROFILE(syscall_fdopendir);
373 static struct dirent *vfswrap_readdir(vfs_handle_struct *handle,
375 SMB_STRUCT_STAT *sbuf)
377 struct dirent *result;
379 START_PROFILE(syscall_readdir);
380 result = readdir(dirp);
381 /* Default Posix readdir() does not give us stat info.
382 * Set to invalid to indicate we didn't return this info. */
384 SET_STAT_INVALID(*sbuf);
385 END_PROFILE(syscall_readdir);
389 static void vfswrap_seekdir(vfs_handle_struct *handle, DIR *dirp, long offset)
391 START_PROFILE(syscall_seekdir);
392 seekdir(dirp, offset);
393 END_PROFILE(syscall_seekdir);
396 static long vfswrap_telldir(vfs_handle_struct *handle, DIR *dirp)
399 START_PROFILE(syscall_telldir);
400 result = telldir(dirp);
401 END_PROFILE(syscall_telldir);
405 static void vfswrap_rewinddir(vfs_handle_struct *handle, DIR *dirp)
407 START_PROFILE(syscall_rewinddir);
409 END_PROFILE(syscall_rewinddir);
412 static int vfswrap_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode)
415 bool has_dacl = False;
418 START_PROFILE(syscall_mkdir);
420 if (lp_inherit_acls(SNUM(handle->conn))
421 && parent_dirname(talloc_tos(), path, &parent, NULL)
422 && (has_dacl = directory_has_default_acl(handle->conn, parent)))
423 mode = (0777 & lp_dir_mask(SNUM(handle->conn)));
427 result = mkdir(path, mode);
429 if (result == 0 && !has_dacl) {
431 * We need to do this as the default behavior of POSIX ACLs
432 * is to set the mask to be the requested group permission
433 * bits, not the group permission bits to be the requested
434 * group permission bits. This is not what we want, as it will
435 * mess up any inherited ACL bits that were set. JRA.
437 int saved_errno = errno; /* We may get ENOSYS */
438 if ((SMB_VFS_CHMOD_ACL(handle->conn, path, mode) == -1) && (errno == ENOSYS))
442 END_PROFILE(syscall_mkdir);
446 static int vfswrap_rmdir(vfs_handle_struct *handle, const char *path)
450 START_PROFILE(syscall_rmdir);
451 result = rmdir(path);
452 END_PROFILE(syscall_rmdir);
456 static int vfswrap_closedir(vfs_handle_struct *handle, DIR *dirp)
460 START_PROFILE(syscall_closedir);
461 result = closedir(dirp);
462 END_PROFILE(syscall_closedir);
466 static void vfswrap_init_search_op(vfs_handle_struct *handle,
469 /* Default behavior is a NOOP */
472 /* File operations */
474 static int vfswrap_open(vfs_handle_struct *handle,
475 struct smb_filename *smb_fname,
476 files_struct *fsp, int flags, mode_t mode)
480 START_PROFILE(syscall_open);
482 if (smb_fname->stream_name) {
487 result = open(smb_fname->base_name, flags, mode);
489 END_PROFILE(syscall_open);
493 static NTSTATUS vfswrap_create_file(vfs_handle_struct *handle,
494 struct smb_request *req,
495 uint16_t root_dir_fid,
496 struct smb_filename *smb_fname,
497 uint32_t access_mask,
498 uint32_t share_access,
499 uint32_t create_disposition,
500 uint32_t create_options,
501 uint32_t file_attributes,
502 uint32_t oplock_request,
503 uint64_t allocation_size,
504 uint32_t private_flags,
505 struct security_descriptor *sd,
506 struct ea_list *ea_list,
507 files_struct **result,
510 return create_file_default(handle->conn, req, root_dir_fid, smb_fname,
511 access_mask, share_access,
512 create_disposition, create_options,
513 file_attributes, oplock_request,
514 allocation_size, private_flags,
519 static int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp)
523 START_PROFILE(syscall_close);
524 result = fd_close_posix(fsp);
525 END_PROFILE(syscall_close);
529 static ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, void *data, size_t n)
533 START_PROFILE_BYTES(syscall_read, n);
534 result = sys_read(fsp->fh->fd, data, n);
535 END_PROFILE(syscall_read);
539 static ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, void *data,
540 size_t n, off_t offset)
544 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
545 START_PROFILE_BYTES(syscall_pread, n);
546 result = sys_pread(fsp->fh->fd, data, n, offset);
547 END_PROFILE(syscall_pread);
549 if (result == -1 && errno == ESPIPE) {
550 /* Maintain the fiction that pipes can be seeked (sought?) on. */
551 result = SMB_VFS_READ(fsp, data, n);
555 #else /* HAVE_PREAD */
559 curr = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
560 if (curr == -1 && errno == ESPIPE) {
561 /* Maintain the fiction that pipes can be seeked (sought?) on. */
562 result = SMB_VFS_READ(fsp, data, n);
567 if (SMB_VFS_LSEEK(fsp, offset, SEEK_SET) == -1) {
572 result = SMB_VFS_READ(fsp, data, n);
575 SMB_VFS_LSEEK(fsp, curr, SEEK_SET);
578 #endif /* HAVE_PREAD */
583 struct vfswrap_pread_state {
587 static struct tevent_req *vfswrap_pread_send(struct vfs_handle_struct *handle,
589 struct tevent_context *ev,
590 struct files_struct *fsp,
592 size_t n, off_t offset)
594 struct tevent_req *req;
595 struct vfswrap_pread_state *state;
598 req = tevent_req_create(req, &state, struct vfswrap_pread_state);
602 START_PROFILE_BYTES(syscall_pread, n);
603 state->ret = sys_pread(fsp->fh->fd, data, n, offset);
605 END_PROFILE(syscall_pread);
607 if (state->ret == -1) {
608 tevent_req_error(req, saved_errno);
609 return tevent_req_post(req, ev);
611 tevent_req_done(req);
612 return tevent_req_post(req, ev);
615 static ssize_t vfswrap_pread_recv(struct tevent_req *req, int *err)
617 struct vfswrap_pread_state *state = tevent_req_data(
618 req, struct vfswrap_pread_state);
620 if (tevent_req_is_unix_error(req, err)) {
626 static ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n)
630 START_PROFILE_BYTES(syscall_write, n);
631 result = sys_write(fsp->fh->fd, data, n);
632 END_PROFILE(syscall_write);
636 static ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, const void *data,
637 size_t n, off_t offset)
641 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
642 START_PROFILE_BYTES(syscall_pwrite, n);
643 result = sys_pwrite(fsp->fh->fd, data, n, offset);
644 END_PROFILE(syscall_pwrite);
646 if (result == -1 && errno == ESPIPE) {
647 /* Maintain the fiction that pipes can be sought on. */
648 result = SMB_VFS_WRITE(fsp, data, n);
651 #else /* HAVE_PWRITE */
655 curr = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
660 if (SMB_VFS_LSEEK(fsp, offset, SEEK_SET) == -1) {
664 result = SMB_VFS_WRITE(fsp, data, n);
667 SMB_VFS_LSEEK(fsp, curr, SEEK_SET);
670 #endif /* HAVE_PWRITE */
675 struct vfswrap_pwrite_state {
679 static struct tevent_req *vfswrap_pwrite_send(
680 struct vfs_handle_struct *handle,
681 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
682 struct files_struct *fsp, const void *data, size_t n, off_t offset)
684 struct tevent_req *req;
685 struct vfswrap_pwrite_state *state;
688 req = tevent_req_create(mem_ctx, &state,
689 struct vfswrap_pwrite_state);
694 START_PROFILE_BYTES(syscall_pwrite, n);
695 state->retval = sys_pwrite(fsp->fh->fd, data, n, offset);
697 END_PROFILE(syscall_pwrite);
699 if (state->retval == -1) {
700 tevent_req_error(req, saved_errno);
702 tevent_req_done(req);
704 return tevent_req_post(req, ev);
707 static ssize_t vfswrap_pwrite_recv(struct tevent_req *req, int *perrno)
709 struct vfswrap_pwrite_state *state = tevent_req_data(
710 req, struct vfswrap_pwrite_state);
713 if (tevent_req_is_unix_error(req, &err)) {
717 return state->retval;
720 static off_t vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, off_t offset, int whence)
724 START_PROFILE(syscall_lseek);
726 /* Cope with 'stat' file opens. */
727 if (fsp->fh->fd != -1)
728 result = lseek(fsp->fh->fd, offset, whence);
731 * We want to maintain the fiction that we can seek
732 * on a fifo for file system purposes. This allows
733 * people to set up UNIX fifo's that feed data to Windows
737 if((result == -1) && (errno == ESPIPE)) {
742 END_PROFILE(syscall_lseek);
746 static ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fromfsp, const DATA_BLOB *hdr,
747 off_t offset, size_t n)
751 START_PROFILE_BYTES(syscall_sendfile, n);
752 result = sys_sendfile(tofd, fromfsp->fh->fd, hdr, offset, n);
753 END_PROFILE(syscall_sendfile);
757 static ssize_t vfswrap_recvfile(vfs_handle_struct *handle,
765 START_PROFILE_BYTES(syscall_recvfile, n);
766 result = sys_recvfile(fromfd, tofsp->fh->fd, offset, n);
767 END_PROFILE(syscall_recvfile);
771 static int vfswrap_rename(vfs_handle_struct *handle,
772 const struct smb_filename *smb_fname_src,
773 const struct smb_filename *smb_fname_dst)
777 START_PROFILE(syscall_rename);
779 if (smb_fname_src->stream_name || smb_fname_dst->stream_name) {
784 result = rename(smb_fname_src->base_name, smb_fname_dst->base_name);
787 END_PROFILE(syscall_rename);
791 static int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp)
796 START_PROFILE(syscall_fsync);
797 result = fsync(fsp->fh->fd);
798 END_PROFILE(syscall_fsync);
805 static int vfswrap_stat(vfs_handle_struct *handle,
806 struct smb_filename *smb_fname)
810 START_PROFILE(syscall_stat);
812 if (smb_fname->stream_name) {
817 result = sys_stat(smb_fname->base_name, &smb_fname->st,
818 lp_fake_dir_create_times(SNUM(handle->conn)));
820 END_PROFILE(syscall_stat);
824 static int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
828 START_PROFILE(syscall_fstat);
829 result = sys_fstat(fsp->fh->fd,
830 sbuf, lp_fake_dir_create_times(SNUM(handle->conn)));
831 END_PROFILE(syscall_fstat);
835 static int vfswrap_lstat(vfs_handle_struct *handle,
836 struct smb_filename *smb_fname)
840 START_PROFILE(syscall_lstat);
842 if (smb_fname->stream_name) {
847 result = sys_lstat(smb_fname->base_name, &smb_fname->st,
848 lp_fake_dir_create_times(SNUM(handle->conn)));
850 END_PROFILE(syscall_lstat);
854 static NTSTATUS vfswrap_translate_name(struct vfs_handle_struct *handle,
856 enum vfs_translate_direction direction,
860 return NT_STATUS_NONE_MAPPED;
864 * Implement the default fsctl operation.
866 static bool vfswrap_logged_ioctl_message = false;
868 static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
869 struct files_struct *fsp,
872 uint16_t req_flags, /* Needed for UNICODE ... */
873 const uint8_t *_in_data,
876 uint32_t max_out_len,
879 const char *in_data = (const char *)_in_data;
880 char **out_data = (char **)_out_data;
883 case FSCTL_SET_SPARSE:
885 bool set_sparse = true;
888 if (in_len >= 1 && in_data[0] == 0) {
892 status = file_set_sparse(handle->conn, fsp, set_sparse);
894 DEBUG(NT_STATUS_IS_OK(status) ? 10 : 9,
895 ("FSCTL_SET_SPARSE: fname[%s] set[%u] - %s\n",
896 smb_fname_str_dbg(fsp->fsp_name), set_sparse,
902 case FSCTL_CREATE_OR_GET_OBJECT_ID:
904 unsigned char objid[16];
905 char *return_data = NULL;
907 /* This should return the object-id on this file.
908 * I think I'll make this be the inode+dev. JRA.
911 DEBUG(10,("FSCTL_CREATE_OR_GET_OBJECT_ID: called on %s\n",
914 *out_len = (max_out_len >= 64) ? 64 : max_out_len;
915 /* Hmmm, will this cause problems if less data asked for? */
916 return_data = talloc_array(ctx, char, 64);
917 if (return_data == NULL) {
918 return NT_STATUS_NO_MEMORY;
921 /* For backwards compatibility only store the dev/inode. */
922 push_file_id_16(return_data, &fsp->file_id);
923 memcpy(return_data+16,create_volume_objectid(fsp->conn,objid),16);
924 push_file_id_16(return_data+32, &fsp->file_id);
925 *out_data = return_data;
929 case FSCTL_GET_REPARSE_POINT:
931 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
932 DEBUG(10, ("FSCTL_GET_REPARSE_POINT: called on %s. "
933 "Status: NOT_IMPLEMENTED\n", fsp_fnum_dbg(fsp)));
934 return NT_STATUS_NOT_A_REPARSE_POINT;
937 case FSCTL_SET_REPARSE_POINT:
939 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
940 DEBUG(10, ("FSCTL_SET_REPARSE_POINT: called on %s. "
941 "Status: NOT_IMPLEMENTED\n", fsp_fnum_dbg(fsp)));
942 return NT_STATUS_NOT_A_REPARSE_POINT;
945 case FSCTL_GET_SHADOW_COPY_DATA:
948 * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
949 * and return their volume names. If max_data_count is 16, then it is just
950 * asking for the number of volumes and length of the combined names.
952 * pdata is the data allocated by our caller, but that uses
953 * total_data_count (which is 0 in our case) rather than max_data_count.
954 * Allocate the correct amount and return the pointer to let
955 * it be deallocated when we return.
957 struct shadow_copy_data *shadow_data = NULL;
959 uint32 labels_data_count = 0;
961 char *cur_pdata = NULL;
963 if (max_out_len < 16) {
964 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
966 return NT_STATUS_INVALID_PARAMETER;
969 if (max_out_len > 16) {
973 shadow_data = talloc_zero(ctx, struct shadow_copy_data);
974 if (shadow_data == NULL) {
975 DEBUG(0,("TALLOC_ZERO() failed!\n"));
976 return NT_STATUS_NO_MEMORY;
980 * Call the VFS routine to actually do the work.
982 if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) {
983 TALLOC_FREE(shadow_data);
984 if (errno == ENOSYS) {
985 DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n",
986 fsp->conn->connectpath));
987 return NT_STATUS_NOT_SUPPORTED;
989 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n",
990 fsp->conn->connectpath));
991 return NT_STATUS_UNSUCCESSFUL;
995 labels_data_count = (shadow_data->num_volumes * 2 *
996 sizeof(SHADOW_COPY_LABEL)) + 2;
1001 *out_len = 12 + labels_data_count + 4;
1004 if (max_out_len < *out_len) {
1005 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
1006 max_out_len, *out_len));
1007 TALLOC_FREE(shadow_data);
1008 return NT_STATUS_BUFFER_TOO_SMALL;
1011 cur_pdata = talloc_array(ctx, char, *out_len);
1012 if (cur_pdata == NULL) {
1013 TALLOC_FREE(shadow_data);
1014 return NT_STATUS_NO_MEMORY;
1017 *out_data = cur_pdata;
1019 /* num_volumes 4 bytes */
1020 SIVAL(cur_pdata, 0, shadow_data->num_volumes);
1023 /* num_labels 4 bytes */
1024 SIVAL(cur_pdata, 4, shadow_data->num_volumes);
1027 /* needed_data_count 4 bytes */
1028 SIVAL(cur_pdata, 8, labels_data_count + 4);
1032 DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
1033 shadow_data->num_volumes, fsp_str_dbg(fsp)));
1034 if (labels && shadow_data->labels) {
1035 for (i=0; i<shadow_data->num_volumes; i++) {
1036 srvstr_push(cur_pdata, req_flags,
1037 cur_pdata, shadow_data->labels[i],
1038 2 * sizeof(SHADOW_COPY_LABEL),
1039 STR_UNICODE|STR_TERMINATE);
1040 cur_pdata += 2 * sizeof(SHADOW_COPY_LABEL);
1041 DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i]));
1045 TALLOC_FREE(shadow_data);
1047 return NT_STATUS_OK;
1050 case FSCTL_FIND_FILES_BY_SID:
1052 /* pretend this succeeded -
1054 * we have to send back a list with all files owned by this SID
1056 * but I have to check that --metze
1062 DEBUG(10, ("FSCTL_FIND_FILES_BY_SID: called on %s\n",
1063 fsp_fnum_dbg(fsp)));
1066 /* NT_STATUS_BUFFER_TOO_SMALL maybe? */
1067 return NT_STATUS_INVALID_PARAMETER;
1070 sid_len = MIN(in_len - 4,SID_MAX_SIZE);
1072 /* unknown 4 bytes: this is not the length of the sid :-( */
1073 /*unknown = IVAL(pdata,0);*/
1075 if (!sid_parse(in_data + 4, sid_len, &sid)) {
1076 return NT_STATUS_INVALID_PARAMETER;
1078 DEBUGADD(10, ("for SID: %s\n", sid_string_dbg(&sid)));
1080 if (!sid_to_uid(&sid, &uid)) {
1081 DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
1082 sid_string_dbg(&sid),
1083 (unsigned long)sid_len));
1087 /* we can take a look at the find source :-)
1089 * find ./ -uid $uid -name '*' is what we need here
1092 * and send 4bytes len and then NULL terminated unicode strings
1095 * but I don't know how to deal with the paged results
1096 * (maybe we can hang the result anywhere in the fsp struct)
1098 * but I don't know how to deal with the paged results
1099 * (maybe we can hang the result anywhere in the fsp struct)
1101 * we don't send all files at once
1102 * and at the next we should *not* start from the beginning,
1103 * so we have to cache the result
1108 /* this works for now... */
1109 return NT_STATUS_OK;
1112 case FSCTL_QUERY_ALLOCATED_RANGES:
1114 /* FIXME: This is just a dummy reply, telling that all of the
1115 * file is allocated. MKS cp needs that.
1116 * Adding the real allocated ranges via FIEMAP on Linux
1117 * and SEEK_DATA/SEEK_HOLE on Solaris is needed to make
1118 * this FSCTL correct for sparse files.
1121 uint64_t offset, length;
1122 char *out_data_tmp = NULL;
1125 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: data_count(%u) != 16 is invalid!\n",
1127 return NT_STATUS_INVALID_PARAMETER;
1130 if (max_out_len < 16) {
1131 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: max_out_len (%u) < 16 is invalid!\n",
1133 return NT_STATUS_INVALID_PARAMETER;
1136 offset = BVAL(in_data,0);
1137 length = BVAL(in_data,8);
1139 if (offset + length < offset) {
1140 /* No 64-bit integer wrap. */
1141 return NT_STATUS_INVALID_PARAMETER;
1144 /* Shouldn't this be SMB_VFS_STAT ... ? */
1145 status = vfs_stat_fsp(fsp);
1146 if (!NT_STATUS_IS_OK(status)) {
1151 out_data_tmp = talloc_array(ctx, char, *out_len);
1152 if (out_data_tmp == NULL) {
1153 DEBUG(10, ("unable to allocate memory for response\n"));
1154 return NT_STATUS_NO_MEMORY;
1157 if (offset > fsp->fsp_name->st.st_ex_size ||
1158 fsp->fsp_name->st.st_ex_size == 0 ||
1160 memset(out_data_tmp, 0, *out_len);
1162 uint64_t end = offset + length;
1163 end = MIN(end, fsp->fsp_name->st.st_ex_size);
1164 SBVAL(out_data_tmp, 0, 0);
1165 SBVAL(out_data_tmp, 8, end);
1168 *out_data = out_data_tmp;
1170 return NT_STATUS_OK;
1173 case FSCTL_IS_VOLUME_DIRTY:
1175 DEBUG(10,("FSCTL_IS_VOLUME_DIRTY: called on %s "
1176 "(but remotely not supported)\n", fsp_fnum_dbg(fsp)));
1178 * http://msdn.microsoft.com/en-us/library/cc232128%28PROT.10%29.aspx
1179 * says we have to respond with NT_STATUS_INVALID_PARAMETER
1181 return NT_STATUS_INVALID_PARAMETER;
1186 * Only print once ... unfortunately there could be lots of
1187 * different FSCTLs that are called.
1189 if (!vfswrap_logged_ioctl_message) {
1190 vfswrap_logged_ioctl_message = true;
1191 DEBUG(2, ("%s (0x%x): Currently not implemented.\n",
1192 __func__, function));
1196 return NT_STATUS_NOT_SUPPORTED;
1199 /********************************************************************
1200 Given a stat buffer return the allocated size on disk, taking into
1201 account sparse files.
1202 ********************************************************************/
1203 static uint64_t vfswrap_get_alloc_size(vfs_handle_struct *handle,
1204 struct files_struct *fsp,
1205 const SMB_STRUCT_STAT *sbuf)
1209 START_PROFILE(syscall_get_alloc_size);
1211 if(S_ISDIR(sbuf->st_ex_mode)) {
1216 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
1217 /* The type of st_blocksize is blkcnt_t which *MUST* be
1218 signed (according to POSIX) and can be less than 64-bits.
1219 Ensure when we're converting to 64 bits wide we don't
1221 #if defined(SIZEOF_BLKCNT_T_8)
1222 result = (uint64_t)STAT_ST_BLOCKSIZE * (uint64_t)sbuf->st_ex_blocks;
1223 #elif defined(SIZEOF_BLKCNT_T_4)
1225 uint64_t bs = ((uint64_t)sbuf->st_ex_blocks) & 0xFFFFFFFFLL;
1226 result = (uint64_t)STAT_ST_BLOCKSIZE * bs;
1229 #error SIZEOF_BLKCNT_T_NOT_A_SUPPORTED_VALUE
1232 result = get_file_size_stat(sbuf);
1235 if (fsp && fsp->initial_allocation_size)
1236 result = MAX(result,fsp->initial_allocation_size);
1238 result = smb_roundup(handle->conn, result);
1241 END_PROFILE(syscall_get_alloc_size);
1245 static int vfswrap_unlink(vfs_handle_struct *handle,
1246 const struct smb_filename *smb_fname)
1250 START_PROFILE(syscall_unlink);
1252 if (smb_fname->stream_name) {
1256 result = unlink(smb_fname->base_name);
1259 END_PROFILE(syscall_unlink);
1263 static int vfswrap_chmod(vfs_handle_struct *handle, const char *path, mode_t mode)
1267 START_PROFILE(syscall_chmod);
1270 * We need to do this due to the fact that the default POSIX ACL
1271 * chmod modifies the ACL *mask* for the group owner, not the
1272 * group owner bits directly. JRA.
1277 int saved_errno = errno; /* We might get ENOSYS */
1278 if ((result = SMB_VFS_CHMOD_ACL(handle->conn, path, mode)) == 0) {
1279 END_PROFILE(syscall_chmod);
1282 /* Error - return the old errno. */
1283 errno = saved_errno;
1286 result = chmod(path, mode);
1287 END_PROFILE(syscall_chmod);
1291 static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
1295 START_PROFILE(syscall_fchmod);
1298 * We need to do this due to the fact that the default POSIX ACL
1299 * chmod modifies the ACL *mask* for the group owner, not the
1300 * group owner bits directly. JRA.
1304 int saved_errno = errno; /* We might get ENOSYS */
1305 if ((result = SMB_VFS_FCHMOD_ACL(fsp, mode)) == 0) {
1306 END_PROFILE(syscall_fchmod);
1309 /* Error - return the old errno. */
1310 errno = saved_errno;
1313 #if defined(HAVE_FCHMOD)
1314 result = fchmod(fsp->fh->fd, mode);
1320 END_PROFILE(syscall_fchmod);
1324 static int vfswrap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
1328 START_PROFILE(syscall_chown);
1329 result = chown(path, uid, gid);
1330 END_PROFILE(syscall_chown);
1334 static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t uid, gid_t gid)
1339 START_PROFILE(syscall_fchown);
1340 result = fchown(fsp->fh->fd, uid, gid);
1341 END_PROFILE(syscall_fchown);
1349 static int vfswrap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
1353 START_PROFILE(syscall_lchown);
1354 result = lchown(path, uid, gid);
1355 END_PROFILE(syscall_lchown);
1359 static int vfswrap_chdir(vfs_handle_struct *handle, const char *path)
1363 START_PROFILE(syscall_chdir);
1364 result = chdir(path);
1365 END_PROFILE(syscall_chdir);
1369 static char *vfswrap_getwd(vfs_handle_struct *handle)
1373 START_PROFILE(syscall_getwd);
1374 result = sys_getwd();
1375 END_PROFILE(syscall_getwd);
1379 /*********************************************************************
1380 nsec timestamp resolution call. Convert down to whatever the underlying
1381 system will support.
1382 **********************************************************************/
1384 static int vfswrap_ntimes(vfs_handle_struct *handle,
1385 const struct smb_filename *smb_fname,
1386 struct smb_file_time *ft)
1390 START_PROFILE(syscall_ntimes);
1392 if (smb_fname->stream_name) {
1398 if (null_timespec(ft->atime)) {
1399 ft->atime= smb_fname->st.st_ex_atime;
1402 if (null_timespec(ft->mtime)) {
1403 ft->mtime = smb_fname->st.st_ex_mtime;
1406 if (!null_timespec(ft->create_time)) {
1407 set_create_timespec_ea(handle->conn,
1412 if ((timespec_compare(&ft->atime,
1413 &smb_fname->st.st_ex_atime) == 0) &&
1414 (timespec_compare(&ft->mtime,
1415 &smb_fname->st.st_ex_mtime) == 0)) {
1420 #if defined(HAVE_UTIMENSAT)
1422 struct timespec ts[2];
1425 result = utimensat(AT_FDCWD, smb_fname->base_name, ts, 0);
1427 result = utimensat(AT_FDCWD, smb_fname->base_name, NULL, 0);
1429 if (!((result == -1) && (errno == ENOSYS))) {
1433 #if defined(HAVE_UTIMES)
1435 struct timeval tv[2];
1436 tv[0] = convert_timespec_to_timeval(ft->atime);
1437 tv[1] = convert_timespec_to_timeval(ft->mtime);
1438 result = utimes(smb_fname->base_name, tv);
1440 result = utimes(smb_fname->base_name, NULL);
1442 if (!((result == -1) && (errno == ENOSYS))) {
1446 #if defined(HAVE_UTIME)
1448 struct utimbuf times;
1449 times.actime = convert_timespec_to_time_t(ft->atime);
1450 times.modtime = convert_timespec_to_time_t(ft->mtime);
1451 result = utime(smb_fname->base_name, ×);
1453 result = utime(smb_fname->base_name, NULL);
1455 if (!((result == -1) && (errno == ENOSYS))) {
1463 END_PROFILE(syscall_ntimes);
1467 /*********************************************************************
1468 A version of ftruncate that will write the space on disk if strict
1470 **********************************************************************/
1472 static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, off_t len)
1474 off_t space_to_write;
1475 uint64_t space_avail;
1476 uint64_t bsize,dfree,dsize;
1479 SMB_STRUCT_STAT *pst;
1481 status = vfs_stat_fsp(fsp);
1482 if (!NT_STATUS_IS_OK(status)) {
1485 pst = &fsp->fsp_name->st;
1488 if (S_ISFIFO(pst->st_ex_mode))
1492 if (pst->st_ex_size == len)
1495 /* Shrink - just ftruncate. */
1496 if (pst->st_ex_size > len)
1497 return ftruncate(fsp->fh->fd, len);
1499 space_to_write = len - pst->st_ex_size;
1501 /* for allocation try fallocate first. This can fail on some
1502 platforms e.g. when the filesystem doesn't support it and no
1503 emulation is being done by the libc (like on AIX with JFS1). In that
1504 case we do our own emulation. fallocate implementations can
1505 return ENOTSUP or EINVAL in cases like that. */
1506 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
1507 pst->st_ex_size, space_to_write);
1508 if (ret == ENOSPC) {
1515 DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with "
1516 "error %d. Falling back to slow manual allocation\n", ret));
1518 /* available disk space is enough or not? */
1519 space_avail = get_dfree_info(fsp->conn,
1520 fsp->fsp_name->base_name, false,
1521 &bsize,&dfree,&dsize);
1522 /* space_avail is 1k blocks */
1523 if (space_avail == (uint64_t)-1 ||
1524 ((uint64_t)space_to_write/1024 > space_avail) ) {
1529 /* Write out the real space on disk. */
1530 ret = vfs_slow_fallocate(fsp, pst->st_ex_size, space_to_write);
1539 static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, off_t len)
1542 SMB_STRUCT_STAT *pst;
1546 START_PROFILE(syscall_ftruncate);
1548 if (lp_strict_allocate(SNUM(fsp->conn)) && !fsp->is_sparse) {
1549 result = strict_allocate_ftruncate(handle, fsp, len);
1550 END_PROFILE(syscall_ftruncate);
1554 /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
1555 ftruncate if the system supports it. Then I discovered that
1556 you can have some filesystems that support ftruncate
1557 expansion and some that don't! On Linux fat can't do
1558 ftruncate extend but ext2 can. */
1560 result = ftruncate(fsp->fh->fd, len);
1564 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
1565 extend a file with ftruncate. Provide alternate implementation
1568 /* Do an fstat to see if the file is longer than the requested
1569 size in which case the ftruncate above should have
1570 succeeded or shorter, in which case seek to len - 1 and
1571 write 1 byte of zero */
1572 status = vfs_stat_fsp(fsp);
1573 if (!NT_STATUS_IS_OK(status)) {
1576 pst = &fsp->fsp_name->st;
1579 if (S_ISFIFO(pst->st_ex_mode)) {
1585 if (pst->st_ex_size == len) {
1590 if (pst->st_ex_size > len) {
1591 /* the ftruncate should have worked */
1595 if (SMB_VFS_PWRITE(fsp, &c, 1, len-1)!=1) {
1603 END_PROFILE(syscall_ftruncate);
1607 static int vfswrap_fallocate(vfs_handle_struct *handle,
1609 enum vfs_fallocate_mode mode,
1615 START_PROFILE(syscall_fallocate);
1616 if (mode == VFS_FALLOCATE_EXTEND_SIZE) {
1617 result = sys_posix_fallocate(fsp->fh->fd, offset, len);
1618 } else if (mode == VFS_FALLOCATE_KEEP_SIZE) {
1619 result = sys_fallocate(fsp->fh->fd, mode, offset, len);
1624 END_PROFILE(syscall_fallocate);
1628 static bool vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int op, off_t offset, off_t count, int type)
1632 START_PROFILE(syscall_fcntl_lock);
1633 result = fcntl_lock(fsp->fh->fd, op, offset, count, type);
1634 END_PROFILE(syscall_fcntl_lock);
1638 static int vfswrap_kernel_flock(vfs_handle_struct *handle, files_struct *fsp,
1639 uint32 share_mode, uint32 access_mask)
1641 START_PROFILE(syscall_kernel_flock);
1642 kernel_flock(fsp->fh->fd, share_mode, access_mask);
1643 END_PROFILE(syscall_kernel_flock);
1647 static bool vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid)
1651 START_PROFILE(syscall_fcntl_getlock);
1652 result = fcntl_getlock(fsp->fh->fd, poffset, pcount, ptype, ppid);
1653 END_PROFILE(syscall_fcntl_getlock);
1657 static int vfswrap_linux_setlease(vfs_handle_struct *handle, files_struct *fsp,
1662 START_PROFILE(syscall_linux_setlease);
1664 #ifdef HAVE_KERNEL_OPLOCKS_LINUX
1665 result = linux_setlease(fsp->fh->fd, leasetype);
1669 END_PROFILE(syscall_linux_setlease);
1673 static int vfswrap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
1677 START_PROFILE(syscall_symlink);
1678 result = symlink(oldpath, newpath);
1679 END_PROFILE(syscall_symlink);
1683 static int vfswrap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz)
1687 START_PROFILE(syscall_readlink);
1688 result = readlink(path, buf, bufsiz);
1689 END_PROFILE(syscall_readlink);
1693 static int vfswrap_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
1697 START_PROFILE(syscall_link);
1698 result = link(oldpath, newpath);
1699 END_PROFILE(syscall_link);
1703 static int vfswrap_mknod(vfs_handle_struct *handle, const char *pathname, mode_t mode, SMB_DEV_T dev)
1707 START_PROFILE(syscall_mknod);
1708 result = sys_mknod(pathname, mode, dev);
1709 END_PROFILE(syscall_mknod);
1713 static char *vfswrap_realpath(vfs_handle_struct *handle, const char *path)
1717 START_PROFILE(syscall_realpath);
1718 #ifdef REALPATH_TAKES_NULL
1719 result = realpath(path, NULL);
1721 result = SMB_MALLOC_ARRAY(char, PATH_MAX+1);
1723 char *resolved_path = realpath(path, result);
1724 if (!resolved_path) {
1727 /* SMB_ASSERT(result == resolved_path) ? */
1728 result = resolved_path;
1732 END_PROFILE(syscall_realpath);
1736 static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle,
1737 struct sys_notify_context *ctx,
1740 uint32_t *subdir_filter,
1741 void (*callback)(struct sys_notify_context *ctx,
1743 struct notify_event *ev),
1744 void *private_data, void *handle)
1747 * So far inotify is the only supported default notify mechanism. If
1748 * another platform like the the BSD's or a proprietary Unix comes
1749 * along and wants another default, we can play the same trick we
1750 * played with Posix ACLs.
1752 * Until that is the case, hard-code inotify here.
1755 if (lp_kernel_change_notify(vfs_handle->conn->params)) {
1756 return inotify_watch(ctx, path, filter, subdir_filter,
1757 callback, private_data, handle);
1761 * Do nothing, leave everything to notify_internal.c
1763 return NT_STATUS_OK;
1766 static int vfswrap_chflags(vfs_handle_struct *handle, const char *path,
1770 return chflags(path, flags);
1777 static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle,
1778 const SMB_STRUCT_STAT *sbuf)
1782 /* the ZERO_STRUCT ensures padding doesn't break using the key as a
1786 key.devid = sbuf->st_ex_dev;
1787 key.inode = sbuf->st_ex_ino;
1788 /* key.extid is unused by default. */
1793 static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
1794 struct files_struct *fsp,
1796 TALLOC_CTX *mem_ctx,
1797 unsigned int *pnum_streams,
1798 struct stream_struct **pstreams)
1800 SMB_STRUCT_STAT sbuf;
1801 struct stream_struct *tmp_streams = NULL;
1804 if ((fsp != NULL) && (fsp->is_directory)) {
1806 * No default streams on directories
1811 if ((fsp != NULL) && (fsp->fh->fd != -1)) {
1812 ret = SMB_VFS_FSTAT(fsp, &sbuf);
1815 struct smb_filename smb_fname;
1817 ZERO_STRUCT(smb_fname);
1818 smb_fname.base_name = discard_const_p(char, fname);
1820 if (lp_posix_pathnames()) {
1821 ret = SMB_VFS_LSTAT(handle->conn, &smb_fname);
1823 ret = SMB_VFS_STAT(handle->conn, &smb_fname);
1825 sbuf = smb_fname.st;
1829 return map_nt_error_from_unix(errno);
1832 if (S_ISDIR(sbuf.st_ex_mode)) {
1836 tmp_streams = talloc_realloc(mem_ctx, *pstreams, struct stream_struct,
1837 (*pnum_streams) + 1);
1838 if (tmp_streams == NULL) {
1839 return NT_STATUS_NO_MEMORY;
1841 tmp_streams[*pnum_streams].name = talloc_strdup(tmp_streams, "::$DATA");
1842 if (tmp_streams[*pnum_streams].name == NULL) {
1843 return NT_STATUS_NO_MEMORY;
1845 tmp_streams[*pnum_streams].size = sbuf.st_ex_size;
1846 tmp_streams[*pnum_streams].alloc_size = SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp, &sbuf);
1849 *pstreams = tmp_streams;
1851 return NT_STATUS_OK;
1854 static int vfswrap_get_real_filename(struct vfs_handle_struct *handle,
1857 TALLOC_CTX *mem_ctx,
1861 * Don't fall back to get_real_filename so callers can differentiate
1862 * between a full directory scan and an actual case-insensitive stat.
1868 static const char *vfswrap_connectpath(struct vfs_handle_struct *handle,
1871 return handle->conn->connectpath;
1874 static NTSTATUS vfswrap_brl_lock_windows(struct vfs_handle_struct *handle,
1875 struct byte_range_lock *br_lck,
1876 struct lock_struct *plock,
1878 struct blocking_lock_record *blr)
1880 SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1882 /* Note: blr is not used in the default implementation. */
1883 return brl_lock_windows_default(br_lck, plock, blocking_lock);
1886 static bool vfswrap_brl_unlock_windows(struct vfs_handle_struct *handle,
1887 struct messaging_context *msg_ctx,
1888 struct byte_range_lock *br_lck,
1889 const struct lock_struct *plock)
1891 SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1893 return brl_unlock_windows_default(msg_ctx, br_lck, plock);
1896 static bool vfswrap_brl_cancel_windows(struct vfs_handle_struct *handle,
1897 struct byte_range_lock *br_lck,
1898 struct lock_struct *plock,
1899 struct blocking_lock_record *blr)
1901 SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1903 /* Note: blr is not used in the default implementation. */
1904 return brl_lock_cancel_default(br_lck, plock);
1907 static bool vfswrap_strict_lock(struct vfs_handle_struct *handle,
1909 struct lock_struct *plock)
1911 SMB_ASSERT(plock->lock_type == READ_LOCK ||
1912 plock->lock_type == WRITE_LOCK);
1914 return strict_lock_default(fsp, plock);
1917 static void vfswrap_strict_unlock(struct vfs_handle_struct *handle,
1919 struct lock_struct *plock)
1921 SMB_ASSERT(plock->lock_type == READ_LOCK ||
1922 plock->lock_type == WRITE_LOCK);
1924 strict_unlock_default(fsp, plock);
1927 /* NT ACL operations. */
1929 static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle,
1931 uint32 security_info,
1932 struct security_descriptor **ppdesc)
1936 START_PROFILE(fget_nt_acl);
1937 result = posix_fget_nt_acl(fsp, security_info, ppdesc);
1938 END_PROFILE(fget_nt_acl);
1942 static NTSTATUS vfswrap_get_nt_acl(vfs_handle_struct *handle,
1944 uint32 security_info,
1945 struct security_descriptor **ppdesc)
1949 START_PROFILE(get_nt_acl);
1950 result = posix_get_nt_acl(handle->conn, name, security_info, ppdesc);
1951 END_PROFILE(get_nt_acl);
1955 static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, const struct security_descriptor *psd)
1959 START_PROFILE(fset_nt_acl);
1960 result = set_nt_acl(fsp, security_info_sent, psd);
1961 END_PROFILE(fset_nt_acl);
1965 static NTSTATUS vfswrap_audit_file(struct vfs_handle_struct *handle,
1966 struct smb_filename *file,
1967 struct security_acl *sacl,
1968 uint32_t access_requested,
1969 uint32_t access_denied)
1971 return NT_STATUS_OK; /* Nothing to do here ... */
1974 static int vfswrap_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode)
1982 START_PROFILE(chmod_acl);
1983 result = chmod_acl(handle->conn, name, mode);
1984 END_PROFILE(chmod_acl);
1989 static int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
1997 START_PROFILE(fchmod_acl);
1998 result = fchmod_acl(fsp, mode);
1999 END_PROFILE(fchmod_acl);
2004 static int vfswrap_sys_acl_get_entry(vfs_handle_struct *handle, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
2006 return sys_acl_get_entry(theacl, entry_id, entry_p);
2009 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)
2011 return sys_acl_get_tag_type(entry_d, tag_type_p);
2014 static int vfswrap_sys_acl_get_permset(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
2016 return sys_acl_get_permset(entry_d, permset_p);
2019 static void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d)
2021 return sys_acl_get_qualifier(entry_d);
2024 static SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, SMB_ACL_TYPE_T type)
2026 return sys_acl_get_file(handle, path_p, type);
2029 static SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp)
2031 return sys_acl_get_fd(handle, fsp);
2034 static int vfswrap_sys_acl_clear_perms(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset)
2036 return sys_acl_clear_perms(permset);
2039 static int vfswrap_sys_acl_add_perm(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2041 return sys_acl_add_perm(permset, perm);
2044 static char * vfswrap_sys_acl_to_text(vfs_handle_struct *handle, SMB_ACL_T theacl, ssize_t *plen)
2046 return sys_acl_to_text(theacl, plen);
2049 static SMB_ACL_T vfswrap_sys_acl_init(vfs_handle_struct *handle, int count)
2051 return sys_acl_init(count);
2054 static int vfswrap_sys_acl_create_entry(vfs_handle_struct *handle, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2056 return sys_acl_create_entry(pacl, pentry);
2059 static int vfswrap_sys_acl_set_tag_type(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
2061 return sys_acl_set_tag_type(entry, tagtype);
2064 static int vfswrap_sys_acl_set_qualifier(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, void *qual)
2066 return sys_acl_set_qualifier(entry, qual);
2069 static int vfswrap_sys_acl_set_permset(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
2071 return sys_acl_set_permset(entry, permset);
2074 static int vfswrap_sys_acl_valid(vfs_handle_struct *handle, SMB_ACL_T theacl )
2076 return sys_acl_valid(theacl );
2079 static int vfswrap_sys_acl_set_file(vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
2081 return sys_acl_set_file(handle, name, acltype, theacl);
2084 static int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_T theacl)
2086 return sys_acl_set_fd(handle, fsp, theacl);
2089 static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle, const char *path)
2091 return sys_acl_delete_def_file(handle, path);
2094 static int vfswrap_sys_acl_get_perm(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2096 return sys_acl_get_perm(permset, perm);
2099 static int vfswrap_sys_acl_free_text(vfs_handle_struct *handle, char *text)
2101 return sys_acl_free_text(text);
2104 static int vfswrap_sys_acl_free_acl(vfs_handle_struct *handle, SMB_ACL_T posix_acl)
2106 return sys_acl_free_acl(posix_acl);
2109 static int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle, void *qualifier, SMB_ACL_TAG_T tagtype)
2111 return sys_acl_free_qualifier(qualifier, tagtype);
2114 /****************************************************************
2115 Extended attribute operations.
2116 *****************************************************************/
2118 static ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
2120 return getxattr(path, name, value, size);
2123 static ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, void *value, size_t size)
2125 return fgetxattr(fsp->fh->fd, name, value, size);
2128 static ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
2130 return listxattr(path, list, size);
2133 static ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size)
2135 return flistxattr(fsp->fh->fd, list, size);
2138 static int vfswrap_removexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
2140 return removexattr(path, name);
2143 static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name)
2145 return fremovexattr(fsp->fh->fd, name);
2148 static int vfswrap_setxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
2150 return setxattr(path, name, value, size, flags);
2153 static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, const void *value, size_t size, int flags)
2155 return fsetxattr(fsp->fh->fd, name, value, size, flags);
2158 static int vfswrap_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2161 if (!initialize_async_io_handler()) {
2166 * aio_read must be done as root, because in the glibc aio
2167 * implementation the helper thread needs to be able to send a signal
2168 * to the main thread, even when it has done a seteuid() to a
2172 ret = sys_aio_read(aiocb);
2177 static int vfswrap_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2180 if (!initialize_async_io_handler()) {
2185 * aio_write must be done as root, because in the glibc aio
2186 * implementation the helper thread needs to be able to send a signal
2187 * to the main thread, even when it has done a seteuid() to a
2191 ret = sys_aio_write(aiocb);
2196 static ssize_t vfswrap_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2198 return sys_aio_return(aiocb);
2201 static int vfswrap_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2203 return sys_aio_cancel(fsp->fh->fd, aiocb);
2206 static int vfswrap_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2208 return sys_aio_error(aiocb);
2211 static int vfswrap_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb)
2213 return sys_aio_fsync(op, aiocb);
2216 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)
2218 return sys_aio_suspend(aiocb, n, timeout);
2221 static bool vfswrap_aio_force(struct vfs_handle_struct *handle, struct files_struct *fsp)
2226 static bool vfswrap_is_offline(struct vfs_handle_struct *handle,
2227 const struct smb_filename *fname,
2228 SMB_STRUCT_STAT *sbuf)
2232 bool offline = false;
2234 if (ISDOT(fname->base_name) || ISDOTDOT(fname->base_name)) {
2238 if (!lp_dmapi_support(SNUM(handle->conn)) || !dmapi_have_session()) {
2239 #if defined(ENOTSUP)
2245 status = get_full_smb_filename(talloc_tos(), fname, &path);
2246 if (!NT_STATUS_IS_OK(status)) {
2247 errno = map_errno_from_nt_status(status);
2251 offline = (dmapi_file_flags(path) & FILE_ATTRIBUTE_OFFLINE) != 0;
2258 static int vfswrap_set_offline(struct vfs_handle_struct *handle,
2259 const struct smb_filename *fname)
2261 /* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */
2262 #if defined(ENOTSUP)
2268 static struct vfs_fn_pointers vfs_default_fns = {
2269 /* Disk operations */
2271 .connect_fn = vfswrap_connect,
2272 .disconnect_fn = vfswrap_disconnect,
2273 .disk_free_fn = vfswrap_disk_free,
2274 .get_quota_fn = vfswrap_get_quota,
2275 .set_quota_fn = vfswrap_set_quota,
2276 .get_shadow_copy_data_fn = vfswrap_get_shadow_copy_data,
2277 .statvfs_fn = vfswrap_statvfs,
2278 .fs_capabilities_fn = vfswrap_fs_capabilities,
2279 .get_dfs_referrals_fn = vfswrap_get_dfs_referrals,
2281 /* Directory operations */
2283 .opendir_fn = vfswrap_opendir,
2284 .fdopendir_fn = vfswrap_fdopendir,
2285 .readdir_fn = vfswrap_readdir,
2286 .seekdir_fn = vfswrap_seekdir,
2287 .telldir_fn = vfswrap_telldir,
2288 .rewind_dir_fn = vfswrap_rewinddir,
2289 .mkdir_fn = vfswrap_mkdir,
2290 .rmdir_fn = vfswrap_rmdir,
2291 .closedir_fn = vfswrap_closedir,
2292 .init_search_op_fn = vfswrap_init_search_op,
2294 /* File operations */
2296 .open_fn = vfswrap_open,
2297 .create_file_fn = vfswrap_create_file,
2298 .close_fn = vfswrap_close,
2299 .read_fn = vfswrap_read,
2300 .pread_fn = vfswrap_pread,
2301 .pread_send_fn = vfswrap_pread_send,
2302 .pread_recv_fn = vfswrap_pread_recv,
2303 .write_fn = vfswrap_write,
2304 .pwrite_fn = vfswrap_pwrite,
2305 .pwrite_send_fn = vfswrap_pwrite_send,
2306 .pwrite_recv_fn = vfswrap_pwrite_recv,
2307 .lseek_fn = vfswrap_lseek,
2308 .sendfile_fn = vfswrap_sendfile,
2309 .recvfile_fn = vfswrap_recvfile,
2310 .rename_fn = vfswrap_rename,
2311 .fsync_fn = vfswrap_fsync,
2312 .stat_fn = vfswrap_stat,
2313 .fstat_fn = vfswrap_fstat,
2314 .lstat_fn = vfswrap_lstat,
2315 .get_alloc_size_fn = vfswrap_get_alloc_size,
2316 .unlink_fn = vfswrap_unlink,
2317 .chmod_fn = vfswrap_chmod,
2318 .fchmod_fn = vfswrap_fchmod,
2319 .chown_fn = vfswrap_chown,
2320 .fchown_fn = vfswrap_fchown,
2321 .lchown_fn = vfswrap_lchown,
2322 .chdir_fn = vfswrap_chdir,
2323 .getwd_fn = vfswrap_getwd,
2324 .ntimes_fn = vfswrap_ntimes,
2325 .ftruncate_fn = vfswrap_ftruncate,
2326 .fallocate_fn = vfswrap_fallocate,
2327 .lock_fn = vfswrap_lock,
2328 .kernel_flock_fn = vfswrap_kernel_flock,
2329 .linux_setlease_fn = vfswrap_linux_setlease,
2330 .getlock_fn = vfswrap_getlock,
2331 .symlink_fn = vfswrap_symlink,
2332 .readlink_fn = vfswrap_readlink,
2333 .link_fn = vfswrap_link,
2334 .mknod_fn = vfswrap_mknod,
2335 .realpath_fn = vfswrap_realpath,
2336 .notify_watch_fn = vfswrap_notify_watch,
2337 .chflags_fn = vfswrap_chflags,
2338 .file_id_create_fn = vfswrap_file_id_create,
2339 .streaminfo_fn = vfswrap_streaminfo,
2340 .get_real_filename_fn = vfswrap_get_real_filename,
2341 .connectpath_fn = vfswrap_connectpath,
2342 .brl_lock_windows_fn = vfswrap_brl_lock_windows,
2343 .brl_unlock_windows_fn = vfswrap_brl_unlock_windows,
2344 .brl_cancel_windows_fn = vfswrap_brl_cancel_windows,
2345 .strict_lock_fn = vfswrap_strict_lock,
2346 .strict_unlock_fn = vfswrap_strict_unlock,
2347 .translate_name_fn = vfswrap_translate_name,
2348 .fsctl_fn = vfswrap_fsctl,
2350 /* NT ACL operations. */
2352 .fget_nt_acl_fn = vfswrap_fget_nt_acl,
2353 .get_nt_acl_fn = vfswrap_get_nt_acl,
2354 .fset_nt_acl_fn = vfswrap_fset_nt_acl,
2355 .audit_file_fn = vfswrap_audit_file,
2357 /* POSIX ACL operations. */
2359 .chmod_acl_fn = vfswrap_chmod_acl,
2360 .fchmod_acl_fn = vfswrap_fchmod_acl,
2362 .sys_acl_get_entry_fn = vfswrap_sys_acl_get_entry,
2363 .sys_acl_get_tag_type_fn = vfswrap_sys_acl_get_tag_type,
2364 .sys_acl_get_permset_fn = vfswrap_sys_acl_get_permset,
2365 .sys_acl_get_qualifier_fn = vfswrap_sys_acl_get_qualifier,
2366 .sys_acl_get_file_fn = vfswrap_sys_acl_get_file,
2367 .sys_acl_get_fd_fn = vfswrap_sys_acl_get_fd,
2368 .sys_acl_clear_perms_fn = vfswrap_sys_acl_clear_perms,
2369 .sys_acl_add_perm_fn = vfswrap_sys_acl_add_perm,
2370 .sys_acl_to_text_fn = vfswrap_sys_acl_to_text,
2371 .sys_acl_init_fn = vfswrap_sys_acl_init,
2372 .sys_acl_create_entry_fn = vfswrap_sys_acl_create_entry,
2373 .sys_acl_set_tag_type_fn = vfswrap_sys_acl_set_tag_type,
2374 .sys_acl_set_qualifier_fn = vfswrap_sys_acl_set_qualifier,
2375 .sys_acl_set_permset_fn = vfswrap_sys_acl_set_permset,
2376 .sys_acl_valid_fn = vfswrap_sys_acl_valid,
2377 .sys_acl_set_file_fn = vfswrap_sys_acl_set_file,
2378 .sys_acl_set_fd_fn = vfswrap_sys_acl_set_fd,
2379 .sys_acl_delete_def_file_fn = vfswrap_sys_acl_delete_def_file,
2380 .sys_acl_get_perm_fn = vfswrap_sys_acl_get_perm,
2381 .sys_acl_free_text_fn = vfswrap_sys_acl_free_text,
2382 .sys_acl_free_acl_fn = vfswrap_sys_acl_free_acl,
2383 .sys_acl_free_qualifier_fn = vfswrap_sys_acl_free_qualifier,
2385 /* EA operations. */
2386 .getxattr_fn = vfswrap_getxattr,
2387 .fgetxattr_fn = vfswrap_fgetxattr,
2388 .listxattr_fn = vfswrap_listxattr,
2389 .flistxattr_fn = vfswrap_flistxattr,
2390 .removexattr_fn = vfswrap_removexattr,
2391 .fremovexattr_fn = vfswrap_fremovexattr,
2392 .setxattr_fn = vfswrap_setxattr,
2393 .fsetxattr_fn = vfswrap_fsetxattr,
2395 /* aio operations */
2396 .aio_read_fn = vfswrap_aio_read,
2397 .aio_write_fn = vfswrap_aio_write,
2398 .aio_return_fn = vfswrap_aio_return,
2399 .aio_cancel_fn = vfswrap_aio_cancel,
2400 .aio_error_fn = vfswrap_aio_error,
2401 .aio_fsync_fn = vfswrap_aio_fsync,
2402 .aio_suspend_fn = vfswrap_aio_suspend,
2403 .aio_force_fn = vfswrap_aio_force,
2405 /* offline operations */
2406 .is_offline_fn = vfswrap_is_offline,
2407 .set_offline_fn = vfswrap_set_offline
2410 NTSTATUS vfs_default_init(void);
2411 NTSTATUS vfs_default_init(void)
2413 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
2414 DEFAULT_VFS_MODULE_NAME, &vfs_default_fns);