~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/modules/vfs_default.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

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