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