/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- vfswrap_connect
- vfswrap_disconnect
- vfswrap_disk_free
- vfswrap_get_quota
- vfswrap_set_quota
- vfswrap_get_shadow_copy_data
- vfswrap_statvfs
- vfswrap_fs_capabilities
- vfswrap_opendir
- vfswrap_readdir
- vfswrap_seekdir
- vfswrap_telldir
- vfswrap_rewinddir
- vfswrap_mkdir
- vfswrap_rmdir
- vfswrap_closedir
- vfswrap_init_search_op
- vfswrap_open
- vfswrap_create_file
- vfswrap_close
- vfswrap_read
- vfswrap_pread
- vfswrap_write
- vfswrap_pwrite
- vfswrap_lseek
- vfswrap_sendfile
- vfswrap_recvfile
- copy_reg
- vfswrap_rename
- vfswrap_fsync
- vfswrap_stat
- vfswrap_fstat
- vfswrap_lstat
- vfswrap_get_alloc_size
- vfswrap_unlink
- vfswrap_chmod
- vfswrap_fchmod
- vfswrap_chown
- vfswrap_fchown
- vfswrap_lchown
- vfswrap_chdir
- vfswrap_getwd
- vfswrap_ntimes
- strict_allocate_ftruncate
- vfswrap_ftruncate
- vfswrap_lock
- vfswrap_kernel_flock
- vfswrap_getlock
- vfswrap_linux_setlease
- vfswrap_symlink
- vfswrap_readlink
- vfswrap_link
- vfswrap_mknod
- vfswrap_realpath
- vfswrap_notify_watch
- vfswrap_chflags
- vfswrap_file_id_create
- vfswrap_streaminfo
- vfswrap_get_real_filename
- vfswrap_brl_lock_windows
- vfswrap_brl_unlock_windows
- vfswrap_brl_cancel_windows
- vfswrap_strict_lock
- vfswrap_strict_unlock
- vfswrap_fget_nt_acl
- vfswrap_get_nt_acl
- vfswrap_fset_nt_acl
- vfswrap_chmod_acl
- vfswrap_fchmod_acl
- vfswrap_sys_acl_get_entry
- vfswrap_sys_acl_get_tag_type
- vfswrap_sys_acl_get_permset
- vfswrap_sys_acl_get_qualifier
- vfswrap_sys_acl_get_file
- vfswrap_sys_acl_get_fd
- vfswrap_sys_acl_clear_perms
- vfswrap_sys_acl_add_perm
- vfswrap_sys_acl_to_text
- vfswrap_sys_acl_init
- vfswrap_sys_acl_create_entry
- vfswrap_sys_acl_set_tag_type
- vfswrap_sys_acl_set_qualifier
- vfswrap_sys_acl_set_permset
- vfswrap_sys_acl_valid
- vfswrap_sys_acl_set_file
- vfswrap_sys_acl_set_fd
- vfswrap_sys_acl_delete_def_file
- vfswrap_sys_acl_get_perm
- vfswrap_sys_acl_free_text
- vfswrap_sys_acl_free_acl
- vfswrap_sys_acl_free_qualifier
- vfswrap_getxattr
- vfswrap_lgetxattr
- vfswrap_fgetxattr
- vfswrap_listxattr
- vfswrap_llistxattr
- vfswrap_flistxattr
- vfswrap_removexattr
- vfswrap_lremovexattr
- vfswrap_fremovexattr
- vfswrap_setxattr
- vfswrap_lsetxattr
- vfswrap_fsetxattr
- vfswrap_aio_read
- vfswrap_aio_write
- vfswrap_aio_return
- vfswrap_aio_cancel
- vfswrap_aio_error
- vfswrap_aio_fsync
- vfswrap_aio_suspend
- vfswrap_aio_force
- vfswrap_is_offline
- vfswrap_set_offline
- vfs_default_init
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
23 #undef DBGC_CLASS
24 #define DBGC_CLASS DBGC_VFS
25
26 /* Check for NULL pointer parameters in vfswrap_* functions */
27
28 /* We don't want to have NULL function pointers lying around. Someone
29 is sure to try and execute them. These stubs are used to prevent
30 this possibility. */
31
32 static int vfswrap_connect(vfs_handle_struct *handle, const char *service, const char *user)
/* [<][>][^][v][top][bottom][index][help] */
33 {
34 return 0; /* Return >= 0 for success */
35 }
36
37 static void vfswrap_disconnect(vfs_handle_struct *handle)
/* [<][>][^][v][top][bottom][index][help] */
38 {
39 }
40
41 /* Disk operations */
42
43 static uint64_t vfswrap_disk_free(vfs_handle_struct *handle, const char *path, bool small_query, uint64_t *bsize,
/* [<][>][^][v][top][bottom][index][help] */
44 uint64_t *dfree, uint64_t *dsize)
45 {
46 uint64_t result;
47
48 result = sys_disk_free(handle->conn, path, small_query, bsize, dfree, dsize);
49 return result;
50 }
51
52 static int vfswrap_get_quota(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
/* [<][>][^][v][top][bottom][index][help] */
53 {
54 #ifdef HAVE_SYS_QUOTAS
55 int result;
56
57 START_PROFILE(syscall_get_quota);
58 result = sys_get_quota(handle->conn->connectpath, qtype, id, qt);
59 END_PROFILE(syscall_get_quota);
60 return result;
61 #else
62 errno = ENOSYS;
63 return -1;
64 #endif
65 }
66
67 static int vfswrap_set_quota(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
/* [<][>][^][v][top][bottom][index][help] */
68 {
69 #ifdef HAVE_SYS_QUOTAS
70 int result;
71
72 START_PROFILE(syscall_set_quota);
73 result = sys_set_quota(handle->conn->connectpath, qtype, id, qt);
74 END_PROFILE(syscall_set_quota);
75 return result;
76 #else
77 errno = ENOSYS;
78 return -1;
79 #endif
80 }
81
82 static int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, bool labels)
/* [<][>][^][v][top][bottom][index][help] */
83 {
84 errno = ENOSYS;
85 return -1; /* Not implemented. */
86 }
87
88 static int vfswrap_statvfs(struct vfs_handle_struct *handle, const char *path, vfs_statvfs_struct *statbuf)
/* [<][>][^][v][top][bottom][index][help] */
89 {
90 return sys_statvfs(path, statbuf);
91 }
92
93 static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle)
/* [<][>][^][v][top][bottom][index][help] */
94 {
95 connection_struct *conn = handle->conn;
96 uint32_t caps = FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES;
97 SMB_STRUCT_STAT st;
98 NTSTATUS status;
99 struct timespec mtime_ts, ctime_ts, atime_ts;
100 int ret = -1;
101
102 #if defined(DARWINOS)
103 struct vfs_statvfs_struct statbuf;
104 ZERO_STRUCT(statbuf);
105 sys_statvfs(handle->conn->connectpath, &statbuf);
106 return statbuf.FsCapabilities;
107 #endif
108
109 conn->ts_res = TIMESTAMP_SET_SECONDS;
110
111 /* Work out what timestamp resolution we can
112 * use when setting a timestamp. */
113
114 ret = SMB_VFS_STAT(conn, conn->connectpath, &st);
115 if (ret == -1) {
116 return caps;
117 }
118
119 mtime_ts = get_mtimespec(&st);
120 ctime_ts = get_ctimespec(&st);
121 atime_ts = get_atimespec(&st);
122
123 if (mtime_ts.tv_nsec ||
124 atime_ts.tv_nsec ||
125 ctime_ts.tv_nsec) {
126 /* If any of the normal UNIX directory timestamps
127 * have a non-zero tv_nsec component assume
128 * we might be able to set sub-second timestamps.
129 * See what filetime set primitives we have.
130 */
131 #if defined(HAVE_UTIMES)
132 /* utimes allows msec timestamps to be set. */
133 conn->ts_res = TIMESTAMP_SET_MSEC;
134 #elif defined(HAVE_UTIME)
135 /* utime only allows sec timestamps to be set. */
136 conn->ts_res = TIMESTAMP_SET_SECONDS;
137 #endif
138
139 /* TODO. Add a configure test for the Linux
140 * nsec timestamp set system call, and use it
141 * if available....
142 */
143 DEBUG(10,("vfswrap_fs_capabilities: timestamp "
144 "resolution of %s "
145 "available on share %s, directory %s\n",
146 conn->ts_res == TIMESTAMP_SET_MSEC ? "msec" : "sec",
147 lp_servicename(conn->cnum),
148 conn->connectpath ));
149 }
150 return caps;
151 }
152
153 /* Directory operations */
154
155 static SMB_STRUCT_DIR *vfswrap_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr)
/* [<][>][^][v][top][bottom][index][help] */
156 {
157 SMB_STRUCT_DIR *result;
158
159 START_PROFILE(syscall_opendir);
160 result = sys_opendir(fname);
161 END_PROFILE(syscall_opendir);
162 return result;
163 }
164
165 static SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle,
/* [<][>][^][v][top][bottom][index][help] */
166 SMB_STRUCT_DIR *dirp,
167 SMB_STRUCT_STAT *sbuf)
168 {
169 SMB_STRUCT_DIRENT *result;
170
171 START_PROFILE(syscall_readdir);
172 result = sys_readdir(dirp);
173 /* Default Posix readdir() does not give us stat info.
174 * Set to invalid to indicate we didn't return this info. */
175 if (sbuf)
176 SET_STAT_INVALID(*sbuf);
177 END_PROFILE(syscall_readdir);
178 return result;
179 }
180
181 static void vfswrap_seekdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp, long offset)
/* [<][>][^][v][top][bottom][index][help] */
182 {
183 START_PROFILE(syscall_seekdir);
184 sys_seekdir(dirp, offset);
185 END_PROFILE(syscall_seekdir);
186 }
187
188 static long vfswrap_telldir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp)
/* [<][>][^][v][top][bottom][index][help] */
189 {
190 long result;
191 START_PROFILE(syscall_telldir);
192 result = sys_telldir(dirp);
193 END_PROFILE(syscall_telldir);
194 return result;
195 }
196
197 static void vfswrap_rewinddir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp)
/* [<][>][^][v][top][bottom][index][help] */
198 {
199 START_PROFILE(syscall_rewinddir);
200 sys_rewinddir(dirp);
201 END_PROFILE(syscall_rewinddir);
202 }
203
204 static int vfswrap_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode)
/* [<][>][^][v][top][bottom][index][help] */
205 {
206 int result;
207 bool has_dacl = False;
208 char *parent = NULL;
209
210 START_PROFILE(syscall_mkdir);
211
212 if (lp_inherit_acls(SNUM(handle->conn))
213 && parent_dirname(talloc_tos(), path, &parent, NULL)
214 && (has_dacl = directory_has_default_acl(handle->conn, parent)))
215 mode = 0777;
216
217 TALLOC_FREE(parent);
218
219 result = mkdir(path, mode);
220
221 if (result == 0 && !has_dacl) {
222 /*
223 * We need to do this as the default behavior of POSIX ACLs
224 * is to set the mask to be the requested group permission
225 * bits, not the group permission bits to be the requested
226 * group permission bits. This is not what we want, as it will
227 * mess up any inherited ACL bits that were set. JRA.
228 */
229 int saved_errno = errno; /* We may get ENOSYS */
230 if ((SMB_VFS_CHMOD_ACL(handle->conn, path, mode) == -1) && (errno == ENOSYS))
231 errno = saved_errno;
232 }
233
234 END_PROFILE(syscall_mkdir);
235 return result;
236 }
237
238 static int vfswrap_rmdir(vfs_handle_struct *handle, const char *path)
/* [<][>][^][v][top][bottom][index][help] */
239 {
240 int result;
241
242 START_PROFILE(syscall_rmdir);
243 result = rmdir(path);
244 END_PROFILE(syscall_rmdir);
245 return result;
246 }
247
248 static int vfswrap_closedir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp)
/* [<][>][^][v][top][bottom][index][help] */
249 {
250 int result;
251
252 START_PROFILE(syscall_closedir);
253 result = sys_closedir(dirp);
254 END_PROFILE(syscall_closedir);
255 return result;
256 }
257
258 static void vfswrap_init_search_op(vfs_handle_struct *handle,
/* [<][>][^][v][top][bottom][index][help] */
259 SMB_STRUCT_DIR *dirp)
260 {
261 /* Default behavior is a NOOP */
262 }
263
264 /* File operations */
265
266 static int vfswrap_open(vfs_handle_struct *handle, const char *fname,
/* [<][>][^][v][top][bottom][index][help] */
267 files_struct *fsp, int flags, mode_t mode)
268 {
269 int result;
270
271 START_PROFILE(syscall_open);
272 result = sys_open(fname, flags, mode);
273 END_PROFILE(syscall_open);
274 return result;
275 }
276
277 static NTSTATUS vfswrap_create_file(vfs_handle_struct *handle,
/* [<][>][^][v][top][bottom][index][help] */
278 struct smb_request *req,
279 uint16_t root_dir_fid,
280 const char *fname,
281 uint32_t create_file_flags,
282 uint32_t access_mask,
283 uint32_t share_access,
284 uint32_t create_disposition,
285 uint32_t create_options,
286 uint32_t file_attributes,
287 uint32_t oplock_request,
288 uint64_t allocation_size,
289 struct security_descriptor *sd,
290 struct ea_list *ea_list,
291 files_struct **result,
292 int *pinfo,
293 SMB_STRUCT_STAT *psbuf)
294 {
295 return create_file_default(handle->conn, req, root_dir_fid, fname,
296 create_file_flags, access_mask, share_access,
297 create_disposition, create_options,
298 file_attributes, oplock_request,
299 allocation_size, sd, ea_list, result, pinfo,
300 psbuf);
301 }
302
303 static int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp)
/* [<][>][^][v][top][bottom][index][help] */
304 {
305 int result;
306
307 START_PROFILE(syscall_close);
308 result = fd_close_posix(fsp);
309 END_PROFILE(syscall_close);
310 return result;
311 }
312
313 static ssize_t vfswrap_read(vfs_handle_struct *handle, files_struct *fsp, void *data, size_t n)
/* [<][>][^][v][top][bottom][index][help] */
314 {
315 ssize_t result;
316
317 START_PROFILE_BYTES(syscall_read, n);
318 result = sys_read(fsp->fh->fd, data, n);
319 END_PROFILE(syscall_read);
320 return result;
321 }
322
323 static ssize_t vfswrap_pread(vfs_handle_struct *handle, files_struct *fsp, void *data,
/* [<][>][^][v][top][bottom][index][help] */
324 size_t n, SMB_OFF_T offset)
325 {
326 ssize_t result;
327
328 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
329 START_PROFILE_BYTES(syscall_pread, n);
330 result = sys_pread(fsp->fh->fd, data, n, offset);
331 END_PROFILE(syscall_pread);
332
333 if (result == -1 && errno == ESPIPE) {
334 /* Maintain the fiction that pipes can be seeked (sought?) on. */
335 result = SMB_VFS_READ(fsp, data, n);
336 fsp->fh->pos = 0;
337 }
338
339 #else /* HAVE_PREAD */
340 SMB_OFF_T curr;
341 int lerrno;
342
343 curr = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
344 if (curr == -1 && errno == ESPIPE) {
345 /* Maintain the fiction that pipes can be seeked (sought?) on. */
346 result = SMB_VFS_READ(fsp, data, n);
347 fsp->fh->pos = 0;
348 return result;
349 }
350
351 if (SMB_VFS_LSEEK(fsp, offset, SEEK_SET) == -1) {
352 return -1;
353 }
354
355 errno = 0;
356 result = SMB_VFS_READ(fsp, data, n);
357 lerrno = errno;
358
359 SMB_VFS_LSEEK(fsp, curr, SEEK_SET);
360 errno = lerrno;
361
362 #endif /* HAVE_PREAD */
363
364 return result;
365 }
366
367 static ssize_t vfswrap_write(vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n)
/* [<][>][^][v][top][bottom][index][help] */
368 {
369 ssize_t result;
370
371 START_PROFILE_BYTES(syscall_write, n);
372 result = sys_write(fsp->fh->fd, data, n);
373 END_PROFILE(syscall_write);
374 return result;
375 }
376
377 static ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, const void *data,
/* [<][>][^][v][top][bottom][index][help] */
378 size_t n, SMB_OFF_T offset)
379 {
380 ssize_t result;
381
382 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
383 START_PROFILE_BYTES(syscall_pwrite, n);
384 result = sys_pwrite(fsp->fh->fd, data, n, offset);
385 END_PROFILE(syscall_pwrite);
386
387 if (result == -1 && errno == ESPIPE) {
388 /* Maintain the fiction that pipes can be sought on. */
389 result = SMB_VFS_WRITE(fsp, data, n);
390 }
391
392 #else /* HAVE_PWRITE */
393 SMB_OFF_T curr;
394 int lerrno;
395
396 curr = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
397 if (curr == -1) {
398 return -1;
399 }
400
401 if (SMB_VFS_LSEEK(fsp, offset, SEEK_SET) == -1) {
402 return -1;
403 }
404
405 result = SMB_VFS_WRITE(fsp, data, n);
406 lerrno = errno;
407
408 SMB_VFS_LSEEK(fsp, curr, SEEK_SET);
409 errno = lerrno;
410
411 #endif /* HAVE_PWRITE */
412
413 return result;
414 }
415
416 static SMB_OFF_T vfswrap_lseek(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T offset, int whence)
/* [<][>][^][v][top][bottom][index][help] */
417 {
418 SMB_OFF_T result = 0;
419
420 START_PROFILE(syscall_lseek);
421
422 /* Cope with 'stat' file opens. */
423 if (fsp->fh->fd != -1)
424 result = sys_lseek(fsp->fh->fd, offset, whence);
425
426 /*
427 * We want to maintain the fiction that we can seek
428 * on a fifo for file system purposes. This allows
429 * people to set up UNIX fifo's that feed data to Windows
430 * applications. JRA.
431 */
432
433 if((result == -1) && (errno == ESPIPE)) {
434 result = 0;
435 errno = 0;
436 }
437
438 END_PROFILE(syscall_lseek);
439 return result;
440 }
441
442 static ssize_t vfswrap_sendfile(vfs_handle_struct *handle, int tofd, files_struct *fromfsp, const DATA_BLOB *hdr,
/* [<][>][^][v][top][bottom][index][help] */
443 SMB_OFF_T offset, size_t n)
444 {
445 ssize_t result;
446
447 START_PROFILE_BYTES(syscall_sendfile, n);
448 result = sys_sendfile(tofd, fromfsp->fh->fd, hdr, offset, n);
449 END_PROFILE(syscall_sendfile);
450 return result;
451 }
452
453 static ssize_t vfswrap_recvfile(vfs_handle_struct *handle,
/* [<][>][^][v][top][bottom][index][help] */
454 int fromfd,
455 files_struct *tofsp,
456 SMB_OFF_T offset,
457 size_t n)
458 {
459 ssize_t result;
460
461 START_PROFILE_BYTES(syscall_recvfile, n);
462 result = sys_recvfile(fromfd, tofsp->fh->fd, offset, n);
463 END_PROFILE(syscall_recvfile);
464 return result;
465 }
466
467 /*********************************************************
468 For rename across filesystems Patch from Warren Birnbaum
469 <warrenb@hpcvscdp.cv.hp.com>
470 **********************************************************/
471
472 static int copy_reg(const char *source, const char *dest)
/* [<][>][^][v][top][bottom][index][help] */
473 {
474 SMB_STRUCT_STAT source_stats;
475 int saved_errno;
476 int ifd = -1;
477 int ofd = -1;
478
479 if (sys_lstat (source, &source_stats) == -1)
480 return -1;
481
482 if (!S_ISREG (source_stats.st_mode))
483 return -1;
484
485 if((ifd = sys_open (source, O_RDONLY, 0)) < 0)
486 return -1;
487
488 if (unlink (dest) && errno != ENOENT)
489 return -1;
490
491 #ifdef O_NOFOLLOW
492 if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 0 )
493 #else
494 if((ofd = sys_open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 )
495 #endif
496 goto err;
497
498 if (transfer_file(ifd, ofd, (size_t)-1) == -1)
499 goto err;
500
501 /*
502 * Try to preserve ownership. For non-root it might fail, but that's ok.
503 * But root probably wants to know, e.g. if NFS disallows it.
504 */
505
506 #ifdef HAVE_FCHOWN
507 if ((fchown(ofd, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM))
508 #else
509 if ((chown(dest, source_stats.st_uid, source_stats.st_gid) == -1) && (errno != EPERM))
510 #endif
511 goto err;
512
513 /*
514 * fchown turns off set[ug]id bits for non-root,
515 * so do the chmod last.
516 */
517
518 #if defined(HAVE_FCHMOD)
519 if (fchmod (ofd, source_stats.st_mode & 07777))
520 #else
521 if (chmod (dest, source_stats.st_mode & 07777))
522 #endif
523 goto err;
524
525 if (close (ifd) == -1)
526 goto err;
527
528 if (close (ofd) == -1)
529 return -1;
530
531 /* Try to copy the old file's modtime and access time. */
532 {
533 struct utimbuf tv;
534
535 tv.actime = source_stats.st_atime;
536 tv.modtime = source_stats.st_mtime;
537 utime(dest, &tv);
538 }
539
540 if (unlink (source) == -1)
541 return -1;
542
543 return 0;
544
545 err:
546
547 saved_errno = errno;
548 if (ifd != -1)
549 close(ifd);
550 if (ofd != -1)
551 close(ofd);
552 errno = saved_errno;
553 return -1;
554 }
555
556 static int vfswrap_rename(vfs_handle_struct *handle, const char *oldname, const char *newname)
/* [<][>][^][v][top][bottom][index][help] */
557 {
558 int result;
559
560 START_PROFILE(syscall_rename);
561 result = rename(oldname, newname);
562 if ((result == -1) && (errno == EXDEV)) {
563 /* Rename across filesystems needed. */
564 result = copy_reg(oldname, newname);
565 }
566
567 END_PROFILE(syscall_rename);
568 return result;
569 }
570
571 static int vfswrap_fsync(vfs_handle_struct *handle, files_struct *fsp)
/* [<][>][^][v][top][bottom][index][help] */
572 {
573 #ifdef HAVE_FSYNC
574 int result;
575
576 START_PROFILE(syscall_fsync);
577 result = fsync(fsp->fh->fd);
578 END_PROFILE(syscall_fsync);
579 return result;
580 #else
581 return 0;
582 #endif
583 }
584
585 static int vfswrap_stat(vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf)
/* [<][>][^][v][top][bottom][index][help] */
586 {
587 int result;
588
589 START_PROFILE(syscall_stat);
590 result = sys_stat(fname, sbuf);
591 END_PROFILE(syscall_stat);
592 return result;
593 }
594
595 static int vfswrap_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STRUCT_STAT *sbuf)
/* [<][>][^][v][top][bottom][index][help] */
596 {
597 int result;
598
599 START_PROFILE(syscall_fstat);
600 result = sys_fstat(fsp->fh->fd, sbuf);
601 END_PROFILE(syscall_fstat);
602 return result;
603 }
604
605 int vfswrap_lstat(vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf)
/* [<][>][^][v][top][bottom][index][help] */
606 {
607 int result;
608
609 START_PROFILE(syscall_lstat);
610 result = sys_lstat(path, sbuf);
611 END_PROFILE(syscall_lstat);
612 return result;
613 }
614
615 /********************************************************************
616 Given a stat buffer return the allocated size on disk, taking into
617 account sparse files.
618 ********************************************************************/
619 static uint64_t vfswrap_get_alloc_size(vfs_handle_struct *handle,
/* [<][>][^][v][top][bottom][index][help] */
620 struct files_struct *fsp,
621 const SMB_STRUCT_STAT *sbuf)
622 {
623 uint64_t result;
624
625 START_PROFILE(syscall_get_alloc_size);
626
627 if(S_ISDIR(sbuf->st_mode)) {
628 result = 0;
629 goto out;
630 }
631
632 #if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
633 result = (uint64_t)STAT_ST_BLOCKSIZE * (uint64_t)sbuf->st_blocks;
634 #else
635 result = get_file_size_stat(sbuf);
636 #endif
637
638 if (fsp && fsp->initial_allocation_size)
639 result = MAX(result,fsp->initial_allocation_size);
640
641 result = smb_roundup(handle->conn, result);
642
643 out:
644 END_PROFILE(syscall_get_alloc_size);
645 return result;
646 }
647
648 static int vfswrap_unlink(vfs_handle_struct *handle, const char *path)
/* [<][>][^][v][top][bottom][index][help] */
649 {
650 int result;
651
652 START_PROFILE(syscall_unlink);
653 result = unlink(path);
654 END_PROFILE(syscall_unlink);
655 return result;
656 }
657
658 static int vfswrap_chmod(vfs_handle_struct *handle, const char *path, mode_t mode)
/* [<][>][^][v][top][bottom][index][help] */
659 {
660 int result;
661
662 START_PROFILE(syscall_chmod);
663
664 /*
665 * We need to do this due to the fact that the default POSIX ACL
666 * chmod modifies the ACL *mask* for the group owner, not the
667 * group owner bits directly. JRA.
668 */
669
670
671 {
672 int saved_errno = errno; /* We might get ENOSYS */
673 if ((result = SMB_VFS_CHMOD_ACL(handle->conn, path, mode)) == 0) {
674 END_PROFILE(syscall_chmod);
675 return result;
676 }
677 /* Error - return the old errno. */
678 errno = saved_errno;
679 }
680
681 result = chmod(path, mode);
682 END_PROFILE(syscall_chmod);
683 return result;
684 }
685
686 static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
/* [<][>][^][v][top][bottom][index][help] */
687 {
688 int result;
689
690 START_PROFILE(syscall_fchmod);
691
692 /*
693 * We need to do this due to the fact that the default POSIX ACL
694 * chmod modifies the ACL *mask* for the group owner, not the
695 * group owner bits directly. JRA.
696 */
697
698 {
699 int saved_errno = errno; /* We might get ENOSYS */
700 if ((result = SMB_VFS_FCHMOD_ACL(fsp, mode)) == 0) {
701 END_PROFILE(syscall_fchmod);
702 return result;
703 }
704 /* Error - return the old errno. */
705 errno = saved_errno;
706 }
707
708 #if defined(HAVE_FCHMOD)
709 result = fchmod(fsp->fh->fd, mode);
710 #else
711 result = -1;
712 errno = ENOSYS;
713 #endif
714
715 END_PROFILE(syscall_fchmod);
716 return result;
717 }
718
719 static int vfswrap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
/* [<][>][^][v][top][bottom][index][help] */
720 {
721 int result;
722
723 START_PROFILE(syscall_chown);
724 result = chown(path, uid, gid);
725 END_PROFILE(syscall_chown);
726 return result;
727 }
728
729 static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t uid, gid_t gid)
/* [<][>][^][v][top][bottom][index][help] */
730 {
731 #ifdef HAVE_FCHOWN
732 int result;
733
734 START_PROFILE(syscall_fchown);
735 result = fchown(fsp->fh->fd, uid, gid);
736 END_PROFILE(syscall_fchown);
737 return result;
738 #else
739 errno = ENOSYS;
740 return -1;
741 #endif
742 }
743
744 static int vfswrap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
/* [<][>][^][v][top][bottom][index][help] */
745 {
746 int result;
747
748 START_PROFILE(syscall_lchown);
749 result = lchown(path, uid, gid);
750 END_PROFILE(syscall_lchown);
751 return result;
752 }
753
754 static int vfswrap_chdir(vfs_handle_struct *handle, const char *path)
/* [<][>][^][v][top][bottom][index][help] */
755 {
756 int result;
757
758 START_PROFILE(syscall_chdir);
759 result = chdir(path);
760 END_PROFILE(syscall_chdir);
761 return result;
762 }
763
764 static char *vfswrap_getwd(vfs_handle_struct *handle, char *path)
/* [<][>][^][v][top][bottom][index][help] */
765 {
766 char *result;
767
768 START_PROFILE(syscall_getwd);
769 result = sys_getwd(path);
770 END_PROFILE(syscall_getwd);
771 return result;
772 }
773
774 /*********************************************************************
775 nsec timestamp resolution call. Convert down to whatever the underlying
776 system will support.
777 **********************************************************************/
778
779 static int vfswrap_ntimes(vfs_handle_struct *handle, const char *path,
/* [<][>][^][v][top][bottom][index][help] */
780 struct smb_file_time *ft)
781 {
782 int result;
783
784 START_PROFILE(syscall_ntimes);
785 #if defined(HAVE_UTIMES)
786 if (ft != NULL) {
787 struct timeval tv[2];
788 tv[0] = convert_timespec_to_timeval(ft->atime);
789 tv[1] = convert_timespec_to_timeval(ft->mtime);
790 result = utimes(path, tv);
791 } else {
792 result = utimes(path, NULL);
793 }
794 #elif defined(HAVE_UTIME)
795 if (ft != NULL) {
796 struct utimbuf times;
797 times.actime = convert_timespec_to_time_t(ft->atime);
798 times.modtime = convert_timespec_to_time_t(ft->mtime);
799 result = utime(path, ×);
800 } else {
801 result = utime(path, NULL);
802 }
803 #else
804 errno = ENOSYS;
805 result = -1;
806 #endif
807 END_PROFILE(syscall_ntimes);
808 return result;
809 }
810
811 /*********************************************************************
812 A version of ftruncate that will write the space on disk if strict
813 allocate is set.
814 **********************************************************************/
815
816 static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T len)
/* [<][>][^][v][top][bottom][index][help] */
817 {
818 SMB_STRUCT_STAT st;
819 SMB_OFF_T currpos = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
820 unsigned char zero_space[4096];
821 SMB_OFF_T space_to_write;
822
823 if (currpos == -1)
824 return -1;
825
826 if (SMB_VFS_FSTAT(fsp, &st) == -1)
827 return -1;
828
829 space_to_write = len - st.st_size;
830
831 #ifdef S_ISFIFO
832 if (S_ISFIFO(st.st_mode))
833 return 0;
834 #endif
835
836 if (st.st_size == len)
837 return 0;
838
839 /* Shrink - just ftruncate. */
840 if (st.st_size > len)
841 return sys_ftruncate(fsp->fh->fd, len);
842
843 /* available disk space is enough or not? */
844 if (lp_strict_allocate(SNUM(fsp->conn))){
845 uint64_t space_avail;
846 uint64_t bsize,dfree,dsize;
847
848 space_avail = get_dfree_info(fsp->conn,fsp->fsp_name,false,&bsize,&dfree,&dsize);
849 /* space_avail is 1k blocks */
850 if (space_avail == (uint64_t)-1 ||
851 ((uint64_t)space_to_write/1024 > space_avail) ) {
852 errno = ENOSPC;
853 return -1;
854 }
855 }
856
857 /* Write out the real space on disk. */
858 if (SMB_VFS_LSEEK(fsp, st.st_size, SEEK_SET) != st.st_size)
859 return -1;
860
861 space_to_write = len - st.st_size;
862
863 memset(zero_space, '\0', sizeof(zero_space));
864 while ( space_to_write > 0) {
865 SMB_OFF_T retlen;
866 SMB_OFF_T current_len_to_write = MIN(sizeof(zero_space),space_to_write);
867
868 retlen = SMB_VFS_WRITE(fsp,(char *)zero_space,current_len_to_write);
869 if (retlen <= 0)
870 return -1;
871
872 space_to_write -= retlen;
873 }
874
875 /* Seek to where we were */
876 if (SMB_VFS_LSEEK(fsp, currpos, SEEK_SET) != currpos)
877 return -1;
878
879 return 0;
880 }
881
882 static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T len)
/* [<][>][^][v][top][bottom][index][help] */
883 {
884 int result = -1;
885 SMB_STRUCT_STAT st;
886 char c = 0;
887 SMB_OFF_T currpos;
888
889 START_PROFILE(syscall_ftruncate);
890
891 if (lp_strict_allocate(SNUM(fsp->conn))) {
892 result = strict_allocate_ftruncate(handle, fsp, len);
893 END_PROFILE(syscall_ftruncate);
894 return result;
895 }
896
897 /* we used to just check HAVE_FTRUNCATE_EXTEND and only use
898 sys_ftruncate if the system supports it. Then I discovered that
899 you can have some filesystems that support ftruncate
900 expansion and some that don't! On Linux fat can't do
901 ftruncate extend but ext2 can. */
902
903 result = sys_ftruncate(fsp->fh->fd, len);
904 if (result == 0)
905 goto done;
906
907 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
908 extend a file with ftruncate. Provide alternate implementation
909 for this */
910 currpos = SMB_VFS_LSEEK(fsp, 0, SEEK_CUR);
911 if (currpos == -1) {
912 goto done;
913 }
914
915 /* Do an fstat to see if the file is longer than the requested
916 size in which case the ftruncate above should have
917 succeeded or shorter, in which case seek to len - 1 and
918 write 1 byte of zero */
919 if (SMB_VFS_FSTAT(fsp, &st) == -1) {
920 goto done;
921 }
922
923 #ifdef S_ISFIFO
924 if (S_ISFIFO(st.st_mode)) {
925 result = 0;
926 goto done;
927 }
928 #endif
929
930 if (st.st_size == len) {
931 result = 0;
932 goto done;
933 }
934
935 if (st.st_size > len) {
936 /* the sys_ftruncate should have worked */
937 goto done;
938 }
939
940 if (SMB_VFS_LSEEK(fsp, len-1, SEEK_SET) != len -1)
941 goto done;
942
943 if (SMB_VFS_WRITE(fsp, &c, 1)!=1)
944 goto done;
945
946 /* Seek to where we were */
947 if (SMB_VFS_LSEEK(fsp, currpos, SEEK_SET) != currpos)
948 goto done;
949 result = 0;
950
951 done:
952
953 END_PROFILE(syscall_ftruncate);
954 return result;
955 }
956
957 static bool vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
/* [<][>][^][v][top][bottom][index][help] */
958 {
959 bool result;
960
961 START_PROFILE(syscall_fcntl_lock);
962 result = fcntl_lock(fsp->fh->fd, op, offset, count, type);
963 END_PROFILE(syscall_fcntl_lock);
964 return result;
965 }
966
967 static int vfswrap_kernel_flock(vfs_handle_struct *handle, files_struct *fsp,
/* [<][>][^][v][top][bottom][index][help] */
968 uint32 share_mode)
969 {
970 START_PROFILE(syscall_kernel_flock);
971 kernel_flock(fsp->fh->fd, share_mode);
972 END_PROFILE(syscall_kernel_flock);
973 return 0;
974 }
975
976 static bool vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
/* [<][>][^][v][top][bottom][index][help] */
977 {
978 bool result;
979
980 START_PROFILE(syscall_fcntl_getlock);
981 result = fcntl_getlock(fsp->fh->fd, poffset, pcount, ptype, ppid);
982 END_PROFILE(syscall_fcntl_getlock);
983 return result;
984 }
985
986 static int vfswrap_linux_setlease(vfs_handle_struct *handle, files_struct *fsp,
/* [<][>][^][v][top][bottom][index][help] */
987 int leasetype)
988 {
989 int result = -1;
990
991 START_PROFILE(syscall_linux_setlease);
992
993 #ifdef HAVE_KERNEL_OPLOCKS_LINUX
994 /* first set the signal handler */
995 if(linux_set_lease_sighandler(fsp->fh->fd) == -1) {
996 return -1;
997 }
998
999 result = linux_setlease(fsp->fh->fd, leasetype);
1000 #else
1001 errno = ENOSYS;
1002 #endif
1003 END_PROFILE(syscall_linux_setlease);
1004 return result;
1005 }
1006
1007 static int vfswrap_symlink(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
/* [<][>][^][v][top][bottom][index][help] */
1008 {
1009 int result;
1010
1011 START_PROFILE(syscall_symlink);
1012 result = symlink(oldpath, newpath);
1013 END_PROFILE(syscall_symlink);
1014 return result;
1015 }
1016
1017 static int vfswrap_readlink(vfs_handle_struct *handle, const char *path, char *buf, size_t bufsiz)
/* [<][>][^][v][top][bottom][index][help] */
1018 {
1019 int result;
1020
1021 START_PROFILE(syscall_readlink);
1022 result = readlink(path, buf, bufsiz);
1023 END_PROFILE(syscall_readlink);
1024 return result;
1025 }
1026
1027 static int vfswrap_link(vfs_handle_struct *handle, const char *oldpath, const char *newpath)
/* [<][>][^][v][top][bottom][index][help] */
1028 {
1029 int result;
1030
1031 START_PROFILE(syscall_link);
1032 result = link(oldpath, newpath);
1033 END_PROFILE(syscall_link);
1034 return result;
1035 }
1036
1037 static int vfswrap_mknod(vfs_handle_struct *handle, const char *pathname, mode_t mode, SMB_DEV_T dev)
/* [<][>][^][v][top][bottom][index][help] */
1038 {
1039 int result;
1040
1041 START_PROFILE(syscall_mknod);
1042 result = sys_mknod(pathname, mode, dev);
1043 END_PROFILE(syscall_mknod);
1044 return result;
1045 }
1046
1047 static char *vfswrap_realpath(vfs_handle_struct *handle, const char *path, char *resolved_path)
/* [<][>][^][v][top][bottom][index][help] */
1048 {
1049 char *result;
1050
1051 START_PROFILE(syscall_realpath);
1052 result = realpath(path, resolved_path);
1053 END_PROFILE(syscall_realpath);
1054 return result;
1055 }
1056
1057 static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle,
/* [<][>][^][v][top][bottom][index][help] */
1058 struct sys_notify_context *ctx,
1059 struct notify_entry *e,
1060 void (*callback)(struct sys_notify_context *ctx,
1061 void *private_data,
1062 struct notify_event *ev),
1063 void *private_data, void *handle)
1064 {
1065 /*
1066 * So far inotify is the only supported default notify mechanism. If
1067 * another platform like the the BSD's or a proprietary Unix comes
1068 * along and wants another default, we can play the same trick we
1069 * played with Posix ACLs.
1070 *
1071 * Until that is the case, hard-code inotify here.
1072 */
1073 #ifdef HAVE_INOTIFY
1074 if (lp_kernel_change_notify(ctx->conn->params)) {
1075 return inotify_watch(ctx, e, callback, private_data, handle);
1076 }
1077 #endif
1078 /*
1079 * Do nothing, leave everything to notify_internal.c
1080 */
1081 return NT_STATUS_OK;
1082 }
1083
1084 static int vfswrap_chflags(vfs_handle_struct *handle, const char *path, int flags)
/* [<][>][^][v][top][bottom][index][help] */
1085 {
1086 #ifdef HAVE_CHFLAGS
1087 return chflags(path, flags);
1088 #else
1089 errno = ENOSYS;
1090 return -1;
1091 #endif
1092 }
1093
1094 static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle,
/* [<][>][^][v][top][bottom][index][help] */
1095 SMB_STRUCT_STAT *sbuf)
1096 {
1097 struct file_id key;
1098
1099 /* the ZERO_STRUCT ensures padding doesn't break using the key as a
1100 * blob */
1101 ZERO_STRUCT(key);
1102
1103 key.devid = sbuf->st_dev;
1104 key.inode = sbuf->st_ino;
1105 /* key.extid is unused by default. */
1106
1107 return key;
1108 }
1109
1110 static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
/* [<][>][^][v][top][bottom][index][help] */
1111 struct files_struct *fsp,
1112 const char *fname,
1113 TALLOC_CTX *mem_ctx,
1114 unsigned int *pnum_streams,
1115 struct stream_struct **pstreams)
1116 {
1117 SMB_STRUCT_STAT sbuf;
1118 unsigned int num_streams = 0;
1119 struct stream_struct *streams = NULL;
1120 int ret;
1121
1122 if ((fsp != NULL) && (fsp->is_directory)) {
1123 /*
1124 * No default streams on directories
1125 */
1126 goto done;
1127 }
1128
1129 if ((fsp != NULL) && (fsp->fh->fd != -1)) {
1130 ret = SMB_VFS_FSTAT(fsp, &sbuf);
1131 }
1132 else {
1133 if (lp_posix_pathnames()) {
1134 ret = SMB_VFS_LSTAT(handle->conn, fname, &sbuf);
1135 } else {
1136 ret = SMB_VFS_STAT(handle->conn, fname, &sbuf);
1137 }
1138 }
1139
1140 if (ret == -1) {
1141 return map_nt_error_from_unix(errno);
1142 }
1143
1144 if (S_ISDIR(sbuf.st_mode)) {
1145 goto done;
1146 }
1147
1148 streams = talloc(mem_ctx, struct stream_struct);
1149
1150 if (streams == NULL) {
1151 return NT_STATUS_NO_MEMORY;
1152 }
1153
1154 streams->size = sbuf.st_size;
1155 streams->alloc_size = SMB_VFS_GET_ALLOC_SIZE(handle->conn, fsp, &sbuf);
1156
1157 streams->name = talloc_strdup(streams, "::$DATA");
1158 if (streams->name == NULL) {
1159 TALLOC_FREE(streams);
1160 return NT_STATUS_NO_MEMORY;
1161 }
1162
1163 num_streams = 1;
1164 done:
1165 *pnum_streams = num_streams;
1166 *pstreams = streams;
1167 return NT_STATUS_OK;
1168 }
1169
1170 static int vfswrap_get_real_filename(struct vfs_handle_struct *handle,
/* [<][>][^][v][top][bottom][index][help] */
1171 const char *path,
1172 const char *name,
1173 TALLOC_CTX *mem_ctx,
1174 char **found_name)
1175 {
1176 /*
1177 * Don't fall back to get_real_filename so callers can differentiate
1178 * between a full directory scan and an actual case-insensitive stat.
1179 */
1180 errno = EOPNOTSUPP;
1181 return -1;
1182 }
1183
1184 static NTSTATUS vfswrap_brl_lock_windows(struct vfs_handle_struct *handle,
/* [<][>][^][v][top][bottom][index][help] */
1185 struct byte_range_lock *br_lck,
1186 struct lock_struct *plock,
1187 bool blocking_lock,
1188 struct blocking_lock_record *blr)
1189 {
1190 SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1191
1192 /* Note: blr is not used in the default implementation. */
1193 return brl_lock_windows_default(br_lck, plock, blocking_lock);
1194 }
1195
1196 static bool vfswrap_brl_unlock_windows(struct vfs_handle_struct *handle,
/* [<][>][^][v][top][bottom][index][help] */
1197 struct messaging_context *msg_ctx,
1198 struct byte_range_lock *br_lck,
1199 const struct lock_struct *plock)
1200 {
1201 SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1202
1203 return brl_unlock_windows_default(msg_ctx, br_lck, plock);
1204 }
1205
1206 static bool vfswrap_brl_cancel_windows(struct vfs_handle_struct *handle,
/* [<][>][^][v][top][bottom][index][help] */
1207 struct byte_range_lock *br_lck,
1208 struct lock_struct *plock,
1209 struct blocking_lock_record *blr)
1210 {
1211 SMB_ASSERT(plock->lock_flav == WINDOWS_LOCK);
1212
1213 /* Note: blr is not used in the default implementation. */
1214 return brl_lock_cancel_default(br_lck, plock);
1215 }
1216
1217 static bool vfswrap_strict_lock(struct vfs_handle_struct *handle,
/* [<][>][^][v][top][bottom][index][help] */
1218 files_struct *fsp,
1219 struct lock_struct *plock)
1220 {
1221 SMB_ASSERT(plock->lock_type == READ_LOCK ||
1222 plock->lock_type == WRITE_LOCK);
1223
1224 return strict_lock_default(fsp, plock);
1225 }
1226
1227 static void vfswrap_strict_unlock(struct vfs_handle_struct *handle,
/* [<][>][^][v][top][bottom][index][help] */
1228 files_struct *fsp,
1229 struct lock_struct *plock)
1230 {
1231 SMB_ASSERT(plock->lock_type == READ_LOCK ||
1232 plock->lock_type == WRITE_LOCK);
1233
1234 strict_unlock_default(fsp, plock);
1235 }
1236
1237 /* NT ACL operations. */
1238
1239 static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle,
/* [<][>][^][v][top][bottom][index][help] */
1240 files_struct *fsp,
1241 uint32 security_info, SEC_DESC **ppdesc)
1242 {
1243 NTSTATUS result;
1244
1245 START_PROFILE(fget_nt_acl);
1246 result = posix_fget_nt_acl(fsp, security_info, ppdesc);
1247 END_PROFILE(fget_nt_acl);
1248 return result;
1249 }
1250
1251 static NTSTATUS vfswrap_get_nt_acl(vfs_handle_struct *handle,
/* [<][>][^][v][top][bottom][index][help] */
1252 const char *name,
1253 uint32 security_info, SEC_DESC **ppdesc)
1254 {
1255 NTSTATUS result;
1256
1257 START_PROFILE(get_nt_acl);
1258 result = posix_get_nt_acl(handle->conn, name, security_info, ppdesc);
1259 END_PROFILE(get_nt_acl);
1260 return result;
1261 }
1262
1263 static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, const SEC_DESC *psd)
/* [<][>][^][v][top][bottom][index][help] */
1264 {
1265 NTSTATUS result;
1266
1267 START_PROFILE(fset_nt_acl);
1268 result = set_nt_acl(fsp, security_info_sent, psd);
1269 END_PROFILE(fset_nt_acl);
1270 return result;
1271 }
1272
1273 static int vfswrap_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode)
/* [<][>][^][v][top][bottom][index][help] */
1274 {
1275 #ifdef HAVE_NO_ACL
1276 errno = ENOSYS;
1277 return -1;
1278 #else
1279 int result;
1280
1281 START_PROFILE(chmod_acl);
1282 result = chmod_acl(handle->conn, name, mode);
1283 END_PROFILE(chmod_acl);
1284 return result;
1285 #endif
1286 }
1287
1288 static int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t mode)
/* [<][>][^][v][top][bottom][index][help] */
1289 {
1290 #ifdef HAVE_NO_ACL
1291 errno = ENOSYS;
1292 return -1;
1293 #else
1294 int result;
1295
1296 START_PROFILE(fchmod_acl);
1297 result = fchmod_acl(fsp, mode);
1298 END_PROFILE(fchmod_acl);
1299 return result;
1300 #endif
1301 }
1302
1303 static int vfswrap_sys_acl_get_entry(vfs_handle_struct *handle, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p)
/* [<][>][^][v][top][bottom][index][help] */
1304 {
1305 return sys_acl_get_entry(theacl, entry_id, entry_p);
1306 }
1307
1308 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)
/* [<][>][^][v][top][bottom][index][help] */
1309 {
1310 return sys_acl_get_tag_type(entry_d, tag_type_p);
1311 }
1312
1313 static int vfswrap_sys_acl_get_permset(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p)
/* [<][>][^][v][top][bottom][index][help] */
1314 {
1315 return sys_acl_get_permset(entry_d, permset_p);
1316 }
1317
1318 static void * vfswrap_sys_acl_get_qualifier(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry_d)
/* [<][>][^][v][top][bottom][index][help] */
1319 {
1320 return sys_acl_get_qualifier(entry_d);
1321 }
1322
1323 static SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, SMB_ACL_TYPE_T type)
/* [<][>][^][v][top][bottom][index][help] */
1324 {
1325 return sys_acl_get_file(handle, path_p, type);
1326 }
1327
1328 static SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp)
/* [<][>][^][v][top][bottom][index][help] */
1329 {
1330 return sys_acl_get_fd(handle, fsp);
1331 }
1332
1333 static int vfswrap_sys_acl_clear_perms(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset)
/* [<][>][^][v][top][bottom][index][help] */
1334 {
1335 return sys_acl_clear_perms(permset);
1336 }
1337
1338 static int vfswrap_sys_acl_add_perm(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
/* [<][>][^][v][top][bottom][index][help] */
1339 {
1340 return sys_acl_add_perm(permset, perm);
1341 }
1342
1343 static char * vfswrap_sys_acl_to_text(vfs_handle_struct *handle, SMB_ACL_T theacl, ssize_t *plen)
/* [<][>][^][v][top][bottom][index][help] */
1344 {
1345 return sys_acl_to_text(theacl, plen);
1346 }
1347
1348 static SMB_ACL_T vfswrap_sys_acl_init(vfs_handle_struct *handle, int count)
/* [<][>][^][v][top][bottom][index][help] */
1349 {
1350 return sys_acl_init(count);
1351 }
1352
1353 static int vfswrap_sys_acl_create_entry(vfs_handle_struct *handle, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry)
/* [<][>][^][v][top][bottom][index][help] */
1354 {
1355 return sys_acl_create_entry(pacl, pentry);
1356 }
1357
1358 static int vfswrap_sys_acl_set_tag_type(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype)
/* [<][>][^][v][top][bottom][index][help] */
1359 {
1360 return sys_acl_set_tag_type(entry, tagtype);
1361 }
1362
1363 static int vfswrap_sys_acl_set_qualifier(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, void *qual)
/* [<][>][^][v][top][bottom][index][help] */
1364 {
1365 return sys_acl_set_qualifier(entry, qual);
1366 }
1367
1368 static int vfswrap_sys_acl_set_permset(vfs_handle_struct *handle, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset)
/* [<][>][^][v][top][bottom][index][help] */
1369 {
1370 return sys_acl_set_permset(entry, permset);
1371 }
1372
1373 static int vfswrap_sys_acl_valid(vfs_handle_struct *handle, SMB_ACL_T theacl )
/* [<][>][^][v][top][bottom][index][help] */
1374 {
1375 return sys_acl_valid(theacl );
1376 }
1377
1378 static int vfswrap_sys_acl_set_file(vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl)
/* [<][>][^][v][top][bottom][index][help] */
1379 {
1380 return sys_acl_set_file(handle, name, acltype, theacl);
1381 }
1382
1383 static int vfswrap_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_T theacl)
/* [<][>][^][v][top][bottom][index][help] */
1384 {
1385 return sys_acl_set_fd(handle, fsp, theacl);
1386 }
1387
1388 static int vfswrap_sys_acl_delete_def_file(vfs_handle_struct *handle, const char *path)
/* [<][>][^][v][top][bottom][index][help] */
1389 {
1390 return sys_acl_delete_def_file(handle, path);
1391 }
1392
1393 static int vfswrap_sys_acl_get_perm(vfs_handle_struct *handle, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm)
/* [<][>][^][v][top][bottom][index][help] */
1394 {
1395 return sys_acl_get_perm(permset, perm);
1396 }
1397
1398 static int vfswrap_sys_acl_free_text(vfs_handle_struct *handle, char *text)
/* [<][>][^][v][top][bottom][index][help] */
1399 {
1400 return sys_acl_free_text(text);
1401 }
1402
1403 static int vfswrap_sys_acl_free_acl(vfs_handle_struct *handle, SMB_ACL_T posix_acl)
/* [<][>][^][v][top][bottom][index][help] */
1404 {
1405 return sys_acl_free_acl(posix_acl);
1406 }
1407
1408 static int vfswrap_sys_acl_free_qualifier(vfs_handle_struct *handle, void *qualifier, SMB_ACL_TAG_T tagtype)
/* [<][>][^][v][top][bottom][index][help] */
1409 {
1410 return sys_acl_free_qualifier(qualifier, tagtype);
1411 }
1412
1413 /****************************************************************
1414 Extended attribute operations.
1415 *****************************************************************/
1416
1417 static ssize_t vfswrap_getxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
/* [<][>][^][v][top][bottom][index][help] */
1418 {
1419 return sys_getxattr(path, name, value, size);
1420 }
1421
1422 static ssize_t vfswrap_lgetxattr(struct vfs_handle_struct *handle,const char *path, const char *name, void *value, size_t size)
/* [<][>][^][v][top][bottom][index][help] */
1423 {
1424 return sys_lgetxattr(path, name, value, size);
1425 }
1426
1427 static ssize_t vfswrap_fgetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, void *value, size_t size)
/* [<][>][^][v][top][bottom][index][help] */
1428 {
1429 return sys_fgetxattr(fsp->fh->fd, name, value, size);
1430 }
1431
1432 static ssize_t vfswrap_listxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
/* [<][>][^][v][top][bottom][index][help] */
1433 {
1434 return sys_listxattr(path, list, size);
1435 }
1436
1437 ssize_t vfswrap_llistxattr(struct vfs_handle_struct *handle, const char *path, char *list, size_t size)
/* [<][>][^][v][top][bottom][index][help] */
1438 {
1439 return sys_llistxattr(path, list, size);
1440 }
1441
1442 ssize_t vfswrap_flistxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, char *list, size_t size)
/* [<][>][^][v][top][bottom][index][help] */
1443 {
1444 return sys_flistxattr(fsp->fh->fd, list, size);
1445 }
1446
1447 static int vfswrap_removexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
/* [<][>][^][v][top][bottom][index][help] */
1448 {
1449 return sys_removexattr(path, name);
1450 }
1451
1452 static int vfswrap_lremovexattr(struct vfs_handle_struct *handle, const char *path, const char *name)
/* [<][>][^][v][top][bottom][index][help] */
1453 {
1454 return sys_lremovexattr(path, name);
1455 }
1456
1457 static int vfswrap_fremovexattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name)
/* [<][>][^][v][top][bottom][index][help] */
1458 {
1459 return sys_fremovexattr(fsp->fh->fd, name);
1460 }
1461
1462 static int vfswrap_setxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
/* [<][>][^][v][top][bottom][index][help] */
1463 {
1464 return sys_setxattr(path, name, value, size, flags);
1465 }
1466
1467 static int vfswrap_lsetxattr(struct vfs_handle_struct *handle, const char *path, const char *name, const void *value, size_t size, int flags)
/* [<][>][^][v][top][bottom][index][help] */
1468 {
1469 return sys_lsetxattr(path, name, value, size, flags);
1470 }
1471
1472 static int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, const void *value, size_t size, int flags)
/* [<][>][^][v][top][bottom][index][help] */
1473 {
1474 return sys_fsetxattr(fsp->fh->fd, name, value, size, flags);
1475 }
1476
1477 static int vfswrap_aio_read(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
/* [<][>][^][v][top][bottom][index][help] */
1478 {
1479 int ret;
1480 /*
1481 * aio_read must be done as root, because in the glibc aio
1482 * implementation the helper thread needs to be able to send a signal
1483 * to the main thread, even when it has done a seteuid() to a
1484 * different user.
1485 */
1486 become_root();
1487 ret = sys_aio_read(aiocb);
1488 unbecome_root();
1489 return ret;
1490 }
1491
1492 static int vfswrap_aio_write(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
/* [<][>][^][v][top][bottom][index][help] */
1493 {
1494 int ret;
1495 /*
1496 * aio_write must be done as root, because in the glibc aio
1497 * implementation the helper thread needs to be able to send a signal
1498 * to the main thread, even when it has done a seteuid() to a
1499 * different user.
1500 */
1501 become_root();
1502 ret = sys_aio_write(aiocb);
1503 unbecome_root();
1504 return ret;
1505 }
1506
1507 static ssize_t vfswrap_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
/* [<][>][^][v][top][bottom][index][help] */
1508 {
1509 return sys_aio_return(aiocb);
1510 }
1511
1512 static int vfswrap_aio_cancel(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
/* [<][>][^][v][top][bottom][index][help] */
1513 {
1514 return sys_aio_cancel(fsp->fh->fd, aiocb);
1515 }
1516
1517 static int vfswrap_aio_error(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_STRUCT_AIOCB *aiocb)
/* [<][>][^][v][top][bottom][index][help] */
1518 {
1519 return sys_aio_error(aiocb);
1520 }
1521
1522 static int vfswrap_aio_fsync(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_STRUCT_AIOCB *aiocb)
/* [<][>][^][v][top][bottom][index][help] */
1523 {
1524 return sys_aio_fsync(op, aiocb);
1525 }
1526
1527 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)
/* [<][>][^][v][top][bottom][index][help] */
1528 {
1529 return sys_aio_suspend(aiocb, n, timeout);
1530 }
1531
1532 static bool vfswrap_aio_force(struct vfs_handle_struct *handle, struct files_struct *fsp)
/* [<][>][^][v][top][bottom][index][help] */
1533 {
1534 return false;
1535 }
1536
1537 static bool vfswrap_is_offline(struct vfs_handle_struct *handle, const char *path, SMB_STRUCT_STAT *sbuf)
/* [<][>][^][v][top][bottom][index][help] */
1538 {
1539 if (ISDOT(path) || ISDOTDOT(path)) {
1540 return false;
1541 }
1542
1543 if (!lp_dmapi_support(SNUM(handle->conn)) || !dmapi_have_session()) {
1544 #if defined(ENOTSUP)
1545 errno = ENOTSUP;
1546 #endif
1547 return false;
1548 }
1549
1550 return (dmapi_file_flags(path) & FILE_ATTRIBUTE_OFFLINE) != 0;
1551 }
1552
1553 static int vfswrap_set_offline(struct vfs_handle_struct *handle, const char *path)
/* [<][>][^][v][top][bottom][index][help] */
1554 {
1555 /* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */
1556 #if defined(ENOTSUP)
1557 errno = ENOTSUP;
1558 #endif
1559 return -1;
1560 }
1561
1562 static vfs_op_tuple vfs_default_ops[] = {
1563
1564 /* Disk operations */
1565
1566 {SMB_VFS_OP(vfswrap_connect), SMB_VFS_OP_CONNECT,
1567 SMB_VFS_LAYER_OPAQUE},
1568 {SMB_VFS_OP(vfswrap_disconnect), SMB_VFS_OP_DISCONNECT,
1569 SMB_VFS_LAYER_OPAQUE},
1570 {SMB_VFS_OP(vfswrap_disk_free), SMB_VFS_OP_DISK_FREE,
1571 SMB_VFS_LAYER_OPAQUE},
1572 {SMB_VFS_OP(vfswrap_get_quota), SMB_VFS_OP_GET_QUOTA,
1573 SMB_VFS_LAYER_OPAQUE},
1574 {SMB_VFS_OP(vfswrap_set_quota), SMB_VFS_OP_SET_QUOTA,
1575 SMB_VFS_LAYER_OPAQUE},
1576 {SMB_VFS_OP(vfswrap_get_shadow_copy_data), SMB_VFS_OP_GET_SHADOW_COPY_DATA,
1577 SMB_VFS_LAYER_OPAQUE},
1578 {SMB_VFS_OP(vfswrap_statvfs), SMB_VFS_OP_STATVFS,
1579 SMB_VFS_LAYER_OPAQUE},
1580 {SMB_VFS_OP(vfswrap_fs_capabilities), SMB_VFS_OP_FS_CAPABILITIES,
1581 SMB_VFS_LAYER_OPAQUE},
1582
1583 /* Directory operations */
1584
1585 {SMB_VFS_OP(vfswrap_opendir), SMB_VFS_OP_OPENDIR,
1586 SMB_VFS_LAYER_OPAQUE},
1587 {SMB_VFS_OP(vfswrap_readdir), SMB_VFS_OP_READDIR,
1588 SMB_VFS_LAYER_OPAQUE},
1589 {SMB_VFS_OP(vfswrap_seekdir), SMB_VFS_OP_SEEKDIR,
1590 SMB_VFS_LAYER_OPAQUE},
1591 {SMB_VFS_OP(vfswrap_telldir), SMB_VFS_OP_TELLDIR,
1592 SMB_VFS_LAYER_OPAQUE},
1593 {SMB_VFS_OP(vfswrap_rewinddir), SMB_VFS_OP_REWINDDIR,
1594 SMB_VFS_LAYER_OPAQUE},
1595 {SMB_VFS_OP(vfswrap_mkdir), SMB_VFS_OP_MKDIR,
1596 SMB_VFS_LAYER_OPAQUE},
1597 {SMB_VFS_OP(vfswrap_rmdir), SMB_VFS_OP_RMDIR,
1598 SMB_VFS_LAYER_OPAQUE},
1599 {SMB_VFS_OP(vfswrap_closedir), SMB_VFS_OP_CLOSEDIR,
1600 SMB_VFS_LAYER_OPAQUE},
1601 {SMB_VFS_OP(vfswrap_init_search_op), SMB_VFS_OP_INIT_SEARCH_OP,
1602 SMB_VFS_LAYER_OPAQUE},
1603
1604 /* File operations */
1605
1606 {SMB_VFS_OP(vfswrap_open), SMB_VFS_OP_OPEN,
1607 SMB_VFS_LAYER_OPAQUE},
1608 {SMB_VFS_OP(vfswrap_create_file), SMB_VFS_OP_CREATE_FILE,
1609 SMB_VFS_LAYER_OPAQUE},
1610 {SMB_VFS_OP(vfswrap_close), SMB_VFS_OP_CLOSE,
1611 SMB_VFS_LAYER_OPAQUE},
1612 {SMB_VFS_OP(vfswrap_read), SMB_VFS_OP_READ,
1613 SMB_VFS_LAYER_OPAQUE},
1614 {SMB_VFS_OP(vfswrap_pread), SMB_VFS_OP_PREAD,
1615 SMB_VFS_LAYER_OPAQUE},
1616 {SMB_VFS_OP(vfswrap_write), SMB_VFS_OP_WRITE,
1617 SMB_VFS_LAYER_OPAQUE},
1618 {SMB_VFS_OP(vfswrap_pwrite), SMB_VFS_OP_PWRITE,
1619 SMB_VFS_LAYER_OPAQUE},
1620 {SMB_VFS_OP(vfswrap_lseek), SMB_VFS_OP_LSEEK,
1621 SMB_VFS_LAYER_OPAQUE},
1622 {SMB_VFS_OP(vfswrap_sendfile), SMB_VFS_OP_SENDFILE,
1623 SMB_VFS_LAYER_OPAQUE},
1624 {SMB_VFS_OP(vfswrap_recvfile), SMB_VFS_OP_RECVFILE,
1625 SMB_VFS_LAYER_OPAQUE},
1626 {SMB_VFS_OP(vfswrap_rename), SMB_VFS_OP_RENAME,
1627 SMB_VFS_LAYER_OPAQUE},
1628 {SMB_VFS_OP(vfswrap_fsync), SMB_VFS_OP_FSYNC,
1629 SMB_VFS_LAYER_OPAQUE},
1630 {SMB_VFS_OP(vfswrap_stat), SMB_VFS_OP_STAT,
1631 SMB_VFS_LAYER_OPAQUE},
1632 {SMB_VFS_OP(vfswrap_fstat), SMB_VFS_OP_FSTAT,
1633 SMB_VFS_LAYER_OPAQUE},
1634 {SMB_VFS_OP(vfswrap_lstat), SMB_VFS_OP_LSTAT,
1635 SMB_VFS_LAYER_OPAQUE},
1636 {SMB_VFS_OP(vfswrap_get_alloc_size), SMB_VFS_OP_GET_ALLOC_SIZE,
1637 SMB_VFS_LAYER_OPAQUE},
1638 {SMB_VFS_OP(vfswrap_unlink), SMB_VFS_OP_UNLINK,
1639 SMB_VFS_LAYER_OPAQUE},
1640 {SMB_VFS_OP(vfswrap_chmod), SMB_VFS_OP_CHMOD,
1641 SMB_VFS_LAYER_OPAQUE},
1642 {SMB_VFS_OP(vfswrap_fchmod), SMB_VFS_OP_FCHMOD,
1643 SMB_VFS_LAYER_OPAQUE},
1644 {SMB_VFS_OP(vfswrap_chown), SMB_VFS_OP_CHOWN,
1645 SMB_VFS_LAYER_OPAQUE},
1646 {SMB_VFS_OP(vfswrap_fchown), SMB_VFS_OP_FCHOWN,
1647 SMB_VFS_LAYER_OPAQUE},
1648 {SMB_VFS_OP(vfswrap_lchown), SMB_VFS_OP_LCHOWN,
1649 SMB_VFS_LAYER_OPAQUE},
1650 {SMB_VFS_OP(vfswrap_chdir), SMB_VFS_OP_CHDIR,
1651 SMB_VFS_LAYER_OPAQUE},
1652 {SMB_VFS_OP(vfswrap_getwd), SMB_VFS_OP_GETWD,
1653 SMB_VFS_LAYER_OPAQUE},
1654 {SMB_VFS_OP(vfswrap_ntimes), SMB_VFS_OP_NTIMES,
1655 SMB_VFS_LAYER_OPAQUE},
1656 {SMB_VFS_OP(vfswrap_ftruncate), SMB_VFS_OP_FTRUNCATE,
1657 SMB_VFS_LAYER_OPAQUE},
1658 {SMB_VFS_OP(vfswrap_lock), SMB_VFS_OP_LOCK,
1659 SMB_VFS_LAYER_OPAQUE},
1660 {SMB_VFS_OP(vfswrap_kernel_flock), SMB_VFS_OP_KERNEL_FLOCK,
1661 SMB_VFS_LAYER_OPAQUE},
1662 {SMB_VFS_OP(vfswrap_linux_setlease), SMB_VFS_OP_LINUX_SETLEASE,
1663 SMB_VFS_LAYER_OPAQUE},
1664 {SMB_VFS_OP(vfswrap_getlock), SMB_VFS_OP_GETLOCK,
1665 SMB_VFS_LAYER_OPAQUE},
1666 {SMB_VFS_OP(vfswrap_symlink), SMB_VFS_OP_SYMLINK,
1667 SMB_VFS_LAYER_OPAQUE},
1668 {SMB_VFS_OP(vfswrap_readlink), SMB_VFS_OP_READLINK,
1669 SMB_VFS_LAYER_OPAQUE},
1670 {SMB_VFS_OP(vfswrap_link), SMB_VFS_OP_LINK,
1671 SMB_VFS_LAYER_OPAQUE},
1672 {SMB_VFS_OP(vfswrap_mknod), SMB_VFS_OP_MKNOD,
1673 SMB_VFS_LAYER_OPAQUE},
1674 {SMB_VFS_OP(vfswrap_realpath), SMB_VFS_OP_REALPATH,
1675 SMB_VFS_LAYER_OPAQUE},
1676 {SMB_VFS_OP(vfswrap_notify_watch), SMB_VFS_OP_NOTIFY_WATCH,
1677 SMB_VFS_LAYER_OPAQUE},
1678 {SMB_VFS_OP(vfswrap_chflags), SMB_VFS_OP_CHFLAGS,
1679 SMB_VFS_LAYER_OPAQUE},
1680 {SMB_VFS_OP(vfswrap_file_id_create), SMB_VFS_OP_FILE_ID_CREATE,
1681 SMB_VFS_LAYER_OPAQUE},
1682 {SMB_VFS_OP(vfswrap_streaminfo), SMB_VFS_OP_STREAMINFO,
1683 SMB_VFS_LAYER_OPAQUE},
1684 {SMB_VFS_OP(vfswrap_get_real_filename), SMB_VFS_OP_GET_REAL_FILENAME,
1685 SMB_VFS_LAYER_OPAQUE},
1686 {SMB_VFS_OP(vfswrap_brl_lock_windows), SMB_VFS_OP_BRL_LOCK_WINDOWS,
1687 SMB_VFS_LAYER_OPAQUE},
1688 {SMB_VFS_OP(vfswrap_brl_unlock_windows),SMB_VFS_OP_BRL_UNLOCK_WINDOWS,
1689 SMB_VFS_LAYER_OPAQUE},
1690 {SMB_VFS_OP(vfswrap_brl_cancel_windows),SMB_VFS_OP_BRL_CANCEL_WINDOWS,
1691 SMB_VFS_LAYER_OPAQUE},
1692 {SMB_VFS_OP(vfswrap_strict_lock), SMB_VFS_OP_STRICT_LOCK,
1693 SMB_VFS_LAYER_OPAQUE},
1694 {SMB_VFS_OP(vfswrap_strict_unlock), SMB_VFS_OP_STRICT_UNLOCK,
1695 SMB_VFS_LAYER_OPAQUE},
1696
1697 /* NT ACL operations. */
1698
1699 {SMB_VFS_OP(vfswrap_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL,
1700 SMB_VFS_LAYER_OPAQUE},
1701 {SMB_VFS_OP(vfswrap_get_nt_acl), SMB_VFS_OP_GET_NT_ACL,
1702 SMB_VFS_LAYER_OPAQUE},
1703 {SMB_VFS_OP(vfswrap_fset_nt_acl), SMB_VFS_OP_FSET_NT_ACL,
1704 SMB_VFS_LAYER_OPAQUE},
1705
1706 /* POSIX ACL operations. */
1707
1708 {SMB_VFS_OP(vfswrap_chmod_acl), SMB_VFS_OP_CHMOD_ACL,
1709 SMB_VFS_LAYER_OPAQUE},
1710 {SMB_VFS_OP(vfswrap_fchmod_acl), SMB_VFS_OP_FCHMOD_ACL,
1711 SMB_VFS_LAYER_OPAQUE},
1712 {SMB_VFS_OP(vfswrap_sys_acl_get_entry), SMB_VFS_OP_SYS_ACL_GET_ENTRY,
1713 SMB_VFS_LAYER_OPAQUE},
1714 {SMB_VFS_OP(vfswrap_sys_acl_get_tag_type), SMB_VFS_OP_SYS_ACL_GET_TAG_TYPE,
1715 SMB_VFS_LAYER_OPAQUE},
1716 {SMB_VFS_OP(vfswrap_sys_acl_get_permset), SMB_VFS_OP_SYS_ACL_GET_PERMSET,
1717 SMB_VFS_LAYER_OPAQUE},
1718 {SMB_VFS_OP(vfswrap_sys_acl_get_qualifier), SMB_VFS_OP_SYS_ACL_GET_QUALIFIER,
1719 SMB_VFS_LAYER_OPAQUE},
1720 {SMB_VFS_OP(vfswrap_sys_acl_get_file), SMB_VFS_OP_SYS_ACL_GET_FILE,
1721 SMB_VFS_LAYER_OPAQUE},
1722 {SMB_VFS_OP(vfswrap_sys_acl_get_fd), SMB_VFS_OP_SYS_ACL_GET_FD,
1723 SMB_VFS_LAYER_OPAQUE},
1724 {SMB_VFS_OP(vfswrap_sys_acl_clear_perms), SMB_VFS_OP_SYS_ACL_CLEAR_PERMS,
1725 SMB_VFS_LAYER_OPAQUE},
1726 {SMB_VFS_OP(vfswrap_sys_acl_add_perm), SMB_VFS_OP_SYS_ACL_ADD_PERM,
1727 SMB_VFS_LAYER_OPAQUE},
1728 {SMB_VFS_OP(vfswrap_sys_acl_to_text), SMB_VFS_OP_SYS_ACL_TO_TEXT,
1729 SMB_VFS_LAYER_OPAQUE},
1730 {SMB_VFS_OP(vfswrap_sys_acl_init), SMB_VFS_OP_SYS_ACL_INIT,
1731 SMB_VFS_LAYER_OPAQUE},
1732 {SMB_VFS_OP(vfswrap_sys_acl_create_entry), SMB_VFS_OP_SYS_ACL_CREATE_ENTRY,
1733 SMB_VFS_LAYER_OPAQUE},
1734 {SMB_VFS_OP(vfswrap_sys_acl_set_tag_type), SMB_VFS_OP_SYS_ACL_SET_TAG_TYPE,
1735 SMB_VFS_LAYER_OPAQUE},
1736 {SMB_VFS_OP(vfswrap_sys_acl_set_qualifier), SMB_VFS_OP_SYS_ACL_SET_QUALIFIER,
1737 SMB_VFS_LAYER_OPAQUE},
1738 {SMB_VFS_OP(vfswrap_sys_acl_set_permset), SMB_VFS_OP_SYS_ACL_SET_PERMSET,
1739 SMB_VFS_LAYER_OPAQUE},
1740 {SMB_VFS_OP(vfswrap_sys_acl_valid), SMB_VFS_OP_SYS_ACL_VALID,
1741 SMB_VFS_LAYER_OPAQUE},
1742 {SMB_VFS_OP(vfswrap_sys_acl_set_file), SMB_VFS_OP_SYS_ACL_SET_FILE,
1743 SMB_VFS_LAYER_OPAQUE},
1744 {SMB_VFS_OP(vfswrap_sys_acl_set_fd), SMB_VFS_OP_SYS_ACL_SET_FD,
1745 SMB_VFS_LAYER_OPAQUE},
1746 {SMB_VFS_OP(vfswrap_sys_acl_delete_def_file), SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE,
1747 SMB_VFS_LAYER_OPAQUE},
1748 {SMB_VFS_OP(vfswrap_sys_acl_get_perm), SMB_VFS_OP_SYS_ACL_GET_PERM,
1749 SMB_VFS_LAYER_OPAQUE},
1750 {SMB_VFS_OP(vfswrap_sys_acl_free_text), SMB_VFS_OP_SYS_ACL_FREE_TEXT,
1751 SMB_VFS_LAYER_OPAQUE},
1752 {SMB_VFS_OP(vfswrap_sys_acl_free_acl), SMB_VFS_OP_SYS_ACL_FREE_ACL,
1753 SMB_VFS_LAYER_OPAQUE},
1754 {SMB_VFS_OP(vfswrap_sys_acl_free_qualifier), SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER,
1755 SMB_VFS_LAYER_OPAQUE},
1756
1757 /* EA operations. */
1758
1759 {SMB_VFS_OP(vfswrap_getxattr), SMB_VFS_OP_GETXATTR,
1760 SMB_VFS_LAYER_OPAQUE},
1761 {SMB_VFS_OP(vfswrap_lgetxattr), SMB_VFS_OP_LGETXATTR,
1762 SMB_VFS_LAYER_OPAQUE},
1763 {SMB_VFS_OP(vfswrap_fgetxattr), SMB_VFS_OP_FGETXATTR,
1764 SMB_VFS_LAYER_OPAQUE},
1765 {SMB_VFS_OP(vfswrap_listxattr), SMB_VFS_OP_LISTXATTR,
1766 SMB_VFS_LAYER_OPAQUE},
1767 {SMB_VFS_OP(vfswrap_llistxattr), SMB_VFS_OP_LLISTXATTR,
1768 SMB_VFS_LAYER_OPAQUE},
1769 {SMB_VFS_OP(vfswrap_flistxattr), SMB_VFS_OP_FLISTXATTR,
1770 SMB_VFS_LAYER_OPAQUE},
1771 {SMB_VFS_OP(vfswrap_removexattr), SMB_VFS_OP_REMOVEXATTR,
1772 SMB_VFS_LAYER_OPAQUE},
1773 {SMB_VFS_OP(vfswrap_lremovexattr), SMB_VFS_OP_LREMOVEXATTR,
1774 SMB_VFS_LAYER_OPAQUE},
1775 {SMB_VFS_OP(vfswrap_fremovexattr), SMB_VFS_OP_FREMOVEXATTR,
1776 SMB_VFS_LAYER_OPAQUE},
1777 {SMB_VFS_OP(vfswrap_setxattr), SMB_VFS_OP_SETXATTR,
1778 SMB_VFS_LAYER_OPAQUE},
1779 {SMB_VFS_OP(vfswrap_lsetxattr), SMB_VFS_OP_LSETXATTR,
1780 SMB_VFS_LAYER_OPAQUE},
1781 {SMB_VFS_OP(vfswrap_fsetxattr), SMB_VFS_OP_FSETXATTR,
1782 SMB_VFS_LAYER_OPAQUE},
1783
1784 {SMB_VFS_OP(vfswrap_aio_read), SMB_VFS_OP_AIO_READ,
1785 SMB_VFS_LAYER_OPAQUE},
1786 {SMB_VFS_OP(vfswrap_aio_write), SMB_VFS_OP_AIO_WRITE,
1787 SMB_VFS_LAYER_OPAQUE},
1788 {SMB_VFS_OP(vfswrap_aio_return), SMB_VFS_OP_AIO_RETURN,
1789 SMB_VFS_LAYER_OPAQUE},
1790 {SMB_VFS_OP(vfswrap_aio_cancel), SMB_VFS_OP_AIO_CANCEL,
1791 SMB_VFS_LAYER_OPAQUE},
1792 {SMB_VFS_OP(vfswrap_aio_error), SMB_VFS_OP_AIO_ERROR,
1793 SMB_VFS_LAYER_OPAQUE},
1794 {SMB_VFS_OP(vfswrap_aio_fsync), SMB_VFS_OP_AIO_FSYNC,
1795 SMB_VFS_LAYER_OPAQUE},
1796 {SMB_VFS_OP(vfswrap_aio_suspend),SMB_VFS_OP_AIO_SUSPEND,
1797 SMB_VFS_LAYER_OPAQUE},
1798
1799 {SMB_VFS_OP(vfswrap_aio_force), SMB_VFS_OP_AIO_FORCE,
1800 SMB_VFS_LAYER_OPAQUE},
1801
1802 {SMB_VFS_OP(vfswrap_is_offline),SMB_VFS_OP_IS_OFFLINE,
1803 SMB_VFS_LAYER_OPAQUE},
1804 {SMB_VFS_OP(vfswrap_set_offline),SMB_VFS_OP_SET_OFFLINE,
1805 SMB_VFS_LAYER_OPAQUE},
1806
1807 /* Finish VFS operations definition */
1808
1809 {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP,
1810 SMB_VFS_LAYER_NOOP}
1811 };
1812
1813 NTSTATUS vfs_default_init(void);
1814 NTSTATUS vfs_default_init(void)
/* [<][>][^][v][top][bottom][index][help] */
1815 {
1816 unsigned int needed = SMB_VFS_OP_LAST + 1; /* convert from index to count */
1817
1818 if (ARRAY_SIZE(vfs_default_ops) != needed) {
1819 DEBUG(0, ("%s: %u ops registered, but %u ops are required\n",
1820 DEFAULT_VFS_MODULE_NAME, (unsigned int)ARRAY_SIZE(vfs_default_ops), needed));
1821 smb_panic("operation(s) missing from default VFS module");
1822 }
1823
1824 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
1825 DEFAULT_VFS_MODULE_NAME, vfs_default_ops);
1826 }