vfs: Make function pointer names consistent. They all end in _fn
[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 "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         NTSTATUS status;
112         int ret = -1;
113
114 #if defined(DARWINOS)
115         struct vfs_statvfs_struct statbuf;
116         ZERO_STRUCT(statbuf);
117         sys_statvfs(conn->connectpath, &statbuf);
118         caps = statbuf.FsCapabilities;
119 #endif
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                                      void (*callback)(struct sys_notify_context *ctx, 
1637                                                       void *private_data,
1638                                                       struct notify_event *ev),
1639                                      void *private_data, void *handle)
1640 {
1641         /*
1642          * So far inotify is the only supported default notify mechanism. If
1643          * another platform like the the BSD's or a proprietary Unix comes
1644          * along and wants another default, we can play the same trick we
1645          * played with Posix ACLs.
1646          *
1647          * Until that is the case, hard-code inotify here.
1648          */
1649 #ifdef HAVE_INOTIFY
1650         if (lp_kernel_change_notify(ctx->conn->params)) {
1651                 return inotify_watch(ctx, e, callback, private_data, handle);
1652         }
1653 #endif
1654         /*
1655          * Do nothing, leave everything to notify_internal.c
1656          */
1657         return NT_STATUS_OK;
1658 }
1659
1660 static int vfswrap_chflags(vfs_handle_struct *handle, const char *path,
1661                            unsigned int flags)
1662 {
1663 #ifdef HAVE_CHFLAGS
1664         return chflags(path, flags);
1665 #else
1666         errno = ENOSYS;
1667         return -1;
1668 #endif
1669 }
1670
1671 static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle,
1672                                              const SMB_STRUCT_STAT *sbuf)
1673 {
1674         struct file_id key;
1675
1676         /* the ZERO_STRUCT ensures padding doesn't break using the key as a
1677          * blob */
1678         ZERO_STRUCT(key);
1679
1680         key.devid = sbuf->st_ex_dev;
1681         key.inode = sbuf->st_ex_ino;
1682         /* key.extid is unused by default. */
1683
1684         return key;
1685 }
1686
1687 static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
1688                                    struct files_struct *fsp,
1689                                    const char *fname,
1690                                    TALLOC_CTX *mem_ctx,
1691                                    unsigned int *pnum_streams,
1692                                    struct stream_struct **pstreams)
1693 {
1694         SMB_STRUCT_STAT sbuf;
1695         struct stream_struct *tmp_streams = NULL;
1696         int ret;
1697
1698         if ((fsp != NULL) && (fsp->is_directory)) {
1699                 /*
1700                  * No default streams on directories
1701                  */
1702                 goto done;
1703         }
1704
1705         if ((fsp != NULL) && (fsp->fh->fd != -1)) {
1706                 ret = SMB_VFS_FSTAT(fsp, &sbuf);
1707         }
1708         else {
1709                 struct smb_filename smb_fname;
1710
1711                 ZERO_STRUCT(smb_fname);
1712                 smb_fname.base_name = discard_const_p(char, fname);
1713
1714                 if (lp_posix_pathnames()) {
1715                         ret = SMB_VFS_LSTAT(handle->conn, &smb_fname);
1716                 } else {
1717                         ret = SMB_VFS_STAT(handle->conn, &smb_fname);
1718                 }
1719                 sbuf = smb_fname.st;
1720         }
1721
1722         if (ret == -1) {
1723                 return map_nt_error_from_unix(errno);
1724         }
1725
1726         if (S_ISDIR(sbuf.st_ex_mode)) {
1727                 goto done;
1728         }
1729
1730         tmp_streams = talloc_realloc(mem_ctx, *pstreams, struct stream_struct,
1731                                         (*pnum_streams) + 1);
1732         if (tmp_streams == NULL) {
1733                 return NT_STATUS_NO_MEMORY;
1734         }
1735         tmp_streams[*pnum_streams].name = talloc_strdup(tmp_streams, "::$DATA");
1736         if (tmp_streams[*pnum_streams].name == NULL) {
1737                 return NT_STATUS_NO_MEMORY;
1738         }
1739         tmp_streams[*pnum_streams].size = sbuf.st_ex_size;
1740         tmp_streams[*pnum_streams].alloc_size = SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp, &sbuf);
1741
1742         *pnum_streams += 1;
1743         *pstreams = tmp_streams;
1744  done:
1745         return NT_STATUS_OK;
1746 }
1747
1748 static int vfswrap_get_real_filename(struct vfs_handle_struct *handle,
1749                                      const char *path,
1750                                      const char *name,
1751                                      TALLOC_CTX *mem_ctx,
1752                                      char **found_name)
1753 {
1754         /*
1755          * Don't fall back to get_real_filename so callers can differentiate
1756          * between a full directory scan and an actual case-insensitive stat.
1757          */
1758         errno = EOPNOTSUPP;
1759         return -1;
1760 }
1761
1762 static const char *vfswrap_connectpath(struct vfs_handle_struct *handle,
1763                                        const char *fname)
1764 {
1765         return handle->conn->connectpath;
1766 }
1767
1768 static NTSTATUS vfswrap_brl_lock_windows(struct vfs_handle_struct *handle,
1769                                          struct byte_range_lock *br_lck,
1770                                          struct lock_struct *plock,
1771                                          bool blocking_lock,
1772                                          struct blocking_lock_record *blr)
1773 {
1774         SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1775
1776         /* Note: blr is not used in the default implementation. */
1777         return brl_lock_windows_default(br_lck, plock, blocking_lock);
1778 }
1779
1780 static bool vfswrap_brl_unlock_windows(struct vfs_handle_struct *handle,
1781                                        struct messaging_context *msg_ctx,
1782                                        struct byte_range_lock *br_lck,
1783                                        const struct lock_struct *plock)
1784 {
1785         SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1786
1787         return brl_unlock_windows_default(msg_ctx, br_lck, plock);
1788 }
1789
1790 static bool vfswrap_brl_cancel_windows(struct vfs_handle_struct *handle,
1791                                        struct byte_range_lock *br_lck,
1792                                        struct lock_struct *plock,
1793                                        struct blocking_lock_record *blr)
1794 {
1795         SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1796
1797         /* Note: blr is not used in the default implementation. */
1798         return brl_lock_cancel_default(br_lck, plock);
1799 }
1800
1801 static bool vfswrap_strict_lock(struct vfs_handle_struct *handle,
1802                                 files_struct *fsp,
1803                                 struct lock_struct *plock)
1804 {
1805         SMB_ASSERT(plock->lock_type == READ_LOCK ||
1806             plock->lock_type == WRITE_LOCK);
1807
1808         return strict_lock_default(fsp, plock);
1809 }
1810
1811 static void vfswrap_strict_unlock(struct vfs_handle_struct *handle,
1812                                 files_struct *fsp,
1813                                 struct lock_struct *plock)
1814 {
1815         SMB_ASSERT(plock->lock_type == READ_LOCK ||
1816             plock->lock_type == WRITE_LOCK);
1817
1818         strict_unlock_default(fsp, plock);
1819 }
1820
1821 /* NT ACL operations. */
1822
1823 static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle,
1824                                     files_struct *fsp,
1825                                     uint32 security_info,
1826                                     struct security_descriptor **ppdesc)
1827 {
1828         NTSTATUS result;
1829
1830         START_PROFILE(fget_nt_acl);
1831         result = posix_fget_nt_acl(fsp, security_info, ppdesc);
1832         END_PROFILE(fget_nt_acl);
1833         return result;
1834 }
1835
1836 static NTSTATUS vfswrap_get_nt_acl(vfs_handle_struct *handle,
1837                                    const char *name,
1838                                    uint32 security_info,
1839                                    struct security_descriptor **ppdesc)
1840 {
1841         NTSTATUS result;
1842
1843         START_PROFILE(get_nt_acl);
1844         result = posix_get_nt_acl(handle->conn, name, security_info, ppdesc);
1845         END_PROFILE(get_nt_acl);
1846         return result;
1847 }
1848
1849 static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, const struct security_descriptor *psd)
1850 {
1851         NTSTATUS result;
1852
1853         START_PROFILE(fset_nt_acl);
1854         result = set_nt_acl(fsp, security_info_sent, psd);
1855         END_PROFILE(fset_nt_acl);
1856         return result;
1857 }
1858
1859 static int vfswrap_chmod_acl(vfs_handle_struct *handle,  const char *name, mode_t mode)
1860 {
1861 #ifdef HAVE_NO_ACL
1862         errno = ENOSYS;
1863         return -1;
1864 #else
1865         int result;
1866
1867         START_PROFILE(chmod_acl);
1868         result = chmod_acl(handle->conn, name, mode);
1869         END_PROFILE(chmod_acl);
1870         return result;
1871 #endif
1872 }
1873
1874 static int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
1875 {
1876 #ifdef HAVE_NO_ACL
1877         errno = ENOSYS;
1878         return -1;
1879 #else
1880         int result;
1881
1882         START_PROFILE(fchmod_acl);
1883         result = fchmod_acl(fsp, mode);
1884         END_PROFILE(fchmod_acl);
1885         return result;
1886 #endif
1887 }
1888
1889 static int vfswrap_sys_acl_get_entry(vfs_handle_struct *handle,  SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
1890 {
1891         return sys_acl_get_entry(theacl, entry_id, entry_p);
1892 }
1893
1894 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)
1895 {
1896         return sys_acl_get_tag_type(entry_d, tag_type_p);
1897 }
1898
1899 static int vfswrap_sys_acl_get_permset(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
1900 {
1901         return sys_acl_get_permset(entry_d, permset_p);
1902 }
1903
1904 static void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry_d)
1905 {
1906         return sys_acl_get_qualifier(entry_d);
1907 }
1908
1909 static SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle,  const char *path_p, SMB_ACL_TYPE_T type)
1910 {
1911         return sys_acl_get_file(handle, path_p, type);
1912 }
1913
1914 static SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp)
1915 {
1916         return sys_acl_get_fd(handle, fsp);
1917 }
1918
1919 static int vfswrap_sys_acl_clear_perms(vfs_handle_struct *handle,  SMB_ACL_PERMSET_T permset)
1920 {
1921         return sys_acl_clear_perms(permset);
1922 }
1923
1924 static int vfswrap_sys_acl_add_perm(vfs_handle_struct *handle,  SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1925 {
1926         return sys_acl_add_perm(permset, perm);
1927 }
1928
1929 static char * vfswrap_sys_acl_to_text(vfs_handle_struct *handle,  SMB_ACL_T theacl, ssize_t *plen)
1930 {
1931         return sys_acl_to_text(theacl, plen);
1932 }
1933
1934 static SMB_ACL_T vfswrap_sys_acl_init(vfs_handle_struct *handle,  int count)
1935 {
1936         return sys_acl_init(count);
1937 }
1938
1939 static int vfswrap_sys_acl_create_entry(vfs_handle_struct *handle,  SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
1940 {
1941         return sys_acl_create_entry(pacl, pentry);
1942 }
1943
1944 static int vfswrap_sys_acl_set_tag_type(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
1945 {
1946         return sys_acl_set_tag_type(entry, tagtype);
1947 }
1948
1949 static int vfswrap_sys_acl_set_qualifier(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry, void *qual)
1950 {
1951         return sys_acl_set_qualifier(entry, qual);
1952 }
1953
1954 static int vfswrap_sys_acl_set_permset(vfs_handle_struct *handle,  SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
1955 {
1956         return sys_acl_set_permset(entry, permset);
1957 }
1958
1959 static int vfswrap_sys_acl_valid(vfs_handle_struct *handle,  SMB_ACL_T theacl )
1960 {
1961         return sys_acl_valid(theacl );
1962 }
1963
1964 static int vfswrap_sys_acl_set_file(vfs_handle_struct *handle,  const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
1965 {
1966         return sys_acl_set_file(handle, name, acltype, theacl);
1967 }
1968
1969 static int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_T theacl)
1970 {
1971         return sys_acl_set_fd(handle, fsp, theacl);
1972 }
1973
1974 static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle,  const char *path)
1975 {
1976         return sys_acl_delete_def_file(handle, path);
1977 }
1978
1979 static int vfswrap_sys_acl_get_perm(vfs_handle_struct *handle,  SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
1980 {
1981         return sys_acl_get_perm(permset, perm);
1982 }
1983
1984 static int vfswrap_sys_acl_free_text(vfs_handle_struct *handle,  char *text)
1985 {
1986         return sys_acl_free_text(text);
1987 }
1988
1989 static int vfswrap_sys_acl_free_acl(vfs_handle_struct *handle,  SMB_ACL_T posix_acl)
1990 {
1991         return sys_acl_free_acl(posix_acl);
1992 }
1993
1994 static int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle,  void *qualifier, SMB_ACL_TAG_T tagtype)
1995 {
1996         return sys_acl_free_qualifier(qualifier, tagtype);
1997 }
1998
1999 /****************************************************************
2000  Extended attribute operations.
2001 *****************************************************************/
2002
2003 static ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
2004 {
2005         return sys_getxattr(path, name, value, size);
2006 }
2007
2008 static ssize_t vfswrap_lgetxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
2009 {
2010         return sys_lgetxattr(path, name, value, size);
2011 }
2012
2013 static ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, void *value, size_t size)
2014 {
2015         return sys_fgetxattr(fsp->fh->fd, name, value, size);
2016 }
2017
2018 static ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
2019 {
2020         return sys_listxattr(path, list, size);
2021 }
2022
2023 static ssize_t vfswrap_llistxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
2024 {
2025         return sys_llistxattr(path, list, size);
2026 }
2027
2028 static ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size)
2029 {
2030         return sys_flistxattr(fsp->fh->fd, list, size);
2031 }
2032
2033 static int vfswrap_removexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
2034 {
2035         return sys_removexattr(path, name);
2036 }
2037
2038 static int vfswrap_lremovexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
2039 {
2040         return sys_lremovexattr(path, name);
2041 }
2042
2043 static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name)
2044 {
2045         return sys_fremovexattr(fsp->fh->fd, name);
2046 }
2047
2048 static int vfswrap_setxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
2049 {
2050         return sys_setxattr(path, name, value, size, flags);
2051 }
2052
2053 static int vfswrap_lsetxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
2054 {
2055         return sys_lsetxattr(path, name, value, size, flags);
2056 }
2057
2058 static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, const void *value, size_t size, int flags)
2059 {
2060         return sys_fsetxattr(fsp->fh->fd, name, value, size, flags);
2061 }
2062
2063 static int vfswrap_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2064 {
2065         int ret;
2066         /*
2067          * aio_read must be done as root, because in the glibc aio
2068          * implementation the helper thread needs to be able to send a signal
2069          * to the main thread, even when it has done a seteuid() to a
2070          * different user.
2071          */
2072         become_root();
2073         ret = sys_aio_read(aiocb);
2074         unbecome_root();
2075         return ret;
2076 }
2077
2078 static int vfswrap_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2079 {
2080         int ret;
2081         /*
2082          * aio_write must be done as root, because in the glibc aio
2083          * implementation the helper thread needs to be able to send a signal
2084          * to the main thread, even when it has done a seteuid() to a
2085          * different user.
2086          */
2087         become_root();
2088         ret = sys_aio_write(aiocb);
2089         unbecome_root();
2090         return ret;
2091 }
2092
2093 static ssize_t vfswrap_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2094 {
2095         return sys_aio_return(aiocb);
2096 }
2097
2098 static int vfswrap_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2099 {
2100         return sys_aio_cancel(fsp->fh->fd, aiocb);
2101 }
2102
2103 static int vfswrap_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
2104 {
2105         return sys_aio_error(aiocb);
2106 }
2107
2108 static int vfswrap_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb)
2109 {
2110         return sys_aio_fsync(op, aiocb);
2111 }
2112
2113 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)
2114 {
2115         return sys_aio_suspend(aiocb, n, timeout);
2116 }
2117
2118 static bool vfswrap_aio_force(struct vfs_handle_struct *handle, struct files_struct *fsp)
2119 {
2120         return false;
2121 }
2122
2123 static bool vfswrap_is_offline(struct vfs_handle_struct *handle,
2124                                const struct smb_filename *fname,
2125                                SMB_STRUCT_STAT *sbuf)
2126 {
2127         NTSTATUS status;
2128         char *path;
2129         bool offline = false;
2130
2131         if (ISDOT(fname->base_name) || ISDOTDOT(fname->base_name)) {
2132                 return false;
2133         }
2134
2135         if (!lp_dmapi_support(SNUM(handle->conn)) || !dmapi_have_session()) {
2136 #if defined(ENOTSUP)
2137                 errno = ENOTSUP;
2138 #endif
2139                 return false;
2140         }
2141
2142         status = get_full_smb_filename(talloc_tos(), fname, &path);
2143         if (!NT_STATUS_IS_OK(status)) {
2144                 errno = map_errno_from_nt_status(status);
2145                 return false;
2146         }
2147
2148         offline = (dmapi_file_flags(path) & FILE_ATTRIBUTE_OFFLINE) != 0;
2149
2150         TALLOC_FREE(path);
2151
2152         return offline;
2153 }
2154
2155 static int vfswrap_set_offline(struct vfs_handle_struct *handle,
2156                                const struct smb_filename *fname)
2157 {
2158         /* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */
2159 #if defined(ENOTSUP)
2160         errno = ENOTSUP;
2161 #endif
2162         return -1;
2163 }
2164
2165 static struct vfs_fn_pointers vfs_default_fns = {
2166         /* Disk operations */
2167
2168         .connect_fn = vfswrap_connect,
2169         .disconnect_fn = vfswrap_disconnect,
2170         .disk_free_fn = vfswrap_disk_free,
2171         .get_quota_fn = vfswrap_get_quota,
2172         .set_quota_fn = vfswrap_set_quota,
2173         .get_shadow_copy_data_fn = vfswrap_get_shadow_copy_data,
2174         .statvfs_fn = vfswrap_statvfs,
2175         .fs_capabilities_fn = vfswrap_fs_capabilities,
2176         .get_dfs_referrals_fn = vfswrap_get_dfs_referrals,
2177
2178         /* Directory operations */
2179
2180         .opendir_fn = vfswrap_opendir,
2181         .fdopendir_fn = vfswrap_fdopendir,
2182         .readdir_fn = vfswrap_readdir,
2183         .seekdir_fn = vfswrap_seekdir,
2184         .telldir_fn = vfswrap_telldir,
2185         .rewind_dir_fn = vfswrap_rewinddir,
2186         .mkdir_fn = vfswrap_mkdir,
2187         .rmdir_fn = vfswrap_rmdir,
2188         .closedir_fn = vfswrap_closedir,
2189         .init_search_op_fn = vfswrap_init_search_op,
2190
2191         /* File operations */
2192
2193         .open_fn = vfswrap_open,
2194         .create_file_fn = vfswrap_create_file,
2195         .close_fn = vfswrap_close,
2196         .read_fn = vfswrap_read,
2197         .pread_fn = vfswrap_pread,
2198         .write_fn = vfswrap_write,
2199         .pwrite_fn = vfswrap_pwrite,
2200         .lseek_fn = vfswrap_lseek,
2201         .sendfile_fn = vfswrap_sendfile,
2202         .recvfile_fn = vfswrap_recvfile,
2203         .rename_fn = vfswrap_rename,
2204         .fsync_fn = vfswrap_fsync,
2205         .stat_fn = vfswrap_stat,
2206         .fstat_fn = vfswrap_fstat,
2207         .lstat_fn = vfswrap_lstat,
2208         .get_alloc_size_fn = vfswrap_get_alloc_size,
2209         .unlink_fn = vfswrap_unlink,
2210         .chmod_fn = vfswrap_chmod,
2211         .fchmod_fn = vfswrap_fchmod,
2212         .chown_fn = vfswrap_chown,
2213         .fchown_fn = vfswrap_fchown,
2214         .lchown_fn = vfswrap_lchown,
2215         .chdir_fn = vfswrap_chdir,
2216         .getwd_fn = vfswrap_getwd,
2217         .ntimes_fn = vfswrap_ntimes,
2218         .ftruncate_fn = vfswrap_ftruncate,
2219         .fallocate_fn = vfswrap_fallocate,
2220         .lock_fn = vfswrap_lock,
2221         .kernel_flock_fn = vfswrap_kernel_flock,
2222         .linux_setlease_fn = vfswrap_linux_setlease,
2223         .getlock_fn = vfswrap_getlock,
2224         .symlink_fn = vfswrap_symlink,
2225         .readlink_fn = vfswrap_readlink,
2226         .link_fn = vfswrap_link,
2227         .mknod_fn = vfswrap_mknod,
2228         .realpath_fn = vfswrap_realpath,
2229         .notify_watch_fn = vfswrap_notify_watch,
2230         .chflags_fn = vfswrap_chflags,
2231         .file_id_create_fn = vfswrap_file_id_create,
2232         .streaminfo_fn = vfswrap_streaminfo,
2233         .get_real_filename_fn = vfswrap_get_real_filename,
2234         .connectpath_fn = vfswrap_connectpath,
2235         .brl_lock_windows_fn = vfswrap_brl_lock_windows,
2236         .brl_unlock_windows_fn = vfswrap_brl_unlock_windows,
2237         .brl_cancel_windows_fn = vfswrap_brl_cancel_windows,
2238         .strict_lock_fn = vfswrap_strict_lock,
2239         .strict_unlock_fn = vfswrap_strict_unlock,
2240         .translate_name_fn = vfswrap_translate_name,
2241         .fsctl_fn = vfswrap_fsctl,
2242
2243         /* NT ACL operations. */
2244
2245         .fget_nt_acl_fn = vfswrap_fget_nt_acl,
2246         .get_nt_acl_fn = vfswrap_get_nt_acl,
2247         .fset_nt_acl_fn = vfswrap_fset_nt_acl,
2248
2249         /* POSIX ACL operations. */
2250
2251         .chmod_acl_fn = vfswrap_chmod_acl,
2252         .fchmod_acl_fn = vfswrap_fchmod_acl,
2253
2254         .sys_acl_get_entry_fn = vfswrap_sys_acl_get_entry,
2255         .sys_acl_get_tag_type_fn = vfswrap_sys_acl_get_tag_type,
2256         .sys_acl_get_permset_fn = vfswrap_sys_acl_get_permset,
2257         .sys_acl_get_qualifier_fn = vfswrap_sys_acl_get_qualifier,
2258         .sys_acl_get_file_fn = vfswrap_sys_acl_get_file,
2259         .sys_acl_get_fd_fn = vfswrap_sys_acl_get_fd,
2260         .sys_acl_clear_perms_fn = vfswrap_sys_acl_clear_perms,
2261         .sys_acl_add_perm_fn = vfswrap_sys_acl_add_perm,
2262         .sys_acl_to_text_fn = vfswrap_sys_acl_to_text,
2263         .sys_acl_init_fn = vfswrap_sys_acl_init,
2264         .sys_acl_create_entry_fn = vfswrap_sys_acl_create_entry,
2265         .sys_acl_set_tag_type_fn = vfswrap_sys_acl_set_tag_type,
2266         .sys_acl_set_qualifier_fn = vfswrap_sys_acl_set_qualifier,
2267         .sys_acl_set_permset_fn = vfswrap_sys_acl_set_permset,
2268         .sys_acl_valid_fn = vfswrap_sys_acl_valid,
2269         .sys_acl_set_file_fn = vfswrap_sys_acl_set_file,
2270         .sys_acl_set_fd_fn = vfswrap_sys_acl_set_fd,
2271         .sys_acl_delete_def_file_fn = vfswrap_sys_acl_delete_def_file,
2272         .sys_acl_get_perm_fn = vfswrap_sys_acl_get_perm,
2273         .sys_acl_free_text_fn = vfswrap_sys_acl_free_text,
2274         .sys_acl_free_acl_fn = vfswrap_sys_acl_free_acl,
2275         .sys_acl_free_qualifier_fn = vfswrap_sys_acl_free_qualifier,
2276
2277         /* EA operations. */
2278         .getxattr_fn = vfswrap_getxattr,
2279         .lgetxattr_fn = vfswrap_lgetxattr,
2280         .fgetxattr_fn = vfswrap_fgetxattr,
2281         .listxattr_fn = vfswrap_listxattr,
2282         .llistxattr_fn = vfswrap_llistxattr,
2283         .flistxattr_fn = vfswrap_flistxattr,
2284         .removexattr_fn = vfswrap_removexattr,
2285         .lremovexattr_fn = vfswrap_lremovexattr,
2286         .fremovexattr_fn = vfswrap_fremovexattr,
2287         .setxattr_fn = vfswrap_setxattr,
2288         .lsetxattr_fn = vfswrap_lsetxattr,
2289         .fsetxattr_fn = vfswrap_fsetxattr,
2290
2291         /* aio operations */
2292         .aio_read_fn = vfswrap_aio_read,
2293         .aio_write_fn = vfswrap_aio_write,
2294         .aio_return_fn = vfswrap_aio_return,
2295         .aio_cancel_fn = vfswrap_aio_cancel,
2296         .aio_error_fn = vfswrap_aio_error,
2297         .aio_fsync_fn = vfswrap_aio_fsync,
2298         .aio_suspend_fn = vfswrap_aio_suspend,
2299         .aio_force_fn = vfswrap_aio_force,
2300
2301         /* offline operations */
2302         .is_offline_fn = vfswrap_is_offline,
2303         .set_offline_fn = vfswrap_set_offline
2304 };
2305
2306 NTSTATUS vfs_default_init(void);
2307 NTSTATUS vfs_default_init(void)
2308 {
2309         return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
2310                                 DEFAULT_VFS_MODULE_NAME, &vfs_default_fns);
2311 }
2312
2313