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 static ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n)
587 START_PROFILE_BYTES(syscall_write, n);
588 result = sys_write(fsp->fh->fd, data, n);
589 END_PROFILE(syscall_write);
593 static ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, const void *data,
594 size_t n, off_t offset)
598 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
599 START_PROFILE_BYTES(syscall_pwrite, n);
600 result = sys_pwrite(fsp->fh->fd, data, n, offset);
601 END_PROFILE(syscall_pwrite);
603 if (result == -1 && errno == ESPIPE) {
604 /* Maintain the fiction that pipes can be sought on. */
605 result = SMB_VFS_WRITE(fsp, data, n);
608 #else /* HAVE_PWRITE */
612 curr = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
617 if (SMB_VFS_LSEEK(fsp, offset, SEEK_SET) == -1) {
621 result = SMB_VFS_WRITE(fsp, data, n);
624 SMB_VFS_LSEEK(fsp, curr, SEEK_SET);
627 #endif /* HAVE_PWRITE */
632 struct vfswrap_pwrite_state {
636 static struct tevent_req *vfswrap_pwrite_send(
637 struct vfs_handle_struct *handle,
638 TALLOC_CTX *mem_ctx, struct tevent_context *ev,
639 struct files_struct *fsp, const void *data, size_t n, off_t offset)
641 struct tevent_req *req;
642 struct vfswrap_pwrite_state *state;
645 req = tevent_req_create(mem_ctx, &state,
646 struct vfswrap_pwrite_state);
651 START_PROFILE_BYTES(syscall_pwrite, n);
652 state->retval = sys_pwrite(fsp->fh->fd, data, n, offset);
654 END_PROFILE(syscall_pwrite);
656 if (state->retval == -1) {
657 tevent_req_error(req, saved_errno);
659 tevent_req_done(req);
661 return tevent_req_post(req, ev);
664 static ssize_t vfswrap_pwrite_recv(struct tevent_req *req, int *perrno)
666 struct vfswrap_pwrite_state *state = tevent_req_data(
667 req, struct vfswrap_pwrite_state);
670 if (tevent_req_is_unix_error(req, &err)) {
674 return state->retval;
677 static off_t vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, off_t offset, int whence)
681 START_PROFILE(syscall_lseek);
683 /* Cope with 'stat' file opens. */
684 if (fsp->fh->fd != -1)
685 result = lseek(fsp->fh->fd, offset, whence);
688 * We want to maintain the fiction that we can seek
689 * on a fifo for file system purposes. This allows
690 * people to set up UNIX fifo's that feed data to Windows
694 if((result == -1) && (errno == ESPIPE)) {
699 END_PROFILE(syscall_lseek);
703 static ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fromfsp, const DATA_BLOB *hdr,
704 off_t offset, size_t n)
708 START_PROFILE_BYTES(syscall_sendfile, n);
709 result = sys_sendfile(tofd, fromfsp->fh->fd, hdr, offset, n);
710 END_PROFILE(syscall_sendfile);
714 static ssize_t vfswrap_recvfile(vfs_handle_struct *handle,
722 START_PROFILE_BYTES(syscall_recvfile, n);
723 result = sys_recvfile(fromfd, tofsp->fh->fd, offset, n);
724 END_PROFILE(syscall_recvfile);
728 static int vfswrap_rename(vfs_handle_struct *handle,
729 const struct smb_filename *smb_fname_src,
730 const struct smb_filename *smb_fname_dst)
734 START_PROFILE(syscall_rename);
736 if (smb_fname_src->stream_name || smb_fname_dst->stream_name) {
741 result = rename(smb_fname_src->base_name, smb_fname_dst->base_name);
744 END_PROFILE(syscall_rename);
748 static int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp)
753 START_PROFILE(syscall_fsync);
754 result = fsync(fsp->fh->fd);
755 END_PROFILE(syscall_fsync);
762 static int vfswrap_stat(vfs_handle_struct *handle,
763 struct smb_filename *smb_fname)
767 START_PROFILE(syscall_stat);
769 if (smb_fname->stream_name) {
774 result = sys_stat(smb_fname->base_name, &smb_fname->st,
775 lp_fake_dir_create_times(SNUM(handle->conn)));
777 END_PROFILE(syscall_stat);
781 static int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
785 START_PROFILE(syscall_fstat);
786 result = sys_fstat(fsp->fh->fd,
787 sbuf, lp_fake_dir_create_times(SNUM(handle->conn)));
788 END_PROFILE(syscall_fstat);
792 static int vfswrap_lstat(vfs_handle_struct *handle,
793 struct smb_filename *smb_fname)
797 START_PROFILE(syscall_lstat);
799 if (smb_fname->stream_name) {
804 result = sys_lstat(smb_fname->base_name, &smb_fname->st,
805 lp_fake_dir_create_times(SNUM(handle->conn)));
807 END_PROFILE(syscall_lstat);
811 static NTSTATUS vfswrap_translate_name(struct vfs_handle_struct *handle,
813 enum vfs_translate_direction direction,
817 return NT_STATUS_NONE_MAPPED;
821 * Implement the default fsctl operation.
823 static bool vfswrap_logged_ioctl_message = false;
825 static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
826 struct files_struct *fsp,
829 uint16_t req_flags, /* Needed for UNICODE ... */
830 const uint8_t *_in_data,
833 uint32_t max_out_len,
836 const char *in_data = (const char *)_in_data;
837 char **out_data = (char **)_out_data;
840 case FSCTL_SET_SPARSE:
842 bool set_sparse = true;
845 if (in_len >= 1 && in_data[0] == 0) {
849 status = file_set_sparse(handle->conn, fsp, set_sparse);
851 DEBUG(NT_STATUS_IS_OK(status) ? 10 : 9,
852 ("FSCTL_SET_SPARSE: fname[%s] set[%u] - %s\n",
853 smb_fname_str_dbg(fsp->fsp_name), set_sparse,
859 case FSCTL_CREATE_OR_GET_OBJECT_ID:
861 unsigned char objid[16];
862 char *return_data = NULL;
864 /* This should return the object-id on this file.
865 * I think I'll make this be the inode+dev. JRA.
868 DEBUG(10,("FSCTL_CREATE_OR_GET_OBJECT_ID: called on %s\n",
871 *out_len = (max_out_len >= 64) ? 64 : max_out_len;
872 /* Hmmm, will this cause problems if less data asked for? */
873 return_data = talloc_array(ctx, char, 64);
874 if (return_data == NULL) {
875 return NT_STATUS_NO_MEMORY;
878 /* For backwards compatibility only store the dev/inode. */
879 push_file_id_16(return_data, &fsp->file_id);
880 memcpy(return_data+16,create_volume_objectid(fsp->conn,objid),16);
881 push_file_id_16(return_data+32, &fsp->file_id);
882 *out_data = return_data;
886 case FSCTL_GET_REPARSE_POINT:
888 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
889 DEBUG(10, ("FSCTL_GET_REPARSE_POINT: called on %s. "
890 "Status: NOT_IMPLEMENTED\n", fsp_fnum_dbg(fsp)));
891 return NT_STATUS_NOT_A_REPARSE_POINT;
894 case FSCTL_SET_REPARSE_POINT:
896 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
897 DEBUG(10, ("FSCTL_SET_REPARSE_POINT: called on %s. "
898 "Status: NOT_IMPLEMENTED\n", fsp_fnum_dbg(fsp)));
899 return NT_STATUS_NOT_A_REPARSE_POINT;
902 case FSCTL_GET_SHADOW_COPY_DATA:
905 * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
906 * and return their volume names. If max_data_count is 16, then it is just
907 * asking for the number of volumes and length of the combined names.
909 * pdata is the data allocated by our caller, but that uses
910 * total_data_count (which is 0 in our case) rather than max_data_count.
911 * Allocate the correct amount and return the pointer to let
912 * it be deallocated when we return.
914 struct shadow_copy_data *shadow_data = NULL;
916 uint32 labels_data_count = 0;
918 char *cur_pdata = NULL;
920 if (max_out_len < 16) {
921 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
923 return NT_STATUS_INVALID_PARAMETER;
926 if (max_out_len > 16) {
930 shadow_data = talloc_zero(ctx, struct shadow_copy_data);
931 if (shadow_data == NULL) {
932 DEBUG(0,("TALLOC_ZERO() failed!\n"));
933 return NT_STATUS_NO_MEMORY;
937 * Call the VFS routine to actually do the work.
939 if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) {
940 TALLOC_FREE(shadow_data);
941 if (errno == ENOSYS) {
942 DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n",
943 fsp->conn->connectpath));
944 return NT_STATUS_NOT_SUPPORTED;
946 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n",
947 fsp->conn->connectpath));
948 return NT_STATUS_UNSUCCESSFUL;
952 labels_data_count = (shadow_data->num_volumes * 2 *
953 sizeof(SHADOW_COPY_LABEL)) + 2;
958 *out_len = 12 + labels_data_count + 4;
961 if (max_out_len < *out_len) {
962 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
963 max_out_len, *out_len));
964 TALLOC_FREE(shadow_data);
965 return NT_STATUS_BUFFER_TOO_SMALL;
968 cur_pdata = talloc_array(ctx, char, *out_len);
969 if (cur_pdata == NULL) {
970 TALLOC_FREE(shadow_data);
971 return NT_STATUS_NO_MEMORY;
974 *out_data = cur_pdata;
976 /* num_volumes 4 bytes */
977 SIVAL(cur_pdata, 0, shadow_data->num_volumes);
980 /* num_labels 4 bytes */
981 SIVAL(cur_pdata, 4, shadow_data->num_volumes);
984 /* needed_data_count 4 bytes */
985 SIVAL(cur_pdata, 8, labels_data_count + 4);
989 DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
990 shadow_data->num_volumes, fsp_str_dbg(fsp)));
991 if (labels && shadow_data->labels) {
992 for (i=0; i<shadow_data->num_volumes; i++) {
993 srvstr_push(cur_pdata, req_flags,
994 cur_pdata, shadow_data->labels[i],
995 2 * sizeof(SHADOW_COPY_LABEL),
996 STR_UNICODE|STR_TERMINATE);
997 cur_pdata += 2 * sizeof(SHADOW_COPY_LABEL);
998 DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i]));
1002 TALLOC_FREE(shadow_data);
1004 return NT_STATUS_OK;
1007 case FSCTL_FIND_FILES_BY_SID:
1009 /* pretend this succeeded -
1011 * we have to send back a list with all files owned by this SID
1013 * but I have to check that --metze
1019 DEBUG(10, ("FSCTL_FIND_FILES_BY_SID: called on %s\n",
1020 fsp_fnum_dbg(fsp)));
1023 /* NT_STATUS_BUFFER_TOO_SMALL maybe? */
1024 return NT_STATUS_INVALID_PARAMETER;
1027 sid_len = MIN(in_len - 4,SID_MAX_SIZE);
1029 /* unknown 4 bytes: this is not the length of the sid :-( */
1030 /*unknown = IVAL(pdata,0);*/
1032 if (!sid_parse(in_data + 4, sid_len, &sid)) {
1033 return NT_STATUS_INVALID_PARAMETER;
1035 DEBUGADD(10, ("for SID: %s\n", sid_string_dbg(&sid)));
1037 if (!sid_to_uid(&sid, &uid)) {
1038 DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
1039 sid_string_dbg(&sid),
1040 (unsigned long)sid_len));
1044 /* we can take a look at the find source :-)
1046 * find ./ -uid $uid -name '*' is what we need here
1049 * and send 4bytes len and then NULL terminated unicode strings
1052 * but I don't know how to deal with the paged results
1053 * (maybe we can hang the result anywhere in the fsp struct)
1055 * but I don't know how to deal with the paged results
1056 * (maybe we can hang the result anywhere in the fsp struct)
1058 * we don't send all files at once
1059 * and at the next we should *not* start from the beginning,
1060 * so we have to cache the result
1065 /* this works for now... */
1066 return NT_STATUS_OK;
1069 case FSCTL_QUERY_ALLOCATED_RANGES:
1071 /* FIXME: This is just a dummy reply, telling that all of the
1072 * file is allocated. MKS cp needs that.
1073 * Adding the real allocated ranges via FIEMAP on Linux
1074 * and SEEK_DATA/SEEK_HOLE on Solaris is needed to make
1075 * this FSCTL correct for sparse files.
1078 uint64_t offset, length;
1079 char *out_data_tmp = NULL;
1082 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: data_count(%u) != 16 is invalid!\n",
1084 return NT_STATUS_INVALID_PARAMETER;
1087 if (max_out_len < 16) {
1088 DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: max_out_len (%u) < 16 is invalid!\n",
1090 return NT_STATUS_INVALID_PARAMETER;
1093 offset = BVAL(in_data,0);
1094 length = BVAL(in_data,8);
1096 if (offset + length < offset) {
1097 /* No 64-bit integer wrap. */
1098 return NT_STATUS_INVALID_PARAMETER;
1101 /* Shouldn't this be SMB_VFS_STAT ... ? */
1102 status = vfs_stat_fsp(fsp);
1103 if (!NT_STATUS_IS_OK(status)) {
1108 out_data_tmp = talloc_array(ctx, char, *out_len);
1109 if (out_data_tmp == NULL) {
1110 DEBUG(10, ("unable to allocate memory for response\n"));
1111 return NT_STATUS_NO_MEMORY;
1114 if (offset > fsp->fsp_name->st.st_ex_size ||
1115 fsp->fsp_name->st.st_ex_size == 0 ||
1117 memset(out_data_tmp, 0, *out_len);
1119 uint64_t end = offset + length;
1120 end = MIN(end, fsp->fsp_name->st.st_ex_size);
1121 SBVAL(out_data_tmp, 0, 0);
1122 SBVAL(out_data_tmp, 8, end);
1125 *out_data = out_data_tmp;
1127 return NT_STATUS_OK;
1130 case FSCTL_IS_VOLUME_DIRTY:
1132 DEBUG(10,("FSCTL_IS_VOLUME_DIRTY: called on %s "
1133 "(but remotely not supported)\n", fsp_fnum_dbg(fsp)));
1135 * http://msdn.microsoft.com/en-us/library/cc232128%28PROT.10%29.aspx
1136 * says we have to respond with NT_STATUS_INVALID_PARAMETER
1138 return NT_STATUS_INVALID_PARAMETER;
1143 * Only print once ... unfortunately there could be lots of
1144 * different FSCTLs that are called.
1146 if (!vfswrap_logged_ioctl_message) {
1147 vfswrap_logged_ioctl_message = true;
1148 DEBUG(2, ("%s (0x%x): Currently not implemented.\n",
1149 __func__, function));
1153 return NT_STATUS_NOT_SUPPORTED;
1156 /********************************************************************
1157 Given a stat buffer return the allocated size on disk, taking into
1158 account sparse files.
1159 ********************************************************************/
1160 static uint64_t vfswrap_get_alloc_size(vfs_handle_struct *handle,
1161 struct files_struct *fsp,
1162 const SMB_STRUCT_STAT *sbuf)
1166 START_PROFILE(syscall_get_alloc_size);
1168 if(S_ISDIR(sbuf->st_ex_mode)) {
1173 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
1174 /* The type of st_blocksize is blkcnt_t which *MUST* be
1175 signed (according to POSIX) and can be less than 64-bits.
1176 Ensure when we're converting to 64 bits wide we don't
1178 #if defined(SIZEOF_BLKCNT_T_8)
1179 result = (uint64_t)STAT_ST_BLOCKSIZE * (uint64_t)sbuf->st_ex_blocks;
1180 #elif defined(SIZEOF_BLKCNT_T_4)
1182 uint64_t bs = ((uint64_t)sbuf->st_ex_blocks) & 0xFFFFFFFFLL;
1183 result = (uint64_t)STAT_ST_BLOCKSIZE * bs;
1186 #error SIZEOF_BLKCNT_T_NOT_A_SUPPORTED_VALUE
1189 result = get_file_size_stat(sbuf);
1192 if (fsp && fsp->initial_allocation_size)
1193 result = MAX(result,fsp->initial_allocation_size);
1195 result = smb_roundup(handle->conn, result);
1198 END_PROFILE(syscall_get_alloc_size);
1202 static int vfswrap_unlink(vfs_handle_struct *handle,
1203 const struct smb_filename *smb_fname)
1207 START_PROFILE(syscall_unlink);
1209 if (smb_fname->stream_name) {
1213 result = unlink(smb_fname->base_name);
1216 END_PROFILE(syscall_unlink);
1220 static int vfswrap_chmod(vfs_handle_struct *handle, const char *path, mode_t mode)
1224 START_PROFILE(syscall_chmod);
1227 * We need to do this due to the fact that the default POSIX ACL
1228 * chmod modifies the ACL *mask* for the group owner, not the
1229 * group owner bits directly. JRA.
1234 int saved_errno = errno; /* We might get ENOSYS */
1235 if ((result = SMB_VFS_CHMOD_ACL(handle->conn, path, mode)) == 0) {
1236 END_PROFILE(syscall_chmod);
1239 /* Error - return the old errno. */
1240 errno = saved_errno;
1243 result = chmod(path, mode);
1244 END_PROFILE(syscall_chmod);
1248 static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
1252 START_PROFILE(syscall_fchmod);
1255 * We need to do this due to the fact that the default POSIX ACL
1256 * chmod modifies the ACL *mask* for the group owner, not the
1257 * group owner bits directly. JRA.
1261 int saved_errno = errno; /* We might get ENOSYS */
1262 if ((result = SMB_VFS_FCHMOD_ACL(fsp, mode)) == 0) {
1263 END_PROFILE(syscall_fchmod);
1266 /* Error - return the old errno. */
1267 errno = saved_errno;
1270 #if defined(HAVE_FCHMOD)
1271 result = fchmod(fsp->fh->fd, mode);
1277 END_PROFILE(syscall_fchmod);
1281 static int vfswrap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
1285 START_PROFILE(syscall_chown);
1286 result = chown(path, uid, gid);
1287 END_PROFILE(syscall_chown);
1291 static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t uid, gid_t gid)
1296 START_PROFILE(syscall_fchown);
1297 result = fchown(fsp->fh->fd, uid, gid);
1298 END_PROFILE(syscall_fchown);
1306 static int vfswrap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
1310 START_PROFILE(syscall_lchown);
1311 result = lchown(path, uid, gid);
1312 END_PROFILE(syscall_lchown);
1316 static int vfswrap_chdir(vfs_handle_struct *handle, const char *path)
1320 START_PROFILE(syscall_chdir);
1321 result = chdir(path);
1322 END_PROFILE(syscall_chdir);
1326 static char *vfswrap_getwd(vfs_handle_struct *handle)
1330 START_PROFILE(syscall_getwd);
1331 result = sys_getwd();
1332 END_PROFILE(syscall_getwd);
1336 /*********************************************************************
1337 nsec timestamp resolution call. Convert down to whatever the underlying
1338 system will support.
1339 **********************************************************************/
1341 static int vfswrap_ntimes(vfs_handle_struct *handle,
1342 const struct smb_filename *smb_fname,
1343 struct smb_file_time *ft)
1347 START_PROFILE(syscall_ntimes);
1349 if (smb_fname->stream_name) {
1355 if (null_timespec(ft->atime)) {
1356 ft->atime= smb_fname->st.st_ex_atime;
1359 if (null_timespec(ft->mtime)) {
1360 ft->mtime = smb_fname->st.st_ex_mtime;
1363 if (!null_timespec(ft->create_time)) {
1364 set_create_timespec_ea(handle->conn,
1369 if ((timespec_compare(&ft->atime,
1370 &smb_fname->st.st_ex_atime) == 0) &&
1371 (timespec_compare(&ft->mtime,
1372 &smb_fname->st.st_ex_mtime) == 0)) {
1377 #if defined(HAVE_UTIMENSAT)
1379 struct timespec ts[2];
1382 result = utimensat(AT_FDCWD, smb_fname->base_name, ts, 0);
1384 result = utimensat(AT_FDCWD, smb_fname->base_name, NULL, 0);
1386 if (!((result == -1) && (errno == ENOSYS))) {
1390 #if defined(HAVE_UTIMES)
1392 struct timeval tv[2];
1393 tv[0] = convert_timespec_to_timeval(ft->atime);
1394 tv[1] = convert_timespec_to_timeval(ft->mtime);
1395 result = utimes(smb_fname->base_name, tv);
1397 result = utimes(smb_fname->base_name, NULL);
1399 if (!((result == -1) && (errno == ENOSYS))) {
1403 #if defined(HAVE_UTIME)
1405 struct utimbuf times;
1406 times.actime = convert_timespec_to_time_t(ft->atime);
1407 times.modtime = convert_timespec_to_time_t(ft->mtime);
1408 result = utime(smb_fname->base_name, ×);
1410 result = utime(smb_fname->base_name, NULL);
1412 if (!((result == -1) && (errno == ENOSYS))) {
1420 END_PROFILE(syscall_ntimes);
1424 /*********************************************************************
1425 A version of ftruncate that will write the space on disk if strict
1427 **********************************************************************/
1429 static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, off_t len)
1431 off_t space_to_write;
1432 uint64_t space_avail;
1433 uint64_t bsize,dfree,dsize;
1436 SMB_STRUCT_STAT *pst;
1438 status = vfs_stat_fsp(fsp);
1439 if (!NT_STATUS_IS_OK(status)) {
1442 pst = &fsp->fsp_name->st;
1445 if (S_ISFIFO(pst->st_ex_mode))
1449 if (pst->st_ex_size == len)
1452 /* Shrink - just ftruncate. */
1453 if (pst->st_ex_size > len)
1454 return ftruncate(fsp->fh->fd, len);
1456 space_to_write = len - pst->st_ex_size;
1458 /* for allocation try fallocate first. This can fail on some
1459 platforms e.g. when the filesystem doesn't support it and no
1460 emulation is being done by the libc (like on AIX with JFS1). In that
1461 case we do our own emulation. fallocate implementations can
1462 return ENOTSUP or EINVAL in cases like that. */
1463 ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
1464 pst->st_ex_size, space_to_write);
1465 if (ret == ENOSPC) {
1472 DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with "
1473 "error %d. Falling back to slow manual allocation\n", ret));
1475 /* available disk space is enough or not? */
1476 space_avail = get_dfree_info(fsp->conn,
1477 fsp->fsp_name->base_name, false,
1478 &bsize,&dfree,&dsize);
1479 /* space_avail is 1k blocks */
1480 if (space_avail == (uint64_t)-1 ||
1481 ((uint64_t)space_to_write/1024 > space_avail) ) {
1486 /* Write out the real space on disk. */
1487 ret = vfs_slow_fallocate(fsp, pst->st_ex_size, space_to_write);
1496 static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, off_t len)
1499 SMB_STRUCT_STAT *pst;
1503 START_PROFILE(syscall_ftruncate);
1505 if (lp_strict_allocate(SNUM(fsp->conn)) && !fsp->is_sparse) {
1506 result = strict_allocate_ftruncate(handle, fsp, len);
1507 END_PROFILE(syscall_ftruncate);
1511 /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
1512 ftruncate if the system supports it. Then I discovered that
1513 you can have some filesystems that support ftruncate
1514 expansion and some that don't! On Linux fat can't do
1515 ftruncate extend but ext2 can. */
1517 result = ftruncate(fsp->fh->fd, len);
1521 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
1522 extend a file with ftruncate. Provide alternate implementation
1525 /* Do an fstat to see if the file is longer than the requested
1526 size in which case the ftruncate above should have
1527 succeeded or shorter, in which case seek to len - 1 and
1528 write 1 byte of zero */
1529 status = vfs_stat_fsp(fsp);
1530 if (!NT_STATUS_IS_OK(status)) {
1533 pst = &fsp->fsp_name->st;
1536 if (S_ISFIFO(pst->st_ex_mode)) {
1542 if (pst->st_ex_size == len) {
1547 if (pst->st_ex_size > len) {
1548 /* the ftruncate should have worked */
1552 if (SMB_VFS_PWRITE(fsp, &c, 1, len-1)!=1) {
1560 END_PROFILE(syscall_ftruncate);
1564 static int vfswrap_fallocate(vfs_handle_struct *handle,
1566 enum vfs_fallocate_mode mode,
1572 START_PROFILE(syscall_fallocate);
1573 if (mode == VFS_FALLOCATE_EXTEND_SIZE) {
1574 result = sys_posix_fallocate(fsp->fh->fd, offset, len);
1575 } else if (mode == VFS_FALLOCATE_KEEP_SIZE) {
1576 result = sys_fallocate(fsp->fh->fd, mode, offset, len);
1581 END_PROFILE(syscall_fallocate);
1585 static bool vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int op, off_t offset, off_t count, int type)
1589 START_PROFILE(syscall_fcntl_lock);
1590 result = fcntl_lock(fsp->fh->fd, op, offset, count, type);
1591 END_PROFILE(syscall_fcntl_lock);
1595 static int vfswrap_kernel_flock(vfs_handle_struct *handle, files_struct *fsp,
1596 uint32 share_mode, uint32 access_mask)
1598 START_PROFILE(syscall_kernel_flock);
1599 kernel_flock(fsp->fh->fd, share_mode, access_mask);
1600 END_PROFILE(syscall_kernel_flock);
1604 static bool vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid)
1608 START_PROFILE(syscall_fcntl_getlock);
1609 result = fcntl_getlock(fsp->fh->fd, poffset, pcount, ptype, ppid);
1610 END_PROFILE(syscall_fcntl_getlock);
1614 static int vfswrap_linux_setlease(vfs_handle_struct *handle, files_struct *fsp,
1619 START_PROFILE(syscall_linux_setlease);
1621 #ifdef HAVE_KERNEL_OPLOCKS_LINUX
1622 result = linux_setlease(fsp->fh->fd, leasetype);
1626 END_PROFILE(syscall_linux_setlease);
1630 static int vfswrap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
1634 START_PROFILE(syscall_symlink);
1635 result = symlink(oldpath, newpath);
1636 END_PROFILE(syscall_symlink);
1640 static int vfswrap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz)
1644 START_PROFILE(syscall_readlink);
1645 result = readlink(path, buf, bufsiz);
1646 END_PROFILE(syscall_readlink);
1650 static int vfswrap_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
1654 START_PROFILE(syscall_link);
1655 result = link(oldpath, newpath);
1656 END_PROFILE(syscall_link);
1660 static int vfswrap_mknod(vfs_handle_struct *handle, const char *pathname, mode_t mode, SMB_DEV_T dev)
1664 START_PROFILE(syscall_mknod);
1665 result = sys_mknod(pathname, mode, dev);
1666 END_PROFILE(syscall_mknod);
1670 static char *vfswrap_realpath(vfs_handle_struct *handle, const char *path)
1674 START_PROFILE(syscall_realpath);
1675 #ifdef REALPATH_TAKES_NULL
1676 result = realpath(path, NULL);
1678 result = SMB_MALLOC_ARRAY(char, PATH_MAX+1);
1680 char *resolved_path = realpath(path, result);
1681 if (!resolved_path) {
1684 /* SMB_ASSERT(result == resolved_path) ? */
1685 result = resolved_path;
1689 END_PROFILE(syscall_realpath);
1693 static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle,
1694 struct sys_notify_context *ctx,
1697 uint32_t *subdir_filter,
1698 void (*callback)(struct sys_notify_context *ctx,
1700 struct notify_event *ev),
1701 void *private_data, void *handle)
1704 * So far inotify is the only supported default notify mechanism. If
1705 * another platform like the the BSD's or a proprietary Unix comes
1706 * along and wants another default, we can play the same trick we
1707 * played with Posix ACLs.
1709 * Until that is the case, hard-code inotify here.
1712 if (lp_kernel_change_notify(vfs_handle->conn->params)) {
1713 return inotify_watch(ctx, path, filter, subdir_filter,
1714 callback, private_data, handle);
1718 * Do nothing, leave everything to notify_internal.c
1720 return NT_STATUS_OK;
1723 static int vfswrap_chflags(vfs_handle_struct *handle, const char *path,
1727 return chflags(path, flags);
1734 static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle,
1735 const SMB_STRUCT_STAT *sbuf)
1739 /* the ZERO_STRUCT ensures padding doesn't break using the key as a
1743 key.devid = sbuf->st_ex_dev;
1744 key.inode = sbuf->st_ex_ino;
1745 /* key.extid is unused by default. */
1750 static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
1751 struct files_struct *fsp,
1753 TALLOC_CTX *mem_ctx,
1754 unsigned int *pnum_streams,
1755 struct stream_struct **pstreams)
1757 SMB_STRUCT_STAT sbuf;
1758 struct stream_struct *tmp_streams = NULL;
1761 if ((fsp != NULL) && (fsp->is_directory)) {
1763 * No default streams on directories
1768 if ((fsp != NULL) && (fsp->fh->fd != -1)) {
1769 ret = SMB_VFS_FSTAT(fsp, &sbuf);
1772 struct smb_filename smb_fname;
1774 ZERO_STRUCT(smb_fname);
1775 smb_fname.base_name = discard_const_p(char, fname);
1777 if (lp_posix_pathnames()) {
1778 ret = SMB_VFS_LSTAT(handle->conn, &smb_fname);
1780 ret = SMB_VFS_STAT(handle->conn, &smb_fname);
1782 sbuf = smb_fname.st;
1786 return map_nt_error_from_unix(errno);
1789 if (S_ISDIR(sbuf.st_ex_mode)) {
1793 tmp_streams = talloc_realloc(mem_ctx, *pstreams, struct stream_struct,
1794 (*pnum_streams) + 1);
1795 if (tmp_streams == NULL) {
1796 return NT_STATUS_NO_MEMORY;
1798 tmp_streams[*pnum_streams].name = talloc_strdup(tmp_streams, "::$DATA");
1799 if (tmp_streams[*pnum_streams].name == NULL) {
1800 return NT_STATUS_NO_MEMORY;
1802 tmp_streams[*pnum_streams].size = sbuf.st_ex_size;
1803 tmp_streams[*pnum_streams].alloc_size = SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp, &sbuf);
1806 *pstreams = tmp_streams;
1808 return NT_STATUS_OK;
1811 static int vfswrap_get_real_filename(struct vfs_handle_struct *handle,
1814 TALLOC_CTX *mem_ctx,
1818 * Don't fall back to get_real_filename so callers can differentiate
1819 * between a full directory scan and an actual case-insensitive stat.
1825 static const char *vfswrap_connectpath(struct vfs_handle_struct *handle,
1828 return handle->conn->connectpath;
1831 static NTSTATUS vfswrap_brl_lock_windows(struct vfs_handle_struct *handle,
1832 struct byte_range_lock *br_lck,
1833 struct lock_struct *plock,
1835 struct blocking_lock_record *blr)
1837 SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1839 /* Note: blr is not used in the default implementation. */
1840 return brl_lock_windows_default(br_lck, plock, blocking_lock);
1843 static bool vfswrap_brl_unlock_windows(struct vfs_handle_struct *handle,
1844 struct messaging_context *msg_ctx,
1845 struct byte_range_lock *br_lck,
1846 const struct lock_struct *plock)
1848 SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1850 return brl_unlock_windows_default(msg_ctx, br_lck, plock);
1853 static bool vfswrap_brl_cancel_windows(struct vfs_handle_struct *handle,
1854 struct byte_range_lock *br_lck,
1855 struct lock_struct *plock,
1856 struct blocking_lock_record *blr)
1858 SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1860 /* Note: blr is not used in the default implementation. */
1861 return brl_lock_cancel_default(br_lck, plock);
1864 static bool vfswrap_strict_lock(struct vfs_handle_struct *handle,
1866 struct lock_struct *plock)
1868 SMB_ASSERT(plock->lock_type == READ_LOCK ||
1869 plock->lock_type == WRITE_LOCK);
1871 return strict_lock_default(fsp, plock);
1874 static void vfswrap_strict_unlock(struct vfs_handle_struct *handle,
1876 struct lock_struct *plock)
1878 SMB_ASSERT(plock->lock_type == READ_LOCK ||
1879 plock->lock_type == WRITE_LOCK);
1881 strict_unlock_default(fsp, plock);
1884 /* NT ACL operations. */
1886 static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle,
1888 uint32 security_info,
1889 struct security_descriptor **ppdesc)
1893 START_PROFILE(fget_nt_acl);
1894 result = posix_fget_nt_acl(fsp, security_info, ppdesc);
1895 END_PROFILE(fget_nt_acl);
1899 static NTSTATUS vfswrap_get_nt_acl(vfs_handle_struct *handle,
1901 uint32 security_info,
1902 struct security_descriptor **ppdesc)
1906 START_PROFILE(get_nt_acl);
1907 result = posix_get_nt_acl(handle->conn, name, security_info, ppdesc);
1908 END_PROFILE(get_nt_acl);
1912 static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, const struct security_descriptor *psd)
1916 START_PROFILE(fset_nt_acl);
1917 result = set_nt_acl(fsp, security_info_sent, psd);
1918 END_PROFILE(fset_nt_acl);
1922 static NTSTATUS vfswrap_audit_file(struct vfs_handle_struct *handle,
1923 struct smb_filename *file,
1924 struct security_acl *sacl,
1925 uint32_t access_requested,
1926 uint32_t access_denied)
1928 return NT_STATUS_OK; /* Nothing to do here ... */
1931 static int vfswrap_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode)
1939 START_PROFILE(chmod_acl);
1940 result = chmod_acl(handle->conn, name, mode);
1941 END_PROFILE(chmod_acl);
1946 static int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
1954 START_PROFILE(fchmod_acl);
1955 result = fchmod_acl(fsp, mode);
1956 END_PROFILE(fchmod_acl);
1961 static int vfswrap_sys_acl_get_entry(vfs_handle_struct *handle, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1963 return sys_acl_get_entry(theacl, entry_id, entry_p);
1966 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)
1968 return sys_acl_get_tag_type(entry_d, tag_type_p);
1971 static int vfswrap_sys_acl_get_permset(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1973 return sys_acl_get_permset(entry_d, permset_p);
1976 static void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d)
1978 return sys_acl_get_qualifier(entry_d);
1981 static SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, SMB_ACL_TYPE_T type)
1983 return sys_acl_get_file(handle, path_p, type);
1986 static SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp)
1988 return sys_acl_get_fd(handle, fsp);
1991 static int vfswrap_sys_acl_clear_perms(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset)
1993 return sys_acl_clear_perms(permset);
1996 static int vfswrap_sys_acl_add_perm(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1998 return sys_acl_add_perm(permset, perm);
2001 static char * vfswrap_sys_acl_to_text(vfs_handle_struct *handle, SMB_ACL_T theacl, ssize_t *plen)
2003 return sys_acl_to_text(theacl, plen);
2006 static SMB_ACL_T vfswrap_sys_acl_init(vfs_handle_struct *handle, int count)
2008 return sys_acl_init(count);
2011 static int vfswrap_sys_acl_create_entry(vfs_handle_struct *handle, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
2013 return sys_acl_create_entry(pacl, pentry);
2016 static int vfswrap_sys_acl_set_tag_type(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
2018 return sys_acl_set_tag_type(entry, tagtype);
2021 static int vfswrap_sys_acl_set_qualifier(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, void *qual)
2023 return sys_acl_set_qualifier(entry, qual);
2026 static int vfswrap_sys_acl_set_permset(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
2028 return sys_acl_set_permset(entry, permset);
2031 static int vfswrap_sys_acl_valid(vfs_handle_struct *handle, SMB_ACL_T theacl )
2033 return sys_acl_valid(theacl );
2036 static int vfswrap_sys_acl_set_file(vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
2038 return sys_acl_set_file(handle, name, acltype, theacl);
2041 static int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_T theacl)
2043 return sys_acl_set_fd(handle, fsp, theacl);
2046 static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle, const char *path)
2048 return sys_acl_delete_def_file(handle, path);
2051 static int vfswrap_sys_acl_get_perm(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
2053 return sys_acl_get_perm(permset, perm);
2056 static int vfswrap_sys_acl_free_text(vfs_handle_struct *handle, char *text)
2058 return sys_acl_free_text(text);
2061 static int vfswrap_sys_acl_free_acl(vfs_handle_struct *handle, SMB_ACL_T posix_acl)
2063 return sys_acl_free_acl(posix_acl);
2066 static int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle, void *qualifier, SMB_ACL_TAG_T tagtype)
2068 return sys_acl_free_qualifier(qualifier, tagtype);
2071 /****************************************************************
2072 Extended attribute operations.
2073 *****************************************************************/
2075 static ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
2077 return getxattr(path, name, value, size);
2080 static ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, void *value, size_t size)
2082 return fgetxattr(fsp->fh->fd, name, value, size);
2085 static ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
2087 return listxattr(path, list, size);
2090 static ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size)
2092 return flistxattr(fsp->fh->fd, list, size);
2095 static int vfswrap_removexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
2097 return removexattr(path, name);
2100 static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name)
2102 return fremovexattr(fsp->fh->fd, name);
2105 static int vfswrap_setxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
2107 return setxattr(path, name, value, size, flags);
2110 static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, const void *value, size_t size, int flags)
2112 return fsetxattr(fsp->fh->fd, name, value, size, flags);
2115 static int vfswrap_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2118 if (!initialize_async_io_handler()) {
2123 * aio_read must be done as root, because in the glibc aio
2124 * implementation the helper thread needs to be able to send a signal
2125 * to the main thread, even when it has done a seteuid() to a
2129 ret = sys_aio_read(aiocb);
2134 static int vfswrap_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2137 if (!initialize_async_io_handler()) {
2142 * aio_write must be done as root, because in the glibc aio
2143 * implementation the helper thread needs to be able to send a signal
2144 * to the main thread, even when it has done a seteuid() to a
2148 ret = sys_aio_write(aiocb);
2153 static ssize_t vfswrap_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2155 return sys_aio_return(aiocb);
2158 static int vfswrap_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2160 return sys_aio_cancel(fsp->fh->fd, aiocb);
2163 static int vfswrap_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2165 return sys_aio_error(aiocb);
2168 static int vfswrap_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb)
2170 return sys_aio_fsync(op, aiocb);
2173 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)
2175 return sys_aio_suspend(aiocb, n, timeout);
2178 static bool vfswrap_aio_force(struct vfs_handle_struct *handle, struct files_struct *fsp)
2183 static bool vfswrap_is_offline(struct vfs_handle_struct *handle,
2184 const struct smb_filename *fname,
2185 SMB_STRUCT_STAT *sbuf)
2189 bool offline = false;
2191 if (ISDOT(fname->base_name) || ISDOTDOT(fname->base_name)) {
2195 if (!lp_dmapi_support(SNUM(handle->conn)) || !dmapi_have_session()) {
2196 #if defined(ENOTSUP)
2202 status = get_full_smb_filename(talloc_tos(), fname, &path);
2203 if (!NT_STATUS_IS_OK(status)) {
2204 errno = map_errno_from_nt_status(status);
2208 offline = (dmapi_file_flags(path) & FILE_ATTRIBUTE_OFFLINE) != 0;
2215 static int vfswrap_set_offline(struct vfs_handle_struct *handle,
2216 const struct smb_filename *fname)
2218 /* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */
2219 #if defined(ENOTSUP)
2225 static struct vfs_fn_pointers vfs_default_fns = {
2226 /* Disk operations */
2228 .connect_fn = vfswrap_connect,
2229 .disconnect_fn = vfswrap_disconnect,
2230 .disk_free_fn = vfswrap_disk_free,
2231 .get_quota_fn = vfswrap_get_quota,
2232 .set_quota_fn = vfswrap_set_quota,
2233 .get_shadow_copy_data_fn = vfswrap_get_shadow_copy_data,
2234 .statvfs_fn = vfswrap_statvfs,
2235 .fs_capabilities_fn = vfswrap_fs_capabilities,
2236 .get_dfs_referrals_fn = vfswrap_get_dfs_referrals,
2238 /* Directory operations */
2240 .opendir_fn = vfswrap_opendir,
2241 .fdopendir_fn = vfswrap_fdopendir,
2242 .readdir_fn = vfswrap_readdir,
2243 .seekdir_fn = vfswrap_seekdir,
2244 .telldir_fn = vfswrap_telldir,
2245 .rewind_dir_fn = vfswrap_rewinddir,
2246 .mkdir_fn = vfswrap_mkdir,
2247 .rmdir_fn = vfswrap_rmdir,
2248 .closedir_fn = vfswrap_closedir,
2249 .init_search_op_fn = vfswrap_init_search_op,
2251 /* File operations */
2253 .open_fn = vfswrap_open,
2254 .create_file_fn = vfswrap_create_file,
2255 .close_fn = vfswrap_close,
2256 .read_fn = vfswrap_read,
2257 .pread_fn = vfswrap_pread,
2258 .write_fn = vfswrap_write,
2259 .pwrite_fn = vfswrap_pwrite,
2260 .pwrite_send_fn = vfswrap_pwrite_send,
2261 .pwrite_recv_fn = vfswrap_pwrite_recv,
2262 .lseek_fn = vfswrap_lseek,
2263 .sendfile_fn = vfswrap_sendfile,
2264 .recvfile_fn = vfswrap_recvfile,
2265 .rename_fn = vfswrap_rename,
2266 .fsync_fn = vfswrap_fsync,
2267 .stat_fn = vfswrap_stat,
2268 .fstat_fn = vfswrap_fstat,
2269 .lstat_fn = vfswrap_lstat,
2270 .get_alloc_size_fn = vfswrap_get_alloc_size,
2271 .unlink_fn = vfswrap_unlink,
2272 .chmod_fn = vfswrap_chmod,
2273 .fchmod_fn = vfswrap_fchmod,
2274 .chown_fn = vfswrap_chown,
2275 .fchown_fn = vfswrap_fchown,
2276 .lchown_fn = vfswrap_lchown,
2277 .chdir_fn = vfswrap_chdir,
2278 .getwd_fn = vfswrap_getwd,
2279 .ntimes_fn = vfswrap_ntimes,
2280 .ftruncate_fn = vfswrap_ftruncate,
2281 .fallocate_fn = vfswrap_fallocate,
2282 .lock_fn = vfswrap_lock,
2283 .kernel_flock_fn = vfswrap_kernel_flock,
2284 .linux_setlease_fn = vfswrap_linux_setlease,
2285 .getlock_fn = vfswrap_getlock,
2286 .symlink_fn = vfswrap_symlink,
2287 .readlink_fn = vfswrap_readlink,
2288 .link_fn = vfswrap_link,
2289 .mknod_fn = vfswrap_mknod,
2290 .realpath_fn = vfswrap_realpath,
2291 .notify_watch_fn = vfswrap_notify_watch,
2292 .chflags_fn = vfswrap_chflags,
2293 .file_id_create_fn = vfswrap_file_id_create,
2294 .streaminfo_fn = vfswrap_streaminfo,
2295 .get_real_filename_fn = vfswrap_get_real_filename,
2296 .connectpath_fn = vfswrap_connectpath,
2297 .brl_lock_windows_fn = vfswrap_brl_lock_windows,
2298 .brl_unlock_windows_fn = vfswrap_brl_unlock_windows,
2299 .brl_cancel_windows_fn = vfswrap_brl_cancel_windows,
2300 .strict_lock_fn = vfswrap_strict_lock,
2301 .strict_unlock_fn = vfswrap_strict_unlock,
2302 .translate_name_fn = vfswrap_translate_name,
2303 .fsctl_fn = vfswrap_fsctl,
2305 /* NT ACL operations. */
2307 .fget_nt_acl_fn = vfswrap_fget_nt_acl,
2308 .get_nt_acl_fn = vfswrap_get_nt_acl,
2309 .fset_nt_acl_fn = vfswrap_fset_nt_acl,
2310 .audit_file_fn = vfswrap_audit_file,
2312 /* POSIX ACL operations. */
2314 .chmod_acl_fn = vfswrap_chmod_acl,
2315 .fchmod_acl_fn = vfswrap_fchmod_acl,
2317 .sys_acl_get_entry_fn = vfswrap_sys_acl_get_entry,
2318 .sys_acl_get_tag_type_fn = vfswrap_sys_acl_get_tag_type,
2319 .sys_acl_get_permset_fn = vfswrap_sys_acl_get_permset,
2320 .sys_acl_get_qualifier_fn = vfswrap_sys_acl_get_qualifier,
2321 .sys_acl_get_file_fn = vfswrap_sys_acl_get_file,
2322 .sys_acl_get_fd_fn = vfswrap_sys_acl_get_fd,
2323 .sys_acl_clear_perms_fn = vfswrap_sys_acl_clear_perms,
2324 .sys_acl_add_perm_fn = vfswrap_sys_acl_add_perm,
2325 .sys_acl_to_text_fn = vfswrap_sys_acl_to_text,
2326 .sys_acl_init_fn = vfswrap_sys_acl_init,
2327 .sys_acl_create_entry_fn = vfswrap_sys_acl_create_entry,
2328 .sys_acl_set_tag_type_fn = vfswrap_sys_acl_set_tag_type,
2329 .sys_acl_set_qualifier_fn = vfswrap_sys_acl_set_qualifier,
2330 .sys_acl_set_permset_fn = vfswrap_sys_acl_set_permset,
2331 .sys_acl_valid_fn = vfswrap_sys_acl_valid,
2332 .sys_acl_set_file_fn = vfswrap_sys_acl_set_file,
2333 .sys_acl_set_fd_fn = vfswrap_sys_acl_set_fd,
2334 .sys_acl_delete_def_file_fn = vfswrap_sys_acl_delete_def_file,
2335 .sys_acl_get_perm_fn = vfswrap_sys_acl_get_perm,
2336 .sys_acl_free_text_fn = vfswrap_sys_acl_free_text,
2337 .sys_acl_free_acl_fn = vfswrap_sys_acl_free_acl,
2338 .sys_acl_free_qualifier_fn = vfswrap_sys_acl_free_qualifier,
2340 /* EA operations. */
2341 .getxattr_fn = vfswrap_getxattr,
2342 .fgetxattr_fn = vfswrap_fgetxattr,
2343 .listxattr_fn = vfswrap_listxattr,
2344 .flistxattr_fn = vfswrap_flistxattr,
2345 .removexattr_fn = vfswrap_removexattr,
2346 .fremovexattr_fn = vfswrap_fremovexattr,
2347 .setxattr_fn = vfswrap_setxattr,
2348 .fsetxattr_fn = vfswrap_fsetxattr,
2350 /* aio operations */
2351 .aio_read_fn = vfswrap_aio_read,
2352 .aio_write_fn = vfswrap_aio_write,
2353 .aio_return_fn = vfswrap_aio_return,
2354 .aio_cancel_fn = vfswrap_aio_cancel,
2355 .aio_error_fn = vfswrap_aio_error,
2356 .aio_fsync_fn = vfswrap_aio_fsync,
2357 .aio_suspend_fn = vfswrap_aio_suspend,
2358 .aio_force_fn = vfswrap_aio_force,
2360 /* offline operations */
2361 .is_offline_fn = vfswrap_is_offline,
2362 .set_offline_fn = vfswrap_set_offline
2365 NTSTATUS vfs_default_init(void);
2366 NTSTATUS vfs_default_init(void)
2368 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
2369 DEFAULT_VFS_MODULE_NAME, &vfs_default_fns);