s3: Remove "conn" from sys_notify_context
[kai/samba-autobuild/.git] / source3 / modules / vfs_default.c
1 /*
2    Unix SMB/CIFS implementation.
3    Wrap disk only vfs functions to sidestep dodgy compilers.
4    Copyright (C) Tim Potter 1998
5    Copyright (C) Jeremy Allison 2007
6
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.
11
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.
16
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/>.
19 */
20
21 #include "includes.h"
22 #include "system/time.h"
23 #include "system/filesys.h"
24 #include "smbd/smbd.h"
25 #include "ntioctl.h"
26 #include "smbprofile.h"
27 #include "../libcli/security/security.h"
28 #include "passdb/lookup_sid.h"
29 #include "source3/include/msdfs.h"
30 #include "librpc/gen_ndr/ndr_dfsblobs.h"
31
32 #undef DBGC_CLASS
33 #define DBGC_CLASS DBGC_VFS
34
35 /* Check for NULL pointer parameters in vfswrap_* functions */
36
37 /* We don't want to have NULL function pointers lying around.  Someone
38    is sure to try and execute them.  These stubs are used to prevent
39    this possibility. */
40
41 static int vfswrap_connect(vfs_handle_struct *handle,  const char *service, const char *user)
42 {
43     return 0;    /* Return >= 0 for success */
44 }
45
46 static void vfswrap_disconnect(vfs_handle_struct *handle)
47 {
48 }
49
50 /* Disk operations */
51
52 static uint64_t vfswrap_disk_free(vfs_handle_struct *handle,  const char *path, bool small_query, uint64_t *bsize,
53                                uint64_t *dfree, uint64_t *dsize)
54 {
55         uint64_t result;
56
57         result = sys_disk_free(handle->conn, path, small_query, bsize, dfree, dsize);
58         return result;
59 }
60
61 static int vfswrap_get_quota(struct vfs_handle_struct *handle,  enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
62 {
63 #ifdef HAVE_SYS_QUOTAS
64         int result;
65
66         START_PROFILE(syscall_get_quota);
67         result = sys_get_quota(handle->conn->connectpath, qtype, id, qt);
68         END_PROFILE(syscall_get_quota);
69         return result;
70 #else
71         errno = ENOSYS;
72         return -1;
73 #endif
74 }
75
76 static int vfswrap_set_quota(struct vfs_handle_struct *handle,  enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
77 {
78 #ifdef HAVE_SYS_QUOTAS
79         int result;
80
81         START_PROFILE(syscall_set_quota);
82         result = sys_set_quota(handle->conn->connectpath, qtype, id, qt);
83         END_PROFILE(syscall_set_quota);
84         return result;
85 #else
86         errno = ENOSYS;
87         return -1;
88 #endif
89 }
90
91 static int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle,
92                                         struct files_struct *fsp,
93                                         struct shadow_copy_data *shadow_copy_data,
94                                         bool labels)
95 {
96         errno = ENOSYS;
97         return -1;  /* Not implemented. */
98 }
99
100 static int vfswrap_statvfs(struct vfs_handle_struct *handle,  const char *path, vfs_statvfs_struct *statbuf)
101 {
102         return sys_statvfs(path, statbuf);
103 }
104
105 static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle,
106                 enum timestamp_set_resolution *p_ts_res)
107 {
108         connection_struct *conn = handle->conn;
109         uint32_t caps = FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
110         struct smb_filename *smb_fname_cpath = NULL;
111         struct vfs_statvfs_struct statbuf;
112         NTSTATUS status;
113         int ret;
114
115         ZERO_STRUCT(statbuf);
116         ret = sys_statvfs(conn->connectpath, &statbuf);
117         if (ret == 0) {
118                 caps = statbuf.FsCapabilities;
119         }
120
121         *p_ts_res = TIMESTAMP_SET_SECONDS;
122
123         /* Work out what timestamp resolution we can
124          * use when setting a timestamp. */
125
126         status = create_synthetic_smb_fname(talloc_tos(),
127                                 conn->connectpath,
128                                 NULL,
129                                 NULL,
130                                 &smb_fname_cpath);
131         if (!NT_STATUS_IS_OK(status)) {
132                 return caps;
133         }
134
135         ret = SMB_VFS_STAT(conn, smb_fname_cpath);
136         if (ret == -1) {
137                 TALLOC_FREE(smb_fname_cpath);
138                 return caps;
139         }
140
141         if (smb_fname_cpath->st.st_ex_mtime.tv_nsec ||
142                         smb_fname_cpath->st.st_ex_atime.tv_nsec ||
143                         smb_fname_cpath->st.st_ex_ctime.tv_nsec) {
144                 /* If any of the normal UNIX directory timestamps
145                  * have a non-zero tv_nsec component assume
146                  * we might be able to set sub-second timestamps.
147                  * See what filetime set primitives we have.
148                  */
149 #if defined(HAVE_UTIMENSAT)
150                 *p_ts_res = TIMESTAMP_SET_NT_OR_BETTER;
151 #elif defined(HAVE_UTIMES)
152                 /* utimes allows msec timestamps to be set. */
153                 *p_ts_res = TIMESTAMP_SET_MSEC;
154 #elif defined(HAVE_UTIME)
155                 /* utime only allows sec timestamps to be set. */
156                 *p_ts_res = TIMESTAMP_SET_SECONDS;
157 #endif
158
159                 DEBUG(10,("vfswrap_fs_capabilities: timestamp "
160                         "resolution of %s "
161                         "available on share %s, directory %s\n",
162                         *p_ts_res == TIMESTAMP_SET_MSEC ? "msec" : "sec",
163                         lp_servicename(conn->params->service),
164                         conn->connectpath ));
165         }
166         TALLOC_FREE(smb_fname_cpath);
167         return caps;
168 }
169
170 static NTSTATUS vfswrap_get_dfs_referrals(struct vfs_handle_struct *handle,
171                                           struct dfs_GetDFSReferral *r)
172 {
173         struct junction_map *junction = NULL;
174         int consumedcnt = 0;
175         bool self_referral = false;
176         char *pathnamep = NULL;
177         char *local_dfs_path = NULL;
178         NTSTATUS status;
179         int i;
180         uint16_t max_referral_level = r->in.req.max_referral_level;
181
182         if (DEBUGLVL(10)) {
183                 NDR_PRINT_IN_DEBUG(dfs_GetDFSReferral, r);
184         }
185
186         /* get the junction entry */
187         if (r->in.req.servername == NULL) {
188                 return NT_STATUS_NOT_FOUND;
189         }
190
191         /*
192          * Trim pathname sent by client so it begins with only one backslash.
193          * Two backslashes confuse some dfs clients
194          */
195
196         local_dfs_path = talloc_strdup(r, r->in.req.servername);
197         if (local_dfs_path == NULL) {
198                 return NT_STATUS_NO_MEMORY;
199         }
200         pathnamep = local_dfs_path;
201         while (IS_DIRECTORY_SEP(pathnamep[0]) &&
202                IS_DIRECTORY_SEP(pathnamep[1])) {
203                 pathnamep++;
204         }
205
206         junction = talloc_zero(r, struct junction_map);
207         if (junction == NULL) {
208                 return NT_STATUS_NO_MEMORY;
209         }
210
211         /* The following call can change cwd. */
212         status = get_referred_path(r, pathnamep, handle->conn->sconn,
213                                    junction, &consumedcnt, &self_referral);
214         if (!NT_STATUS_IS_OK(status)) {
215                 vfs_ChDir(handle->conn, handle->conn->connectpath);
216                 return status;
217         }
218         vfs_ChDir(handle->conn, handle->conn->connectpath);
219
220         if (!self_referral) {
221                 pathnamep[consumedcnt] = '\0';
222
223                 if (DEBUGLVL(3)) {
224                         dbgtext("setup_dfs_referral: Path %s to "
225                                 "alternate path(s):",
226                                 pathnamep);
227                         for (i=0; i < junction->referral_count; i++) {
228                                 dbgtext(" %s",
229                                 junction->referral_list[i].alternate_path);
230                         }
231                         dbgtext(".\n");
232                 }
233         }
234
235         if (r->in.req.max_referral_level <= 2) {
236                 max_referral_level = 2;
237         }
238         if (r->in.req.max_referral_level >= 3) {
239                 max_referral_level = 3;
240         }
241
242         r->out.resp = talloc_zero(r, struct dfs_referral_resp);
243         if (r->out.resp == NULL) {
244                 return NT_STATUS_NO_MEMORY;
245         }
246
247         r->out.resp->path_consumed = strlen_m(pathnamep) * 2;
248         r->out.resp->nb_referrals = junction->referral_count;
249
250         r->out.resp->header_flags = DFS_HEADER_FLAG_STORAGE_SVR;
251         if (self_referral) {
252                 r->out.resp->header_flags |= DFS_HEADER_FLAG_REFERAL_SVR;
253         }
254
255         r->out.resp->referral_entries = talloc_zero_array(r,
256                                 struct dfs_referral_type,
257                                 r->out.resp->nb_referrals);
258         if (r->out.resp->referral_entries == NULL) {
259                 return NT_STATUS_NO_MEMORY;
260         }
261
262         switch (max_referral_level) {
263         case 2:
264                 for(i=0; i < junction->referral_count; i++) {
265                         struct referral *ref = &junction->referral_list[i];
266                         TALLOC_CTX *mem_ctx = r->out.resp->referral_entries;
267                         struct dfs_referral_type *t =
268                                 &r->out.resp->referral_entries[i];
269                         struct dfs_referral_v2 *v2 = &t->referral.v2;
270
271                         t->version = 2;
272                         v2->size = VERSION2_REFERRAL_SIZE;
273                         if (self_referral) {
274                                 v2->server_type = DFS_SERVER_ROOT;
275                         } else {
276                                 v2->server_type = DFS_SERVER_NON_ROOT;
277                         }
278                         v2->entry_flags = 0;
279                         v2->proximity = ref->proximity;
280                         v2->ttl = ref->ttl;
281                         v2->DFS_path = talloc_strdup(mem_ctx, pathnamep);
282                         if (v2->DFS_path == NULL) {
283                                 return NT_STATUS_NO_MEMORY;
284                         }
285                         v2->DFS_alt_path = talloc_strdup(mem_ctx, pathnamep);
286                         if (v2->DFS_alt_path == NULL) {
287                                 return NT_STATUS_NO_MEMORY;
288                         }
289                         v2->netw_address = talloc_strdup(mem_ctx,
290                                                          ref->alternate_path);
291                         if (v2->netw_address == NULL) {
292                                 return NT_STATUS_NO_MEMORY;
293                         }
294                 }
295
296                 break;
297         case 3:
298                 for(i=0; i < junction->referral_count; i++) {
299                         struct referral *ref = &junction->referral_list[i];
300                         TALLOC_CTX *mem_ctx = r->out.resp->referral_entries;
301                         struct dfs_referral_type *t =
302                                 &r->out.resp->referral_entries[i];
303                         struct dfs_referral_v3 *v3 = &t->referral.v3;
304                         struct dfs_normal_referral *r1 = &v3->referrals.r1;
305
306                         t->version = 3;
307                         v3->size = VERSION3_REFERRAL_SIZE;
308                         if (self_referral) {
309                                 v3->server_type = DFS_SERVER_ROOT;
310                         } else {
311                                 v3->server_type = DFS_SERVER_NON_ROOT;
312                         }
313                         v3->entry_flags = 0;
314                         v3->ttl = ref->ttl;
315                         r1->DFS_path = talloc_strdup(mem_ctx, pathnamep);
316                         if (r1->DFS_path == NULL) {
317                                 return NT_STATUS_NO_MEMORY;
318                         }
319                         r1->DFS_alt_path = talloc_strdup(mem_ctx, pathnamep);
320                         if (r1->DFS_alt_path == NULL) {
321                                 return NT_STATUS_NO_MEMORY;
322                         }
323                         r1->netw_address = talloc_strdup(mem_ctx,
324                                                          ref->alternate_path);
325                         if (r1->netw_address == NULL) {
326                                 return NT_STATUS_NO_MEMORY;
327                         }
328                 }
329                 break;
330         default:
331                 DEBUG(0,("setup_dfs_referral: Invalid dfs referral "
332                         "version: %d\n",
333                         max_referral_level));
334                 return NT_STATUS_INVALID_LEVEL;
335         }
336
337         if (DEBUGLVL(10)) {
338                 NDR_PRINT_OUT_DEBUG(dfs_GetDFSReferral, r);
339         }
340
341         return NT_STATUS_OK;
342 }
343
344 /* Directory operations */
345
346 static SMB_STRUCT_DIR *vfswrap_opendir(vfs_handle_struct *handle,  const char *fname, const char *mask, uint32 attr)
347 {
348         SMB_STRUCT_DIR *result;
349
350         START_PROFILE(syscall_opendir);
351         result = sys_opendir(fname);
352         END_PROFILE(syscall_opendir);
353         return result;
354 }
355
356 static SMB_STRUCT_DIR *vfswrap_fdopendir(vfs_handle_struct *handle,
357                         files_struct *fsp,
358                         const char *mask,
359                         uint32 attr)
360 {
361         SMB_STRUCT_DIR *result;
362
363         START_PROFILE(syscall_fdopendir);
364         result = sys_fdopendir(fsp->fh->fd);
365         END_PROFILE(syscall_fdopendir);
366         return result;
367 }
368
369
370 static SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle,
371                                           SMB_STRUCT_DIR *dirp,
372                                           SMB_STRUCT_STAT *sbuf)
373 {
374         SMB_STRUCT_DIRENT *result;
375
376         START_PROFILE(syscall_readdir);
377         result = sys_readdir(dirp);
378         /* Default Posix readdir() does not give us stat info.
379          * Set to invalid to indicate we didn't return this info. */
380         if (sbuf)
381                 SET_STAT_INVALID(*sbuf);
382         END_PROFILE(syscall_readdir);
383         return result;
384 }
385
386 static void vfswrap_seekdir(vfs_handle_struct *handle,  SMB_STRUCT_DIR *dirp, long offset)
387 {
388         START_PROFILE(syscall_seekdir);
389         sys_seekdir(dirp, offset);
390         END_PROFILE(syscall_seekdir);
391 }
392
393 static long vfswrap_telldir(vfs_handle_struct *handle,  SMB_STRUCT_DIR *dirp)
394 {
395         long result;
396         START_PROFILE(syscall_telldir);
397         result = sys_telldir(dirp);
398         END_PROFILE(syscall_telldir);
399         return result;
400 }
401
402 static void vfswrap_rewinddir(vfs_handle_struct *handle,  SMB_STRUCT_DIR *dirp)
403 {
404         START_PROFILE(syscall_rewinddir);
405         sys_rewinddir(dirp);
406         END_PROFILE(syscall_rewinddir);
407 }
408
409 static int vfswrap_mkdir(vfs_handle_struct *handle,  const char *path, mode_t mode)
410 {
411         int result;
412         bool has_dacl = False;
413         char *parent = NULL;
414
415         START_PROFILE(syscall_mkdir);
416
417         if (lp_inherit_acls(SNUM(handle->conn))
418             && parent_dirname(talloc_tos(), path, &parent, NULL)
419             && (has_dacl = directory_has_default_acl(handle->conn, parent)))
420                 mode = (0777 & lp_dir_mask(SNUM(handle->conn)));
421
422         TALLOC_FREE(parent);
423
424         result = mkdir(path, mode);
425
426         if (result == 0 && !has_dacl) {
427                 /*
428                  * We need to do this as the default behavior of POSIX ACLs
429                  * is to set the mask to be the requested group permission
430                  * bits, not the group permission bits to be the requested
431                  * group permission bits. This is not what we want, as it will
432                  * mess up any inherited ACL bits that were set. JRA.
433                  */
434                 int saved_errno = errno; /* We may get ENOSYS */
435                 if ((SMB_VFS_CHMOD_ACL(handle->conn, path, mode) == -1) && (errno == ENOSYS))
436                         errno = saved_errno;
437         }
438
439         END_PROFILE(syscall_mkdir);
440         return result;
441 }
442
443 static int vfswrap_rmdir(vfs_handle_struct *handle,  const char *path)
444 {
445         int result;
446
447         START_PROFILE(syscall_rmdir);
448         result = rmdir(path);
449         END_PROFILE(syscall_rmdir);
450         return result;
451 }
452
453 static int vfswrap_closedir(vfs_handle_struct *handle,  SMB_STRUCT_DIR *dirp)
454 {
455         int result;
456
457         START_PROFILE(syscall_closedir);
458         result = sys_closedir(dirp);
459         END_PROFILE(syscall_closedir);
460         return result;
461 }
462
463 static void vfswrap_init_search_op(vfs_handle_struct *handle,
464                                    SMB_STRUCT_DIR *dirp)
465 {
466         /* Default behavior is a NOOP */
467 }
468
469 /* File operations */
470
471 static int vfswrap_open(vfs_handle_struct *handle,
472                         struct smb_filename *smb_fname,
473                         files_struct *fsp, int flags, mode_t mode)
474 {
475         int result = -1;
476
477         START_PROFILE(syscall_open);
478
479         if (smb_fname->stream_name) {
480                 errno = ENOENT;
481                 goto out;
482         }
483
484         result = sys_open(smb_fname->base_name, flags, mode);
485  out:
486         END_PROFILE(syscall_open);
487         return result;
488 }
489
490 static NTSTATUS vfswrap_create_file(vfs_handle_struct *handle,
491                                     struct smb_request *req,
492                                     uint16_t root_dir_fid,
493                                     struct smb_filename *smb_fname,
494                                     uint32_t access_mask,
495                                     uint32_t share_access,
496                                     uint32_t create_disposition,
497                                     uint32_t create_options,
498                                     uint32_t file_attributes,
499                                     uint32_t oplock_request,
500                                     uint64_t allocation_size,
501                                     uint32_t private_flags,
502                                     struct security_descriptor *sd,
503                                     struct ea_list *ea_list,
504                                     files_struct **result,
505                                     int *pinfo)
506 {
507         return create_file_default(handle->conn, req, root_dir_fid, smb_fname,
508                                    access_mask, share_access,
509                                    create_disposition, create_options,
510                                    file_attributes, oplock_request,
511                                    allocation_size, private_flags,
512                                    sd, ea_list, result,
513                                    pinfo);
514 }
515
516 static int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp)
517 {
518         int result;
519
520         START_PROFILE(syscall_close);
521         result = fd_close_posix(fsp);
522         END_PROFILE(syscall_close);
523         return result;
524 }
525
526 static ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, void *data, size_t n)
527 {
528         ssize_t result;
529
530         START_PROFILE_BYTES(syscall_read, n);
531         result = sys_read(fsp->fh->fd, data, n);
532         END_PROFILE(syscall_read);
533         return result;
534 }
535
536 static ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, void *data,
537                         size_t n, SMB_OFF_T offset)
538 {
539         ssize_t result;
540
541 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
542         START_PROFILE_BYTES(syscall_pread, n);
543         result = sys_pread(fsp->fh->fd, data, n, offset);
544         END_PROFILE(syscall_pread);
545
546         if (result == -1 && errno == ESPIPE) {
547                 /* Maintain the fiction that pipes can be seeked (sought?) on. */
548                 result = SMB_VFS_READ(fsp, data, n);
549                 fsp->fh->pos = 0;
550         }
551
552 #else /* HAVE_PREAD */
553         SMB_OFF_T   curr;
554         int lerrno;
555
556         curr = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
557         if (curr == -1 && errno == ESPIPE) {
558                 /* Maintain the fiction that pipes can be seeked (sought?) on. */
559                 result = SMB_VFS_READ(fsp, data, n);
560                 fsp->fh->pos = 0;
561                 return result;
562         }
563
564         if (SMB_VFS_LSEEK(fsp, offset, SEEK_SET) == -1) {
565                 return -1;
566         }
567
568         errno = 0;
569         result = SMB_VFS_READ(fsp, data, n);
570         lerrno = errno;
571
572         SMB_VFS_LSEEK(fsp, curr, SEEK_SET);
573         errno = lerrno;
574
575 #endif /* HAVE_PREAD */
576
577         return result;
578 }
579
580 static ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n)
581 {
582         ssize_t result;
583
584         START_PROFILE_BYTES(syscall_write, n);
585         result = sys_write(fsp->fh->fd, data, n);
586         END_PROFILE(syscall_write);
587         return result;
588 }
589
590 static ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, const void *data,
591                         size_t n, SMB_OFF_T offset)
592 {
593         ssize_t result;
594
595 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
596         START_PROFILE_BYTES(syscall_pwrite, n);
597         result = sys_pwrite(fsp->fh->fd, data, n, offset);
598         END_PROFILE(syscall_pwrite);
599
600         if (result == -1 && errno == ESPIPE) {
601                 /* Maintain the fiction that pipes can be sought on. */
602                 result = SMB_VFS_WRITE(fsp, data, n);
603         }
604
605 #else /* HAVE_PWRITE */
606         SMB_OFF_T   curr;
607         int         lerrno;
608
609         curr = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
610         if (curr == -1) {
611                 return -1;
612         }
613
614         if (SMB_VFS_LSEEK(fsp, offset, SEEK_SET) == -1) {
615                 return -1;
616         }
617
618         result = SMB_VFS_WRITE(fsp, data, n);
619         lerrno = errno;
620
621         SMB_VFS_LSEEK(fsp, curr, SEEK_SET);
622         errno = lerrno;
623
624 #endif /* HAVE_PWRITE */
625
626         return result;
627 }
628
629 static SMB_OFF_T vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T offset, int whence)
630 {
631         SMB_OFF_T result = 0;
632
633         START_PROFILE(syscall_lseek);
634
635         /* Cope with 'stat' file opens. */
636         if (fsp->fh->fd != -1)
637                 result = sys_lseek(fsp->fh->fd, offset, whence);
638
639         /*
640          * We want to maintain the fiction that we can seek
641          * on a fifo for file system purposes. This allows
642          * people to set up UNIX fifo's that feed data to Windows
643          * applications. JRA.
644          */
645
646         if((result == -1) && (errno == ESPIPE)) {
647                 result = 0;
648                 errno = 0;
649         }
650
651         END_PROFILE(syscall_lseek);
652         return result;
653 }
654
655 static ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fromfsp, const DATA_BLOB *hdr,
656                         SMB_OFF_T offset, size_t n)
657 {
658         ssize_t result;
659
660         START_PROFILE_BYTES(syscall_sendfile, n);
661         result = sys_sendfile(tofd, fromfsp->fh->fd, hdr, offset, n);
662         END_PROFILE(syscall_sendfile);
663         return result;
664 }
665
666 static ssize_t vfswrap_recvfile(vfs_handle_struct *handle,
667                         int fromfd,
668                         files_struct *tofsp,
669                         SMB_OFF_T offset,
670                         size_t n)
671 {
672         ssize_t result;
673
674         START_PROFILE_BYTES(syscall_recvfile, n);
675         result = sys_recvfile(fromfd, tofsp->fh->fd, offset, n);
676         END_PROFILE(syscall_recvfile);
677         return result;
678 }
679
680 static int vfswrap_rename(vfs_handle_struct *handle,
681                           const struct smb_filename *smb_fname_src,
682                           const struct smb_filename *smb_fname_dst)
683 {
684         int result = -1;
685
686         START_PROFILE(syscall_rename);
687
688         if (smb_fname_src->stream_name || smb_fname_dst->stream_name) {
689                 errno = ENOENT;
690                 goto out;
691         }
692
693         result = rename(smb_fname_src->base_name, smb_fname_dst->base_name);
694
695  out:
696         END_PROFILE(syscall_rename);
697         return result;
698 }
699
700 static int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp)
701 {
702 #ifdef HAVE_FSYNC
703         int result;
704
705         START_PROFILE(syscall_fsync);
706         result = fsync(fsp->fh->fd);
707         END_PROFILE(syscall_fsync);
708         return result;
709 #else
710         return 0;
711 #endif
712 }
713
714 static int vfswrap_stat(vfs_handle_struct *handle,
715                         struct smb_filename *smb_fname)
716 {
717         int result = -1;
718
719         START_PROFILE(syscall_stat);
720
721         if (smb_fname->stream_name) {
722                 errno = ENOENT;
723                 goto out;
724         }
725
726         result = sys_stat(smb_fname->base_name, &smb_fname->st,
727                           lp_fake_dir_create_times(SNUM(handle->conn)));
728  out:
729         END_PROFILE(syscall_stat);
730         return result;
731 }
732
733 static int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
734 {
735         int result;
736
737         START_PROFILE(syscall_fstat);
738         result = sys_fstat(fsp->fh->fd,
739                            sbuf, lp_fake_dir_create_times(SNUM(handle->conn)));
740         END_PROFILE(syscall_fstat);
741         return result;
742 }
743
744 static int vfswrap_lstat(vfs_handle_struct *handle,
745                          struct smb_filename *smb_fname)
746 {
747         int result = -1;
748
749         START_PROFILE(syscall_lstat);
750
751         if (smb_fname->stream_name) {
752                 errno = ENOENT;
753                 goto out;
754         }
755
756         result = sys_lstat(smb_fname->base_name, &smb_fname->st,
757                            lp_fake_dir_create_times(SNUM(handle->conn)));
758  out:
759         END_PROFILE(syscall_lstat);
760         return result;
761 }
762
763 static NTSTATUS vfswrap_translate_name(struct vfs_handle_struct *handle,
764                                        const char *name,
765                                        enum vfs_translate_direction direction,
766                                        TALLOC_CTX *mem_ctx,
767                                        char **mapped_name)
768 {
769         return NT_STATUS_NONE_MAPPED;
770 }
771
772 /*
773  * Implement the default fsctl operation.
774  */
775 static bool vfswrap_logged_ioctl_message = false;
776
777 static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
778                               struct files_struct *fsp,
779                               TALLOC_CTX *ctx,
780                               uint32_t function,
781                               uint16_t req_flags,  /* Needed for UNICODE ... */
782                               const uint8_t *_in_data,
783                               uint32_t in_len,
784                               uint8_t **_out_data,
785                               uint32_t max_out_len,
786                               uint32_t *out_len)
787 {
788         const char *in_data = (const char *)_in_data;
789         char **out_data = (char **)_out_data;
790
791         switch (function) {
792         case FSCTL_SET_SPARSE:
793         {
794                 bool set_sparse = true;
795                 NTSTATUS status;
796
797                 if (in_len >= 1 && in_data[0] == 0) {
798                         set_sparse = false;
799                 }
800
801                 status = file_set_sparse(handle->conn, fsp, set_sparse);
802                 
803                 DEBUG(NT_STATUS_IS_OK(status) ? 10 : 9,
804                       ("FSCTL_SET_SPARSE: fname[%s] set[%u] - %s\n",
805                        smb_fname_str_dbg(fsp->fsp_name), set_sparse, 
806                        nt_errstr(status)));
807
808                 return status;
809         }
810
811         case FSCTL_CREATE_OR_GET_OBJECT_ID:
812         {
813                 unsigned char objid[16];
814                 char *return_data = NULL;
815
816                 /* This should return the object-id on this file.
817                  * I think I'll make this be the inode+dev. JRA.
818                  */
819
820                 DEBUG(10,("FSCTL_CREATE_OR_GET_OBJECT_ID: called on FID[0x%04X]\n",fsp->fnum));
821
822                 *out_len = (max_out_len >= 64) ? 64 : max_out_len;
823                 /* Hmmm, will this cause problems if less data asked for? */
824                 return_data = talloc_array(ctx, char, 64);
825                 if (return_data == NULL) {
826                         return NT_STATUS_NO_MEMORY;
827                 }
828
829                 /* For backwards compatibility only store the dev/inode. */
830                 push_file_id_16(return_data, &fsp->file_id);
831                 memcpy(return_data+16,create_volume_objectid(fsp->conn,objid),16);
832                 push_file_id_16(return_data+32, &fsp->file_id);
833                 *out_data = return_data;
834                 return NT_STATUS_OK;
835         }
836
837         case FSCTL_GET_REPARSE_POINT:
838         {
839                 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
840                 DEBUG(10, ("FSCTL_GET_REPARSE_POINT: called on FID[0x%04X] Status: NOT_IMPLEMENTED\n", fsp->fnum));
841                 return NT_STATUS_NOT_A_REPARSE_POINT;
842         }
843
844         case FSCTL_SET_REPARSE_POINT:
845         {
846                 /* Fail it with STATUS_NOT_A_REPARSE_POINT */
847                 DEBUG(10, ("FSCTL_SET_REPARSE_POINT: called on FID[0x%04X] Status: NOT_IMPLEMENTED\n", fsp->fnum));
848                 return NT_STATUS_NOT_A_REPARSE_POINT;
849         }
850
851         case FSCTL_GET_SHADOW_COPY_DATA:
852         {
853                 /*
854                  * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots)
855                  * and return their volume names.  If max_data_count is 16, then it is just
856                  * asking for the number of volumes and length of the combined names.
857                  *
858                  * pdata is the data allocated by our caller, but that uses
859                  * total_data_count (which is 0 in our case) rather than max_data_count.
860                  * Allocate the correct amount and return the pointer to let
861                  * it be deallocated when we return.
862                  */
863                 struct shadow_copy_data *shadow_data = NULL;
864                 bool labels = False;
865                 uint32 labels_data_count = 0;
866                 uint32 i;
867                 char *cur_pdata = NULL;
868
869                 if (max_out_len < 16) {
870                         DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) < 16 is invalid!\n",
871                                 max_out_len));
872                         return NT_STATUS_INVALID_PARAMETER;
873                 }
874
875                 if (max_out_len > 16) {
876                         labels = True;
877                 }
878
879                 shadow_data = talloc_zero(ctx, struct shadow_copy_data);
880                 if (shadow_data == NULL) {
881                         DEBUG(0,("TALLOC_ZERO() failed!\n"));
882                         return NT_STATUS_NO_MEMORY;
883                 }
884
885                 /*
886                  * Call the VFS routine to actually do the work.
887                  */
888                 if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) {
889                         TALLOC_FREE(shadow_data);
890                         if (errno == ENOSYS) {
891                                 DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n", 
892                                         fsp->conn->connectpath));
893                                 return NT_STATUS_NOT_SUPPORTED;
894                         } else {
895                                 DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n", 
896                                         fsp->conn->connectpath));
897                                 return NT_STATUS_UNSUCCESSFUL;
898                         }
899                 }
900
901                 labels_data_count = (shadow_data->num_volumes * 2 * 
902                                         sizeof(SHADOW_COPY_LABEL)) + 2;
903
904                 if (!labels) {
905                         *out_len = 16;
906                 } else {
907                         *out_len = 12 + labels_data_count + 4;
908                 }
909
910                 if (max_out_len < *out_len) {
911                         DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n",
912                                 max_out_len, *out_len));
913                         TALLOC_FREE(shadow_data);
914                         return NT_STATUS_BUFFER_TOO_SMALL;
915                 }
916
917                 cur_pdata = talloc_array(ctx, char, *out_len);
918                 if (cur_pdata == NULL) {
919                         TALLOC_FREE(shadow_data);
920                         return NT_STATUS_NO_MEMORY;
921                 }
922
923                 *out_data = cur_pdata;
924
925                 /* num_volumes 4 bytes */
926                 SIVAL(cur_pdata, 0, shadow_data->num_volumes);
927
928                 if (labels) {
929                         /* num_labels 4 bytes */
930                         SIVAL(cur_pdata, 4, shadow_data->num_volumes);
931                 }
932
933                 /* needed_data_count 4 bytes */
934                 SIVAL(cur_pdata, 8, labels_data_count + 4);
935
936                 cur_pdata += 12;
937
938                 DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for path[%s].\n",
939                           shadow_data->num_volumes, fsp_str_dbg(fsp)));
940                 if (labels && shadow_data->labels) {
941                         for (i=0; i<shadow_data->num_volumes; i++) {
942                                 srvstr_push(cur_pdata, req_flags,
943                                             cur_pdata, shadow_data->labels[i],
944                                             2 * sizeof(SHADOW_COPY_LABEL),
945                                             STR_UNICODE|STR_TERMINATE);
946                                 cur_pdata += 2 * sizeof(SHADOW_COPY_LABEL);
947                                 DEBUGADD(10,("Label[%u]: '%s'\n",i,shadow_data->labels[i]));
948                         }
949                 }
950
951                 TALLOC_FREE(shadow_data);
952
953                 return NT_STATUS_OK;
954         }
955
956         case FSCTL_FIND_FILES_BY_SID:
957         {
958                 /* pretend this succeeded -
959                  *
960                  * we have to send back a list with all files owned by this SID
961                  *
962                  * but I have to check that --metze
963                  */
964                 struct dom_sid sid;
965                 uid_t uid;
966                 size_t sid_len;
967
968                 DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n", fsp->fnum));
969
970                 if (in_len < 8) {
971                         /* NT_STATUS_BUFFER_TOO_SMALL maybe? */
972                         return NT_STATUS_INVALID_PARAMETER;
973                 }
974
975                 sid_len = MIN(in_len - 4,SID_MAX_SIZE);
976
977                 /* unknown 4 bytes: this is not the length of the sid :-(  */
978                 /*unknown = IVAL(pdata,0);*/
979
980                 if (!sid_parse(in_data + 4, sid_len, &sid)) {
981                         return NT_STATUS_INVALID_PARAMETER;
982                 }
983                 DEBUGADD(10, ("for SID: %s\n", sid_string_dbg(&sid)));
984
985                 if (!sid_to_uid(&sid, &uid)) {
986                         DEBUG(0,("sid_to_uid: failed, sid[%s] sid_len[%lu]\n",
987                                  sid_string_dbg(&sid),
988                                  (unsigned long)sid_len));
989                         uid = (-1);
990                 }
991
992                 /* we can take a look at the find source :-)
993                  *
994                  * find ./ -uid $uid  -name '*'   is what we need here
995                  *
996                  *
997                  * and send 4bytes len and then NULL terminated unicode strings
998                  * for each file
999                  *
1000                  * but I don't know how to deal with the paged results
1001                  * (maybe we can hang the result anywhere in the fsp struct)
1002                  *
1003                  * but I don't know how to deal with the paged results
1004                  * (maybe we can hang the result anywhere in the fsp struct)
1005                  *
1006                  * we don't send all files at once
1007                  * and at the next we should *not* start from the beginning,
1008                  * so we have to cache the result
1009                  *
1010                  * --metze
1011                  */
1012
1013                 /* this works for now... */
1014                 return NT_STATUS_OK;
1015         }
1016
1017         case FSCTL_QUERY_ALLOCATED_RANGES:
1018         {
1019                 /* FIXME: This is just a dummy reply, telling that all of the
1020                  * file is allocated. MKS cp needs that.
1021                  * Adding the real allocated ranges via FIEMAP on Linux
1022                  * and SEEK_DATA/SEEK_HOLE on Solaris is needed to make
1023                  * this FSCTL correct for sparse files.
1024                  */
1025                 NTSTATUS status;
1026                 uint64_t offset, length;
1027                 char *out_data_tmp = NULL;
1028
1029                 if (in_len != 16) {
1030                         DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: data_count(%u) != 16 is invalid!\n",
1031                                 in_len));
1032                         return NT_STATUS_INVALID_PARAMETER;
1033                 }
1034
1035                 if (max_out_len < 16) {
1036                         DEBUG(0,("FSCTL_QUERY_ALLOCATED_RANGES: max_out_len (%u) < 16 is invalid!\n",
1037                                 max_out_len));
1038                         return NT_STATUS_INVALID_PARAMETER;
1039                 }
1040
1041                 offset = BVAL(in_data,0);
1042                 length = BVAL(in_data,8);
1043
1044                 if (offset + length < offset) {
1045                         /* No 64-bit integer wrap. */
1046                         return NT_STATUS_INVALID_PARAMETER;
1047                 }
1048
1049                 /* Shouldn't this be SMB_VFS_STAT ... ? */
1050                 status = vfs_stat_fsp(fsp);
1051                 if (!NT_STATUS_IS_OK(status)) {
1052                         return status;
1053                 }
1054
1055                 *out_len = 16;
1056                 out_data_tmp = talloc_array(ctx, char, *out_len);
1057                 if (out_data_tmp == NULL) {
1058                         DEBUG(10, ("unable to allocate memory for response\n"));
1059                         return NT_STATUS_NO_MEMORY;
1060                 }
1061
1062                 if (offset > fsp->fsp_name->st.st_ex_size ||
1063                                 fsp->fsp_name->st.st_ex_size == 0 ||
1064                                 length == 0) {
1065                         memset(out_data_tmp, 0, *out_len);
1066                 } else {
1067                         uint64_t end = offset + length;
1068                         end = MIN(end, fsp->fsp_name->st.st_ex_size);
1069                         SBVAL(out_data_tmp, 0, 0);
1070                         SBVAL(out_data_tmp, 8, end);
1071                 }
1072
1073                 *out_data = out_data_tmp;
1074
1075                 return NT_STATUS_OK;
1076         }
1077
1078         case FSCTL_IS_VOLUME_DIRTY:
1079         {
1080                 DEBUG(10,("FSCTL_IS_VOLUME_DIRTY: called on FID[0x%04X] "
1081                           "(but not implemented)\n", fsp->fnum));
1082                 /*
1083                  * http://msdn.microsoft.com/en-us/library/cc232128%28PROT.10%29.aspx
1084                  * says we have to respond with NT_STATUS_INVALID_PARAMETER
1085                  */
1086                 return NT_STATUS_INVALID_PARAMETER;
1087         }
1088
1089         default:
1090                 /* 
1091                  * Only print once ... unfortunately there could be lots of
1092                  * different FSCTLs that are called.
1093                  */
1094                 if (!vfswrap_logged_ioctl_message) {
1095                         vfswrap_logged_ioctl_message = true;
1096                         DEBUG(2, ("%s (0x%x): Currently not implemented.\n",
1097                         __func__, function));
1098                 }
1099         }
1100
1101         return NT_STATUS_NOT_SUPPORTED;
1102 }
1103
1104 /********************************************************************
1105  Given a stat buffer return the allocated size on disk, taking into
1106  account sparse files.
1107 ********************************************************************/
1108 static uint64_t vfswrap_get_alloc_size(vfs_handle_struct *handle,
1109                                        struct files_struct *fsp,
1110                                        const SMB_STRUCT_STAT *sbuf)
1111 {
1112         uint64_t result;
1113
1114         START_PROFILE(syscall_get_alloc_size);
1115
1116         if(S_ISDIR(sbuf->st_ex_mode)) {
1117                 result = 0;
1118                 goto out;
1119         }
1120
1121 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
1122         result = (uint64_t)STAT_ST_BLOCKSIZE * (uint64_t)sbuf->st_ex_blocks;
1123 #else
1124         result = get_file_size_stat(sbuf);
1125 #endif
1126
1127         if (fsp && fsp->initial_allocation_size)
1128                 result = MAX(result,fsp->initial_allocation_size);
1129
1130         result = smb_roundup(handle->conn, result);
1131
1132  out:
1133         END_PROFILE(syscall_get_alloc_size);
1134         return result;
1135 }
1136
1137 static int vfswrap_unlink(vfs_handle_struct *handle,
1138                           const struct smb_filename *smb_fname)
1139 {
1140         int result = -1;
1141
1142         START_PROFILE(syscall_unlink);
1143
1144         if (smb_fname->stream_name) {
1145                 errno = ENOENT;
1146                 goto out;
1147         }
1148         result = unlink(smb_fname->base_name);
1149
1150  out:
1151         END_PROFILE(syscall_unlink);
1152         return result;
1153 }
1154
1155 static int vfswrap_chmod(vfs_handle_struct *handle,  const char *path, mode_t mode)
1156 {
1157         int result;
1158
1159         START_PROFILE(syscall_chmod);
1160
1161         /*
1162          * We need to do this due to the fact that the default POSIX ACL
1163          * chmod modifies the ACL *mask* for the group owner, not the
1164          * group owner bits directly. JRA.
1165          */
1166
1167
1168         {
1169                 int saved_errno = errno; /* We might get ENOSYS */
1170                 if ((result = SMB_VFS_CHMOD_ACL(handle->conn, path, mode)) == 0) {
1171                         END_PROFILE(syscall_chmod);
1172                         return result;
1173                 }
1174                 /* Error - return the old errno. */
1175                 errno = saved_errno;
1176         }
1177
1178         result = chmod(path, mode);
1179         END_PROFILE(syscall_chmod);
1180         return result;
1181 }
1182
1183 static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
1184 {
1185         int result;
1186
1187         START_PROFILE(syscall_fchmod);
1188
1189         /*
1190          * We need to do this due to the fact that the default POSIX ACL
1191          * chmod modifies the ACL *mask* for the group owner, not the
1192          * group owner bits directly. JRA.
1193          */
1194
1195         {
1196                 int saved_errno = errno; /* We might get ENOSYS */
1197                 if ((result = SMB_VFS_FCHMOD_ACL(fsp, mode)) == 0) {
1198                         END_PROFILE(syscall_fchmod);
1199                         return result;
1200                 }
1201                 /* Error - return the old errno. */
1202                 errno = saved_errno;
1203         }
1204
1205 #if defined(HAVE_FCHMOD)
1206         result = fchmod(fsp->fh->fd, mode);
1207 #else
1208         result = -1;
1209         errno = ENOSYS;
1210 #endif
1211
1212         END_PROFILE(syscall_fchmod);
1213         return result;
1214 }
1215
1216 static int vfswrap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
1217 {
1218         int result;
1219
1220         START_PROFILE(syscall_chown);
1221         result = chown(path, uid, gid);
1222         END_PROFILE(syscall_chown);
1223         return result;
1224 }
1225
1226 static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t uid, gid_t gid)
1227 {
1228 #ifdef HAVE_FCHOWN
1229         int result;
1230
1231         START_PROFILE(syscall_fchown);
1232         result = fchown(fsp->fh->fd, uid, gid);
1233         END_PROFILE(syscall_fchown);
1234         return result;
1235 #else
1236         errno = ENOSYS;
1237         return -1;
1238 #endif
1239 }
1240
1241 static int vfswrap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
1242 {
1243         int result;
1244
1245         START_PROFILE(syscall_lchown);
1246         result = lchown(path, uid, gid);
1247         END_PROFILE(syscall_lchown);
1248         return result;
1249 }
1250
1251 static int vfswrap_chdir(vfs_handle_struct *handle,  const char *path)
1252 {
1253         int result;
1254
1255         START_PROFILE(syscall_chdir);
1256         result = chdir(path);
1257         END_PROFILE(syscall_chdir);
1258         return result;
1259 }
1260
1261 static char *vfswrap_getwd(vfs_handle_struct *handle)
1262 {
1263         char *result;
1264
1265         START_PROFILE(syscall_getwd);
1266         result = sys_getwd();
1267         END_PROFILE(syscall_getwd);
1268         return result;
1269 }
1270
1271 /*********************************************************************
1272  nsec timestamp resolution call. Convert down to whatever the underlying
1273  system will support.
1274 **********************************************************************/
1275
1276 static int vfswrap_ntimes(vfs_handle_struct *handle,
1277                           const struct smb_filename *smb_fname,
1278                           struct smb_file_time *ft)
1279 {
1280         int result = -1;
1281
1282         START_PROFILE(syscall_ntimes);
1283
1284         if (smb_fname->stream_name) {
1285                 errno = ENOENT;
1286                 goto out;
1287         }
1288
1289         if (ft != NULL) {
1290                 if (null_timespec(ft->atime)) {
1291                         ft->atime= smb_fname->st.st_ex_atime;
1292                 }
1293
1294                 if (null_timespec(ft->mtime)) {
1295                         ft->mtime = smb_fname->st.st_ex_mtime;
1296                 }
1297
1298                 if (!null_timespec(ft->create_time)) {
1299                         set_create_timespec_ea(handle->conn,
1300                                                smb_fname,
1301                                                ft->create_time);
1302                 }
1303
1304                 if ((timespec_compare(&ft->atime,
1305                                       &smb_fname->st.st_ex_atime) == 0) &&
1306                     (timespec_compare(&ft->mtime,
1307                                       &smb_fname->st.st_ex_mtime) == 0)) {
1308                         return 0;
1309                 }
1310         }
1311
1312 #if defined(HAVE_UTIMENSAT)
1313         if (ft != NULL) {
1314                 struct timespec ts[2];
1315                 ts[0] = ft->atime;
1316                 ts[1] = ft->mtime;
1317                 result = utimensat(AT_FDCWD, smb_fname->base_name, ts, 0);
1318         } else {
1319                 result = utimensat(AT_FDCWD, smb_fname->base_name, NULL, 0);
1320         }
1321         if (!((result == -1) && (errno == ENOSYS))) {
1322                 goto out;
1323         }
1324 #endif
1325 #if defined(HAVE_UTIMES)
1326         if (ft != NULL) {
1327                 struct timeval tv[2];
1328                 tv[0] = convert_timespec_to_timeval(ft->atime);
1329                 tv[1] = convert_timespec_to_timeval(ft->mtime);
1330                 result = utimes(smb_fname->base_name, tv);
1331         } else {
1332                 result = utimes(smb_fname->base_name, NULL);
1333         }
1334         if (!((result == -1) && (errno == ENOSYS))) {
1335                 goto out;
1336         }
1337 #endif
1338 #if defined(HAVE_UTIME)
1339         if (ft != NULL) {
1340                 struct utimbuf times;
1341                 times.actime = convert_timespec_to_time_t(ft->atime);
1342                 times.modtime = convert_timespec_to_time_t(ft->mtime);
1343                 result = utime(smb_fname->base_name, &times);
1344         } else {
1345                 result = utime(smb_fname->base_name, NULL);
1346         }
1347         if (!((result == -1) && (errno == ENOSYS))) {
1348                 goto out;
1349         }
1350 #endif
1351         errno = ENOSYS;
1352         result = -1;
1353
1354  out:
1355         END_PROFILE(syscall_ntimes);
1356         return result;
1357 }
1358
1359 /*********************************************************************
1360  A version of ftruncate that will write the space on disk if strict
1361  allocate is set.
1362 **********************************************************************/
1363
1364 static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T len)
1365 {
1366         SMB_OFF_T space_to_write;
1367         uint64_t space_avail;
1368         uint64_t bsize,dfree,dsize;
1369         int ret;
1370         NTSTATUS status;
1371         SMB_STRUCT_STAT *pst;
1372
1373         status = vfs_stat_fsp(fsp);
1374         if (!NT_STATUS_IS_OK(status)) {
1375                 return -1;
1376         }
1377         pst = &fsp->fsp_name->st;
1378
1379 #ifdef S_ISFIFO
1380         if (S_ISFIFO(pst->st_ex_mode))
1381                 return 0;
1382 #endif
1383
1384         if (pst->st_ex_size == len)
1385                 return 0;
1386
1387         /* Shrink - just ftruncate. */
1388         if (pst->st_ex_size > len)
1389                 return sys_ftruncate(fsp->fh->fd, len);
1390
1391         space_to_write = len - pst->st_ex_size;
1392
1393         /* for allocation try fallocate first. This can fail on some
1394            platforms e.g. when the filesystem doesn't support it and no
1395            emulation is being done by the libc (like on AIX with JFS1). In that
1396            case we do our own emulation. fallocate implementations can
1397            return ENOTSUP or EINVAL in cases like that. */
1398         ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
1399                                 pst->st_ex_size, space_to_write);
1400         if (ret == ENOSPC) {
1401                 errno = ENOSPC;
1402                 return -1;
1403         }
1404         if (ret == 0) {
1405                 return 0;
1406         }
1407         DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_FALLOCATE failed with "
1408                 "error %d. Falling back to slow manual allocation\n", ret));
1409
1410         /* available disk space is enough or not? */
1411         space_avail = get_dfree_info(fsp->conn,
1412                                      fsp->fsp_name->base_name, false,
1413                                      &bsize,&dfree,&dsize);
1414         /* space_avail is 1k blocks */
1415         if (space_avail == (uint64_t)-1 ||
1416                         ((uint64_t)space_to_write/1024 > space_avail) ) {
1417                 errno = ENOSPC;
1418                 return -1;
1419         }
1420
1421         /* Write out the real space on disk. */
1422         ret = vfs_slow_fallocate(fsp, pst->st_ex_size, space_to_write);
1423         if (ret != 0) {
1424                 errno = ret;
1425                 ret = -1;
1426         }
1427
1428         return 0;
1429 }
1430
1431 static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T len)
1432 {
1433         int result = -1;
1434         SMB_STRUCT_STAT *pst;
1435         NTSTATUS status;
1436         char c = 0;
1437
1438         START_PROFILE(syscall_ftruncate);
1439
1440         if (lp_strict_allocate(SNUM(fsp->conn)) && !fsp->is_sparse) {
1441                 result = strict_allocate_ftruncate(handle, fsp, len);
1442                 END_PROFILE(syscall_ftruncate);
1443                 return result;
1444         }
1445
1446         /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
1447            sys_ftruncate if the system supports it. Then I discovered that
1448            you can have some filesystems that support ftruncate
1449            expansion and some that don't! On Linux fat can't do
1450            ftruncate extend but ext2 can. */
1451
1452         result = sys_ftruncate(fsp->fh->fd, len);
1453         if (result == 0)
1454                 goto done;
1455
1456         /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
1457            extend a file with ftruncate. Provide alternate implementation
1458            for this */
1459
1460         /* Do an fstat to see if the file is longer than the requested
1461            size in which case the ftruncate above should have
1462            succeeded or shorter, in which case seek to len - 1 and
1463            write 1 byte of zero */
1464         status = vfs_stat_fsp(fsp);
1465         if (!NT_STATUS_IS_OK(status)) {
1466                 goto done;
1467         }
1468         pst = &fsp->fsp_name->st;
1469
1470 #ifdef S_ISFIFO
1471         if (S_ISFIFO(pst->st_ex_mode)) {
1472                 result = 0;
1473                 goto done;
1474         }
1475 #endif
1476
1477         if (pst->st_ex_size == len) {
1478                 result = 0;
1479                 goto done;
1480         }
1481
1482         if (pst->st_ex_size > len) {
1483                 /* the sys_ftruncate should have worked */
1484                 goto done;
1485         }
1486
1487         if (SMB_VFS_PWRITE(fsp, &c, 1, len-1)!=1) {
1488                 goto done;
1489         }
1490
1491         result = 0;
1492
1493   done:
1494
1495         END_PROFILE(syscall_ftruncate);
1496         return result;
1497 }
1498
1499 static int vfswrap_fallocate(vfs_handle_struct *handle,
1500                         files_struct *fsp,
1501                         enum vfs_fallocate_mode mode,
1502                         SMB_OFF_T offset,
1503                         SMB_OFF_T len)
1504 {
1505         int result;
1506
1507         START_PROFILE(syscall_fallocate);
1508         if (mode == VFS_FALLOCATE_EXTEND_SIZE) {
1509                 result = sys_posix_fallocate(fsp->fh->fd, offset, len);
1510         } else if (mode == VFS_FALLOCATE_KEEP_SIZE) {
1511                 result = sys_fallocate(fsp->fh->fd, mode, offset, len);
1512         } else {
1513                 errno = EINVAL;
1514                 result = -1;
1515         }
1516         END_PROFILE(syscall_fallocate);
1517         return result;
1518 }
1519
1520 static bool vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
1521 {
1522         bool result;
1523
1524         START_PROFILE(syscall_fcntl_lock);
1525         result =  fcntl_lock(fsp->fh->fd, op, offset, count, type);
1526         END_PROFILE(syscall_fcntl_lock);
1527         return result;
1528 }
1529
1530 static int vfswrap_kernel_flock(vfs_handle_struct *handle, files_struct *fsp,
1531                                 uint32 share_mode, uint32 access_mask)
1532 {
1533         START_PROFILE(syscall_kernel_flock);
1534         kernel_flock(fsp->fh->fd, share_mode, access_mask);
1535         END_PROFILE(syscall_kernel_flock);
1536         return 0;
1537 }
1538
1539 static bool vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1540 {
1541         bool result;
1542
1543         START_PROFILE(syscall_fcntl_getlock);
1544         result =  fcntl_getlock(fsp->fh->fd, poffset, pcount, ptype, ppid);
1545         END_PROFILE(syscall_fcntl_getlock);
1546         return result;
1547 }
1548
1549 static int vfswrap_linux_setlease(vfs_handle_struct *handle, files_struct *fsp,
1550                                 int leasetype)
1551 {
1552         int result = -1;
1553
1554         START_PROFILE(syscall_linux_setlease);
1555
1556 #ifdef HAVE_KERNEL_OPLOCKS_LINUX
1557         /* first set the signal handler */
1558         if(linux_set_lease_sighandler(fsp->fh->fd) == -1) {
1559                 return -1;
1560         }
1561
1562         result = linux_setlease(fsp->fh->fd, leasetype);
1563 #else
1564         errno = ENOSYS;
1565 #endif
1566         END_PROFILE(syscall_linux_setlease);
1567         return result;
1568 }
1569
1570 static int vfswrap_symlink(vfs_handle_struct *handle,  const char *oldpath, const char *newpath)
1571 {
1572         int result;
1573
1574         START_PROFILE(syscall_symlink);
1575         result = symlink(oldpath, newpath);
1576         END_PROFILE(syscall_symlink);
1577         return result;
1578 }
1579
1580 static int vfswrap_readlink(vfs_handle_struct *handle,  const char *path, char *buf, size_t bufsiz)
1581 {
1582         int result;
1583
1584         START_PROFILE(syscall_readlink);
1585         result = readlink(path, buf, bufsiz);
1586         END_PROFILE(syscall_readlink);
1587         return result;
1588 }
1589
1590 static int vfswrap_link(vfs_handle_struct *handle,  const char *oldpath, const char *newpath)
1591 {
1592         int result;
1593
1594         START_PROFILE(syscall_link);
1595         result = link(oldpath, newpath);
1596         END_PROFILE(syscall_link);
1597         return result;
1598 }
1599
1600 static int vfswrap_mknod(vfs_handle_struct *handle,  const char *pathname, mode_t mode, SMB_DEV_T dev)
1601 {
1602         int result;
1603
1604         START_PROFILE(syscall_mknod);
1605         result = sys_mknod(pathname, mode, dev);
1606         END_PROFILE(syscall_mknod);
1607         return result;
1608 }
1609
1610 static char *vfswrap_realpath(vfs_handle_struct *handle,  const char *path)
1611 {
1612         char *result;
1613
1614         START_PROFILE(syscall_realpath);
1615 #ifdef REALPATH_TAKES_NULL
1616         result = realpath(path, NULL);
1617 #else
1618         result = SMB_MALLOC_ARRAY(char, PATH_MAX+1);
1619         if (result) {
1620                 char *resolved_path = realpath(path, result);
1621                 if (!resolved_path) {
1622                         SAFE_FREE(result);
1623                 } else {
1624                         /* SMB_ASSERT(result == resolved_path) ? */
1625                         result = resolved_path;
1626                 }
1627         }
1628 #endif
1629         END_PROFILE(syscall_realpath);
1630         return result;
1631 }
1632
1633 static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle,
1634                                      struct sys_notify_context *ctx,
1635                                      struct notify_entry *e,
1636                                      const char *path,
1637                                      void (*callback)(struct sys_notify_context *ctx, 
1638                                                       void *private_data,
1639                                                       struct notify_event *ev),
1640                                      void *private_data, void *handle)
1641 {
1642         /*
1643          * So far inotify is the only supported default notify mechanism. If
1644          * another platform like the the BSD's or a proprietary Unix comes
1645          * along and wants another default, we can play the same trick we
1646          * played with Posix ACLs.
1647          *
1648          * Until that is the case, hard-code inotify here.
1649          */
1650 #ifdef HAVE_INOTIFY
1651         if (lp_kernel_change_notify(vfs_handle->conn->params)) {
1652                 return inotify_watch(ctx, e, path, callback, private_data,
1653                                      handle);
1654         }
1655 #endif
1656         /*
1657          * Do nothing, leave everything to notify_internal.c
1658          */
1659         return NT_STATUS_OK;
1660 }
1661
1662 static int vfswrap_chflags(vfs_handle_struct *handle, const char *path,
1663                            unsigned int flags)
1664 {
1665 #ifdef HAVE_CHFLAGS
1666         return chflags(path, flags);
1667 #else
1668         errno = ENOSYS;
1669         return -1;
1670 #endif
1671 }
1672
1673 static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle,
1674                                              const SMB_STRUCT_STAT *sbuf)
1675 {
1676         struct file_id key;
1677
1678         /* the ZERO_STRUCT ensures padding doesn't break using the key as a
1679          * blob */
1680         ZERO_STRUCT(key);
1681
1682         key.devid = sbuf->st_ex_dev;
1683         key.inode = sbuf->st_ex_ino;
1684         /* key.extid is unused by default. */
1685
1686         return key;
1687 }
1688
1689 static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
1690                                    struct files_struct *fsp,
1691                                    const char *fname,
1692                                    TALLOC_CTX *mem_ctx,
1693                                    unsigned int *pnum_streams,
1694                                    struct stream_struct **pstreams)
1695 {
1696         SMB_STRUCT_STAT sbuf;
1697         struct stream_struct *tmp_streams = NULL;
1698         int ret;
1699
1700         if ((fsp != NULL) && (fsp->is_directory)) {
1701                 /*
1702                  * No default streams on directories
1703                  */
1704                 goto done;
1705         }
1706
1707         if ((fsp != NULL) && (fsp->fh->fd != -1)) {
1708                 ret = SMB_VFS_FSTAT(fsp, &sbuf);
1709         }
1710         else {
1711                 struct smb_filename smb_fname;
1712
1713                 ZERO_STRUCT(smb_fname);
1714                 smb_fname.base_name = discard_const_p(char, fname);
1715
1716                 if (lp_posix_pathnames()) {
1717                         ret = SMB_VFS_LSTAT(handle->conn, &smb_fname);
1718                 } else {
1719                         ret = SMB_VFS_STAT(handle->conn, &smb_fname);
1720                 }
1721                 sbuf = smb_fname.st;
1722         }
1723
1724         if (ret == -1) {
1725                 return map_nt_error_from_unix(errno);
1726         }
1727
1728         if (S_ISDIR(sbuf.st_ex_mode)) {
1729                 goto done;
1730         }
1731
1732         tmp_streams = talloc_realloc(mem_ctx, *pstreams, struct stream_struct,
1733                                         (*pnum_streams) + 1);
1734         if (tmp_streams == NULL) {
1735                 return NT_STATUS_NO_MEMORY;
1736         }
1737         tmp_streams[*pnum_streams].name = talloc_strdup(tmp_streams, "::$DATA");
1738         if (tmp_streams[*pnum_streams].name == NULL) {
1739                 return NT_STATUS_NO_MEMORY;
1740         }
1741         tmp_streams[*pnum_streams].size = sbuf.st_ex_size;
1742         tmp_streams[*pnum_streams].alloc_size = SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp, &sbuf);
1743
1744         *pnum_streams += 1;
1745         *pstreams = tmp_streams;
1746  done:
1747         return NT_STATUS_OK;
1748 }
1749
1750 static int vfswrap_get_real_filename(struct vfs_handle_struct *handle,
1751                                      const char *path,
1752                                      const char *name,
1753                                      TALLOC_CTX *mem_ctx,
1754                                      char **found_name)
1755 {
1756         /*
1757          * Don't fall back to get_real_filename so callers can differentiate
1758          * between a full directory scan and an actual case-insensitive stat.
1759          */
1760         errno = EOPNOTSUPP;
1761         return -1;
1762 }
1763
1764 static const char *vfswrap_connectpath(struct vfs_handle_struct *handle,
1765                                        const char *fname)
1766 {
1767         return handle->conn->connectpath;
1768 }
1769
1770 static NTSTATUS vfswrap_brl_lock_windows(struct vfs_handle_struct *handle,
1771                                          struct byte_range_lock *br_lck,
1772                                          struct lock_struct *plock,
1773                                          bool blocking_lock,
1774                                          struct blocking_lock_record *blr)
1775 {
1776         SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1777
1778         /* Note: blr is not used in the default implementation. */
1779         return brl_lock_windows_default(br_lck, plock, blocking_lock);
1780 }
1781
1782 static bool vfswrap_brl_unlock_windows(struct vfs_handle_struct *handle,
1783                                        struct messaging_context *msg_ctx,
1784                                        struct byte_range_lock *br_lck,
1785                                        const struct lock_struct *plock)
1786 {
1787         SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1788
1789         return brl_unlock_windows_default(msg_ctx, br_lck, plock);
1790 }
1791
1792 static bool vfswrap_brl_cancel_windows(struct vfs_handle_struct *handle,
1793                                        struct byte_range_lock *br_lck,
1794                                        struct lock_struct *plock,
1795                                        struct blocking_lock_record *blr)
1796 {
1797         SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1798
1799         /* Note: blr is not used in the default implementation. */
1800         return brl_lock_cancel_default(br_lck, plock);
1801 }
1802
1803 static bool vfswrap_strict_lock(struct vfs_handle_struct *handle,
1804                                 files_struct *fsp,
1805                                 struct lock_struct *plock)
1806 {
1807         SMB_ASSERT(plock->lock_type == READ_LOCK ||
1808             plock->lock_type == WRITE_LOCK);
1809
1810         return strict_lock_default(fsp, plock);
1811 }
1812
1813 static void vfswrap_strict_unlock(struct vfs_handle_struct *handle,
1814                                 files_struct *fsp,
1815                                 struct lock_struct *plock)
1816 {
1817         SMB_ASSERT(plock->lock_type == READ_LOCK ||
1818             plock->lock_type == WRITE_LOCK);
1819
1820         strict_unlock_default(fsp, plock);
1821 }
1822
1823 /* NT ACL operations. */
1824
1825 static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle,
1826                                     files_struct *fsp,
1827                                     uint32 security_info,
1828                                     struct security_descriptor **ppdesc)
1829 {
1830         NTSTATUS result;
1831
1832         START_PROFILE(fget_nt_acl);
1833         result = posix_fget_nt_acl(fsp, security_info, ppdesc);
1834         END_PROFILE(fget_nt_acl);
1835         return result;
1836 }
1837
1838 static NTSTATUS vfswrap_get_nt_acl(vfs_handle_struct *handle,
1839                                    const char *name,
1840                                    uint32 security_info,
1841                                    struct security_descriptor **ppdesc)
1842 {
1843         NTSTATUS result;
1844
1845         START_PROFILE(get_nt_acl);
1846         result = posix_get_nt_acl(handle->conn, name, security_info, ppdesc);
1847         END_PROFILE(get_nt_acl);
1848         return result;
1849 }
1850
1851 static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, const struct security_descriptor *psd)
1852 {
1853         NTSTATUS result;
1854
1855         START_PROFILE(fset_nt_acl);
1856         result = set_nt_acl(fsp, security_info_sent, psd);
1857         END_PROFILE(fset_nt_acl);
1858         return result;
1859 }
1860
1861 static int vfswrap_chmod_acl(vfs_handle_struct *handle,  const char *name, mode_t mode)
1862 {
1863 #ifdef HAVE_NO_ACL
1864         errno = ENOSYS;
1865         return -1;
1866 #else
1867         int result;
1868
1869         START_PROFILE(chmod_acl);
1870         result = chmod_acl(handle->conn, name, mode);
1871         END_PROFILE(chmod_acl);
1872         return result;
1873 #endif
1874 }
1875
1876 static int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
1877 {
1878 #ifdef HAVE_NO_ACL
1879         errno = ENOSYS;
1880         return -1;
1881 #else
1882         int result;
1883
1884         START_PROFILE(fchmod_acl);
1885         result = fchmod_acl(fsp, mode);
1886         END_PROFILE(fchmod_acl);
1887         return result;
1888 #endif
1889 }
1890
1891 static int vfswrap_sys_acl_get_entry(vfs_handle_struct *handle,  SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1892 {
1893         return sys_acl_get_entry(theacl, entry_id, entry_p);
1894 }
1895
1896 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)
1897 {
1898         return sys_acl_get_tag_type(entry_d, tag_type_p);
1899 }
1900
1901 static int vfswrap_sys_acl_get_permset(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1902 {
1903         return sys_acl_get_permset(entry_d, permset_p);
1904 }
1905
1906 static void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry_d)
1907 {
1908         return sys_acl_get_qualifier(entry_d);
1909 }
1910
1911 static SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle,  const char *path_p, SMB_ACL_TYPE_T type)
1912 {
1913         return sys_acl_get_file(handle, path_p, type);
1914 }
1915
1916 static SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp)
1917 {
1918         return sys_acl_get_fd(handle, fsp);
1919 }
1920
1921 static int vfswrap_sys_acl_clear_perms(vfs_handle_struct *handle,  SMB_ACL_PERMSET_T permset)
1922 {
1923         return sys_acl_clear_perms(permset);
1924 }
1925
1926 static int vfswrap_sys_acl_add_perm(vfs_handle_struct *handle,  SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1927 {
1928         return sys_acl_add_perm(permset, perm);
1929 }
1930
1931 static char * vfswrap_sys_acl_to_text(vfs_handle_struct *handle,  SMB_ACL_T theacl, ssize_t *plen)
1932 {
1933         return sys_acl_to_text(theacl, plen);
1934 }
1935
1936 static SMB_ACL_T vfswrap_sys_acl_init(vfs_handle_struct *handle,  int count)
1937 {
1938         return sys_acl_init(count);
1939 }
1940
1941 static int vfswrap_sys_acl_create_entry(vfs_handle_struct *handle,  SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
1942 {
1943         return sys_acl_create_entry(pacl, pentry);
1944 }
1945
1946 static int vfswrap_sys_acl_set_tag_type(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
1947 {
1948         return sys_acl_set_tag_type(entry, tagtype);
1949 }
1950
1951 static int vfswrap_sys_acl_set_qualifier(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry, void *qual)
1952 {
1953         return sys_acl_set_qualifier(entry, qual);
1954 }
1955
1956 static int vfswrap_sys_acl_set_permset(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
1957 {
1958         return sys_acl_set_permset(entry, permset);
1959 }
1960
1961 static int vfswrap_sys_acl_valid(vfs_handle_struct *handle,  SMB_ACL_T theacl )
1962 {
1963         return sys_acl_valid(theacl );
1964 }
1965
1966 static int vfswrap_sys_acl_set_file(vfs_handle_struct *handle,  const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
1967 {
1968         return sys_acl_set_file(handle, name, acltype, theacl);
1969 }
1970
1971 static int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_T theacl)
1972 {
1973         return sys_acl_set_fd(handle, fsp, theacl);
1974 }
1975
1976 static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle,  const char *path)
1977 {
1978         return sys_acl_delete_def_file(handle, path);
1979 }
1980
1981 static int vfswrap_sys_acl_get_perm(vfs_handle_struct *handle,  SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1982 {
1983         return sys_acl_get_perm(permset, perm);
1984 }
1985
1986 static int vfswrap_sys_acl_free_text(vfs_handle_struct *handle,  char *text)
1987 {
1988         return sys_acl_free_text(text);
1989 }
1990
1991 static int vfswrap_sys_acl_free_acl(vfs_handle_struct *handle,  SMB_ACL_T posix_acl)
1992 {
1993         return sys_acl_free_acl(posix_acl);
1994 }
1995
1996 static int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle,  void *qualifier, SMB_ACL_TAG_T tagtype)
1997 {
1998         return sys_acl_free_qualifier(qualifier, tagtype);
1999 }
2000
2001 /****************************************************************
2002  Extended attribute operations.
2003 *****************************************************************/
2004
2005 static ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
2006 {
2007         return sys_getxattr(path, name, value, size);
2008 }
2009
2010 static ssize_t vfswrap_lgetxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
2011 {
2012         return sys_lgetxattr(path, name, value, size);
2013 }
2014
2015 static ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, void *value, size_t size)
2016 {
2017         return sys_fgetxattr(fsp->fh->fd, name, value, size);
2018 }
2019
2020 static ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
2021 {
2022         return sys_listxattr(path, list, size);
2023 }
2024
2025 static ssize_t vfswrap_llistxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
2026 {
2027         return sys_llistxattr(path, list, size);
2028 }
2029
2030 static ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size)
2031 {
2032         return sys_flistxattr(fsp->fh->fd, list, size);
2033 }
2034
2035 static int vfswrap_removexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
2036 {
2037         return sys_removexattr(path, name);
2038 }
2039
2040 static int vfswrap_lremovexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
2041 {
2042         return sys_lremovexattr(path, name);
2043 }
2044
2045 static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name)
2046 {
2047         return sys_fremovexattr(fsp->fh->fd, name);
2048 }
2049
2050 static int vfswrap_setxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
2051 {
2052         return sys_setxattr(path, name, value, size, flags);
2053 }
2054
2055 static int vfswrap_lsetxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
2056 {
2057         return sys_lsetxattr(path, name, value, size, flags);
2058 }
2059
2060 static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, const void *value, size_t size, int flags)
2061 {
2062         return sys_fsetxattr(fsp->fh->fd, name, value, size, flags);
2063 }
2064
2065 static int vfswrap_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2066 {
2067         int ret;
2068         /*
2069          * aio_read must be done as root, because in the glibc aio
2070          * implementation the helper thread needs to be able to send a signal
2071          * to the main thread, even when it has done a seteuid() to a
2072          * different user.
2073          */
2074         become_root();
2075         ret = sys_aio_read(aiocb);
2076         unbecome_root();
2077         return ret;
2078 }
2079
2080 static int vfswrap_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2081 {
2082         int ret;
2083         /*
2084          * aio_write must be done as root, because in the glibc aio
2085          * implementation the helper thread needs to be able to send a signal
2086          * to the main thread, even when it has done a seteuid() to a
2087          * different user.
2088          */
2089         become_root();
2090         ret = sys_aio_write(aiocb);
2091         unbecome_root();
2092         return ret;
2093 }
2094
2095 static ssize_t vfswrap_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2096 {
2097         return sys_aio_return(aiocb);
2098 }
2099
2100 static int vfswrap_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2101 {
2102         return sys_aio_cancel(fsp->fh->fd, aiocb);
2103 }
2104
2105 static int vfswrap_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2106 {
2107         return sys_aio_error(aiocb);
2108 }
2109
2110 static int vfswrap_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb)
2111 {
2112         return sys_aio_fsync(op, aiocb);
2113 }
2114
2115 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)
2116 {
2117         return sys_aio_suspend(aiocb, n, timeout);
2118 }
2119
2120 static bool vfswrap_aio_force(struct vfs_handle_struct *handle, struct files_struct *fsp)
2121 {
2122         return false;
2123 }
2124
2125 static bool vfswrap_is_offline(struct vfs_handle_struct *handle,
2126                                const struct smb_filename *fname,
2127                                SMB_STRUCT_STAT *sbuf)
2128 {
2129         NTSTATUS status;
2130         char *path;
2131         bool offline = false;
2132
2133         if (ISDOT(fname->base_name) || ISDOTDOT(fname->base_name)) {
2134                 return false;
2135         }
2136
2137         if (!lp_dmapi_support(SNUM(handle->conn)) || !dmapi_have_session()) {
2138 #if defined(ENOTSUP)
2139                 errno = ENOTSUP;
2140 #endif
2141                 return false;
2142         }
2143
2144         status = get_full_smb_filename(talloc_tos(), fname, &path);
2145         if (!NT_STATUS_IS_OK(status)) {
2146                 errno = map_errno_from_nt_status(status);
2147                 return false;
2148         }
2149
2150         offline = (dmapi_file_flags(path) & FILE_ATTRIBUTE_OFFLINE) != 0;
2151
2152         TALLOC_FREE(path);
2153
2154         return offline;
2155 }
2156
2157 static int vfswrap_set_offline(struct vfs_handle_struct *handle,
2158                                const struct smb_filename *fname)
2159 {
2160         /* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */
2161 #if defined(ENOTSUP)
2162         errno = ENOTSUP;
2163 #endif
2164         return -1;
2165 }
2166
2167 static struct vfs_fn_pointers vfs_default_fns = {
2168         /* Disk operations */
2169
2170         .connect_fn = vfswrap_connect,
2171         .disconnect_fn = vfswrap_disconnect,
2172         .disk_free_fn = vfswrap_disk_free,
2173         .get_quota_fn = vfswrap_get_quota,
2174         .set_quota_fn = vfswrap_set_quota,
2175         .get_shadow_copy_data_fn = vfswrap_get_shadow_copy_data,
2176         .statvfs_fn = vfswrap_statvfs,
2177         .fs_capabilities_fn = vfswrap_fs_capabilities,
2178         .get_dfs_referrals_fn = vfswrap_get_dfs_referrals,
2179
2180         /* Directory operations */
2181
2182         .opendir_fn = vfswrap_opendir,
2183         .fdopendir_fn = vfswrap_fdopendir,
2184         .readdir_fn = vfswrap_readdir,
2185         .seekdir_fn = vfswrap_seekdir,
2186         .telldir_fn = vfswrap_telldir,
2187         .rewind_dir_fn = vfswrap_rewinddir,
2188         .mkdir_fn = vfswrap_mkdir,
2189         .rmdir_fn = vfswrap_rmdir,
2190         .closedir_fn = vfswrap_closedir,
2191         .init_search_op_fn = vfswrap_init_search_op,
2192
2193         /* File operations */
2194
2195         .open_fn = vfswrap_open,
2196         .create_file_fn = vfswrap_create_file,
2197         .close_fn = vfswrap_close,
2198         .read_fn = vfswrap_read,
2199         .pread_fn = vfswrap_pread,
2200         .write_fn = vfswrap_write,
2201         .pwrite_fn = vfswrap_pwrite,
2202         .lseek_fn = vfswrap_lseek,
2203         .sendfile_fn = vfswrap_sendfile,
2204         .recvfile_fn = vfswrap_recvfile,
2205         .rename_fn = vfswrap_rename,
2206         .fsync_fn = vfswrap_fsync,
2207         .stat_fn = vfswrap_stat,
2208         .fstat_fn = vfswrap_fstat,
2209         .lstat_fn = vfswrap_lstat,
2210         .get_alloc_size_fn = vfswrap_get_alloc_size,
2211         .unlink_fn = vfswrap_unlink,
2212         .chmod_fn = vfswrap_chmod,
2213         .fchmod_fn = vfswrap_fchmod,
2214         .chown_fn = vfswrap_chown,
2215         .fchown_fn = vfswrap_fchown,
2216         .lchown_fn = vfswrap_lchown,
2217         .chdir_fn = vfswrap_chdir,
2218         .getwd_fn = vfswrap_getwd,
2219         .ntimes_fn = vfswrap_ntimes,
2220         .ftruncate_fn = vfswrap_ftruncate,
2221         .fallocate_fn = vfswrap_fallocate,
2222         .lock_fn = vfswrap_lock,
2223         .kernel_flock_fn = vfswrap_kernel_flock,
2224         .linux_setlease_fn = vfswrap_linux_setlease,
2225         .getlock_fn = vfswrap_getlock,
2226         .symlink_fn = vfswrap_symlink,
2227         .readlink_fn = vfswrap_readlink,
2228         .link_fn = vfswrap_link,
2229         .mknod_fn = vfswrap_mknod,
2230         .realpath_fn = vfswrap_realpath,
2231         .notify_watch_fn = vfswrap_notify_watch,
2232         .chflags_fn = vfswrap_chflags,
2233         .file_id_create_fn = vfswrap_file_id_create,
2234         .streaminfo_fn = vfswrap_streaminfo,
2235         .get_real_filename_fn = vfswrap_get_real_filename,
2236         .connectpath_fn = vfswrap_connectpath,
2237         .brl_lock_windows_fn = vfswrap_brl_lock_windows,
2238         .brl_unlock_windows_fn = vfswrap_brl_unlock_windows,
2239         .brl_cancel_windows_fn = vfswrap_brl_cancel_windows,
2240         .strict_lock_fn = vfswrap_strict_lock,
2241         .strict_unlock_fn = vfswrap_strict_unlock,
2242         .translate_name_fn = vfswrap_translate_name,
2243         .fsctl_fn = vfswrap_fsctl,
2244
2245         /* NT ACL operations. */
2246
2247         .fget_nt_acl_fn = vfswrap_fget_nt_acl,
2248         .get_nt_acl_fn = vfswrap_get_nt_acl,
2249         .fset_nt_acl_fn = vfswrap_fset_nt_acl,
2250
2251         /* POSIX ACL operations. */
2252
2253         .chmod_acl_fn = vfswrap_chmod_acl,
2254         .fchmod_acl_fn = vfswrap_fchmod_acl,
2255
2256         .sys_acl_get_entry_fn = vfswrap_sys_acl_get_entry,
2257         .sys_acl_get_tag_type_fn = vfswrap_sys_acl_get_tag_type,
2258         .sys_acl_get_permset_fn = vfswrap_sys_acl_get_permset,
2259         .sys_acl_get_qualifier_fn = vfswrap_sys_acl_get_qualifier,
2260         .sys_acl_get_file_fn = vfswrap_sys_acl_get_file,
2261         .sys_acl_get_fd_fn = vfswrap_sys_acl_get_fd,
2262         .sys_acl_clear_perms_fn = vfswrap_sys_acl_clear_perms,
2263         .sys_acl_add_perm_fn = vfswrap_sys_acl_add_perm,
2264         .sys_acl_to_text_fn = vfswrap_sys_acl_to_text,
2265         .sys_acl_init_fn = vfswrap_sys_acl_init,
2266         .sys_acl_create_entry_fn = vfswrap_sys_acl_create_entry,
2267         .sys_acl_set_tag_type_fn = vfswrap_sys_acl_set_tag_type,
2268         .sys_acl_set_qualifier_fn = vfswrap_sys_acl_set_qualifier,
2269         .sys_acl_set_permset_fn = vfswrap_sys_acl_set_permset,
2270         .sys_acl_valid_fn = vfswrap_sys_acl_valid,
2271         .sys_acl_set_file_fn = vfswrap_sys_acl_set_file,
2272         .sys_acl_set_fd_fn = vfswrap_sys_acl_set_fd,
2273         .sys_acl_delete_def_file_fn = vfswrap_sys_acl_delete_def_file,
2274         .sys_acl_get_perm_fn = vfswrap_sys_acl_get_perm,
2275         .sys_acl_free_text_fn = vfswrap_sys_acl_free_text,
2276         .sys_acl_free_acl_fn = vfswrap_sys_acl_free_acl,
2277         .sys_acl_free_qualifier_fn = vfswrap_sys_acl_free_qualifier,
2278
2279         /* EA operations. */
2280         .getxattr_fn = vfswrap_getxattr,
2281         .lgetxattr_fn = vfswrap_lgetxattr,
2282         .fgetxattr_fn = vfswrap_fgetxattr,
2283         .listxattr_fn = vfswrap_listxattr,
2284         .llistxattr_fn = vfswrap_llistxattr,
2285         .flistxattr_fn = vfswrap_flistxattr,
2286         .removexattr_fn = vfswrap_removexattr,
2287         .lremovexattr_fn = vfswrap_lremovexattr,
2288         .fremovexattr_fn = vfswrap_fremovexattr,
2289         .setxattr_fn = vfswrap_setxattr,
2290         .lsetxattr_fn = vfswrap_lsetxattr,
2291         .fsetxattr_fn = vfswrap_fsetxattr,
2292
2293         /* aio operations */
2294         .aio_read_fn = vfswrap_aio_read,
2295         .aio_write_fn = vfswrap_aio_write,
2296         .aio_return_fn = vfswrap_aio_return,
2297         .aio_cancel_fn = vfswrap_aio_cancel,
2298         .aio_error_fn = vfswrap_aio_error,
2299         .aio_fsync_fn = vfswrap_aio_fsync,
2300         .aio_suspend_fn = vfswrap_aio_suspend,
2301         .aio_force_fn = vfswrap_aio_force,
2302
2303         /* offline operations */
2304         .is_offline_fn = vfswrap_is_offline,
2305         .set_offline_fn = vfswrap_set_offline
2306 };
2307
2308 NTSTATUS vfs_default_init(void);
2309 NTSTATUS vfs_default_init(void)
2310 {
2311         return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
2312                                 DEFAULT_VFS_MODULE_NAME, &vfs_default_fns);
2313 }
2314
2315