return -1;
}
-static int skel_open(vfs_handle_struct *handle, struct smb_filename *smb_fname,
- files_struct *fsp, int flags, mode_t mode)
-{
- errno = ENOSYS;
- return -1;
-}
-
static int skel_openat(struct vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
/* File operations */
- .open_fn = skel_open,
.openat_fn = skel_openat,
.create_file_fn = skel_create_file,
.close_fn = skel_close_fn,
return SMB_VFS_NEXT_CLOSEDIR(handle, dir);
}
-static int skel_open(vfs_handle_struct *handle, struct smb_filename *smb_fname,
- files_struct *fsp, int flags, mode_t mode)
-{
- return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
-}
-
static int skel_openat(struct vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
/* File operations */
- .open_fn = skel_open,
.openat_fn = skel_openat,
.create_file_fn = skel_create_file,
.close_fn = skel_close_fn,
* Version 43 - Add dirfsp to struct files_struct
* Version 43 - Add dirfsp args to SMB_VFS_CREATE_FILE()
* Version 43 - Add SMB_VFS_OPENAT()
+ * Version 43 - Remove SMB_VFS_OPEN()
*/
#define SMB_VFS_INTERFACE_VERSION 43
/* File operations */
- int (*open_fn)(struct vfs_handle_struct *handle,
- struct smb_filename *smb_fname, files_struct *fsp,
- int flags, mode_t mode);
int (*openat_fn)(struct vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
mode_t mode);
int smb_vfs_call_closedir(struct vfs_handle_struct *handle,
DIR *dir);
-int smb_vfs_call_open(struct vfs_handle_struct *handle,
- struct smb_filename *smb_fname, struct files_struct *fsp,
- int flags, mode_t mode);
int smb_vfs_call_openat(struct vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
smb_vfs_call_closedir((handle)->next, (dir))
/* File operations */
-#define SMB_VFS_OPEN(conn, fname, fsp, flags, mode) \
- smb_vfs_call_open((conn)->vfs_handles, (fname), (fsp), (flags), (mode))
-#define SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode) \
- smb_vfs_call_open((handle)->next, (fname), (fsp), (flags), (mode))
-
#define SMB_VFS_OPENAT(conn, dirfsp, smb_fname, fsp, flags, mode) \
smb_vfs_call_openat((conn)->vfs_handles, (dirfsp), (smb_fname), (fsp), (flags), (mode))
#define SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, flags, mode) \
opens to prevent any race conditions.
*****************************************************************/
-static int aio_pthread_open_fn(vfs_handle_struct *handle,
- struct smb_filename *smb_fname,
- files_struct *fsp,
- int flags,
- mode_t mode)
-{
- int my_errno = 0;
- int fd = -1;
- bool aio_allow_open = lp_parm_bool(
- SNUM(handle->conn), "aio_pthread", "aio open", false);
- struct files_struct *fspcwd = NULL;
- NTSTATUS status;
-
- if (smb_fname->stream_name) {
- /* Don't handle stream opens. */
- errno = ENOENT;
- return -1;
- }
-
- if (!aio_allow_open) {
- /* aio opens turned off. */
- return open(smb_fname->base_name, flags, mode);
- }
-
- if (!(flags & O_CREAT)) {
- /* Only creates matter. */
- return open(smb_fname->base_name, flags, mode);
- }
-
- if (!(flags & O_EXCL)) {
- /* Only creates with O_EXCL matter. */
- return open(smb_fname->base_name, flags, mode);
- }
-
- /*
- * See if this is a reentrant call - i.e. is this a
- * restart of an existing open that just completed.
- */
-
- if (find_completed_open(fsp,
- &fd,
- &my_errno)) {
- errno = my_errno;
- return fd;
- }
-
- status = vfs_at_fspcwd(talloc_tos(), handle->conn, &fspcwd);
- if (!NT_STATUS_IS_OK(status)) {
- return -1;
- }
-
- /* Ok, it's a create exclusive call - pass it to a thread helper. */
- fd = open_async(fspcwd, smb_fname, fsp, flags, mode);
- TALLOC_FREE(fspcwd);
- return fd;
-}
-
static int aio_pthread_openat_fn(vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
static struct vfs_fn_pointers vfs_aio_pthread_fns = {
#if defined(HAVE_OPENAT) && defined(HAVE_LINUX_THREAD_CREDENTIALS)
- .open_fn = aio_pthread_open_fn,
.openat_fn = aio_pthread_openat_fn,
#endif
};
return result;
}
-static int audit_open(vfs_handle_struct *handle,
- struct smb_filename *smb_fname, files_struct *fsp,
- int flags, mode_t mode)
-{
- int result;
-
- result = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
-
- syslog(audit_syslog_priority(handle), "open %s (fd %d) %s%s%s\n",
- smb_fname->base_name, result,
- ((flags & O_WRONLY) || (flags & O_RDWR)) ? "for writing " : "",
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
-
- return result;
-}
-
static int audit_openat(vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
.connect_fn = audit_connect,
.disconnect_fn = audit_disconnect,
.mkdirat_fn = audit_mkdirat,
- .open_fn = audit_open,
.openat_fn = audit_openat,
.close_fn = audit_close,
.renameat_fn = audit_renameat,
mode);
}
-static int cap_open(vfs_handle_struct *handle, struct smb_filename *smb_fname,
- files_struct *fsp, int flags, mode_t mode)
-{
- char *cappath;
- char *tmp_base_name = NULL;
- int ret;
-
- cappath = capencode(talloc_tos(), smb_fname->base_name);
-
- if (!cappath) {
- errno = ENOMEM;
- return -1;
- }
-
- tmp_base_name = smb_fname->base_name;
- smb_fname->base_name = cappath;
-
- DEBUG(3,("cap: cap_open for %s\n", smb_fname_str_dbg(smb_fname)));
- ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
-
- smb_fname->base_name = tmp_base_name;
- TALLOC_FREE(cappath);
-
- return ret;
-}
-
static int cap_openat(vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname_in,
.get_quota_fn = cap_get_quota,
.readdir_fn = cap_readdir,
.mkdirat_fn = cap_mkdirat,
- .open_fn = cap_open,
.openat_fn = cap_openat,
.renameat_fn = cap_renameat,
.stat_fn = cap_stat,
return;
}
-static int catia_open(vfs_handle_struct *handle,
- struct smb_filename *smb_fname,
- files_struct *fsp,
- int flags,
- mode_t mode)
-{
- struct catia_cache *cc = NULL;
- char *orig_smb_fname = smb_fname->base_name;
- char *mapped_smb_fname = NULL;
- NTSTATUS status;
- int ret;
-
- status = catia_string_replace_allocate(handle->conn,
- smb_fname->base_name,
- &mapped_smb_fname,
- vfs_translate_to_unix);
- if (!NT_STATUS_IS_OK(status)) {
- return -1;
- }
-
- ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
- if (ret != 0) {
- TALLOC_FREE(mapped_smb_fname);
- return ret;
- }
-
- smb_fname->base_name = mapped_smb_fname;
- ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- smb_fname->base_name = orig_smb_fname;
-
- TALLOC_FREE(mapped_smb_fname);
- CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
-
- return ret;
-}
-
static int catia_openat(vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname_in,
.readdir_attr_fn = catia_readdir_attr,
/* File operations */
- .open_fn = catia_open,
.openat_fn = catia_openat,
.pread_fn = catia_pread,
.pread_send_fn = catia_pread_send,
/* File operations */
-static int cephwrap_open(struct vfs_handle_struct *handle,
- struct smb_filename *smb_fname,
- files_struct *fsp, int flags, mode_t mode)
-{
- int result = -ENOENT;
- DBG_DEBUG("[CEPH] open(%p, %s, %p, %d, %d)\n", handle,
- smb_fname_str_dbg(smb_fname), fsp, flags, mode);
-
- if (smb_fname->stream_name) {
- goto out;
- }
-
- result = ceph_open(handle->data, smb_fname->base_name, flags, mode);
-out:
- DBG_DEBUG("[CEPH] open(...) = %d\n", result);
- WRAP_RETURN(result);
-}
-
static int cephwrap_openat(struct vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
.create_dfs_pathat_fn = cephwrap_create_dfs_pathat,
.read_dfs_pathat_fn = cephwrap_read_dfs_pathat,
- .open_fn = cephwrap_open,
.openat_fn = cephwrap_openat,
.close_fn = cephwrap_close,
.pread_fn = cephwrap_pread,
return ret;
}
-static int ceph_snap_gmt_open(vfs_handle_struct *handle,
- struct smb_filename *smb_fname, files_struct *fsp,
- int flags, mode_t mode)
-{
- time_t timestamp = 0;
- char stripped[PATH_MAX + 1];
- char conv[PATH_MAX + 1];
- char *tmp;
- int ret;
-
- ret = ceph_snap_gmt_strip_snapshot(handle,
- smb_fname,
- ×tamp, stripped, sizeof(stripped));
- if (ret < 0) {
- errno = -ret;
- return -1;
- }
- if (timestamp == 0) {
- return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- }
-
- ret = ceph_snap_gmt_convert(handle, stripped,
- timestamp, conv, sizeof(conv));
- if (ret < 0) {
- errno = -ret;
- return -1;
- }
- tmp = smb_fname->base_name;
- smb_fname->base_name = conv;
-
- ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- smb_fname->base_name = tmp;
- return ret;
-}
-
static int ceph_snap_gmt_openat(vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname_in,
.symlinkat_fn = ceph_snap_gmt_symlinkat,
.stat_fn = ceph_snap_gmt_stat,
.lstat_fn = ceph_snap_gmt_lstat,
- .open_fn = ceph_snap_gmt_open,
.openat_fn = ceph_snap_gmt_openat,
.unlinkat_fn = ceph_snap_gmt_unlinkat,
.chmod_fn = ceph_snap_gmt_chmod,
return 0;
}
-static int commit_open(
- vfs_handle_struct * handle,
- struct smb_filename *smb_fname,
- files_struct * fsp,
- int flags,
- mode_t mode)
-{
- off_t dthresh;
- const char *eof_mode;
- struct commit_info *c = NULL;
- int fd;
-
- /* Don't bother with read-only files. */
- if ((flags & O_ACCMODE) == O_RDONLY) {
- return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- }
-
- /* Read and check module configuration */
- dthresh = conv_str_size(lp_parm_const_string(SNUM(handle->conn),
- MODULE, "dthresh", NULL));
-
- eof_mode = lp_parm_const_string(SNUM(handle->conn),
- MODULE, "eof mode", "none");
-
- if (dthresh > 0 || !strequal(eof_mode, "none")) {
- c = VFS_ADD_FSP_EXTENSION(
- handle, fsp, struct commit_info, NULL);
- /* Process main tunables */
- if (c) {
- c->dthresh = dthresh;
- c->dbytes = 0;
- c->on_eof = EOF_NONE;
- c->eof = 0;
- }
- }
- /* Process eof_mode tunable */
- if (c) {
- if (strequal(eof_mode, "hinted")) {
- c->on_eof = EOF_HINTED;
- } else if (strequal(eof_mode, "growth")) {
- c->on_eof = EOF_GROWTH;
- }
- }
-
- fd = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- if (fd == -1) {
- VFS_REMOVE_FSP_EXTENSION(handle, fsp);
- return fd;
- }
-
- /* EOF commit modes require us to know the initial file size. */
- if (c && (c->on_eof != EOF_NONE)) {
- SMB_STRUCT_STAT st;
- /*
- * Setting the fd of the FSP is a hack
- * but also practiced elsewhere -
- * needed for calling the VFS.
- */
- fsp->fh->fd = fd;
- if (SMB_VFS_FSTAT(fsp, &st) == -1) {
- int saved_errno = errno;
- SMB_VFS_CLOSE(fsp);
- errno = saved_errno;
- return -1;
- }
- c->eof = st.st_ex_size;
- }
-
- return fd;
-}
-
static int commit_openat(struct vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
}
static struct vfs_fn_pointers vfs_commit_fns = {
- .open_fn = commit_open,
.openat_fn = commit_openat,
.close_fn = commit_close,
.pwrite_fn = commit_pwrite,
/* File operations */
-static int vfswrap_open(vfs_handle_struct *handle,
- struct smb_filename *smb_fname,
- files_struct *fsp, int flags, mode_t mode)
-{
- int result = -1;
-
- START_PROFILE(syscall_open);
-
- if (is_named_stream(smb_fname)) {
- errno = ENOENT;
- goto out;
- }
-
- result = open(smb_fname->base_name, flags, mode);
- out:
- END_PROFILE(syscall_open);
- return result;
-}
-
static int vfswrap_openat(vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
/* File operations */
- .open_fn = vfswrap_open,
.openat_fn = vfswrap_openat,
.create_file_fn = vfswrap_create_file,
.close_fn = vfswrap_close,
return SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
}
-static int vfs_error_inject_open(
- struct vfs_handle_struct *handle,
- struct smb_filename *smb_fname,
- files_struct *fsp,
- int flags,
- mode_t mode)
-{
- int error = inject_unix_error("open", handle);
- if (error != 0) {
- errno = error;
- return -1;
- }
- return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
-}
-
static int vfs_error_inject_openat(struct vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
static struct vfs_fn_pointers vfs_error_inject_fns = {
.chdir_fn = vfs_error_inject_chdir,
.pwrite_fn = vfs_error_inject_pwrite,
- .open_fn = vfs_error_inject_open,
.openat_fn = vfs_error_inject_openat,
};
return result;
}
-static int audit_open(vfs_handle_struct *handle,
- struct smb_filename *smb_fname, files_struct *fsp,
- int flags, mode_t mode)
-{
- int result;
-
- result = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
-
- if (lp_syslog() > 0) {
- syslog(audit_syslog_priority(handle), "open %s (fd %d) %s%s%s\n",
- smb_fname->base_name, result,
- ((flags & O_WRONLY) || (flags & O_RDWR)) ? "for writing " : "",
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : "");
- }
- DEBUG(2, ("vfs_extd_audit: open %s %s %s\n",
- smb_fname_str_dbg(smb_fname),
- (result < 0) ? "failed: " : "",
- (result < 0) ? strerror(errno) : ""));
-
- return result;
-}
-
static int audit_openat(vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
.connect_fn = audit_connect,
.disconnect_fn = audit_disconnect,
.mkdirat_fn = audit_mkdirat,
- .open_fn = audit_open,
.openat_fn = audit_openat,
.close_fn = audit_close,
.renameat_fn = audit_renameat,
return fd;
}
-static int fruit_open(vfs_handle_struct *handle,
- struct smb_filename *smb_fname,
- files_struct *fsp, int flags, mode_t mode)
-{
- struct files_struct *fspcwd = NULL;
- int saved_errno = 0;
- int fd;
- NTSTATUS status;
-
- DBG_DEBUG("Path [%s]\n", smb_fname_str_dbg(smb_fname));
-
- if (!is_named_stream(smb_fname)) {
- return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- }
-
- status = vfs_at_fspcwd(talloc_tos(),
- handle->conn,
- &fspcwd);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
- }
-
- if (is_afpinfo_stream(smb_fname->stream_name)) {
- fd = fruit_open_meta(handle,
- fspcwd,
- smb_fname,
- fsp,
- flags,
- mode);
- } else if (is_afpresource_stream(smb_fname->stream_name)) {
- fd = fruit_open_rsrc(handle,
- fspcwd,
- smb_fname,
- fsp,
- flags,
- mode);
- } else {
- fd = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- }
- if (fd == -1) {
- saved_errno = errno;
- }
- TALLOC_FREE(fspcwd);
-
- DBG_DEBUG("Path [%s] fd [%d]\n", smb_fname_str_dbg(smb_fname), fd);
-
- if (saved_errno != 0) {
- errno = saved_errno;
- }
- return fd;
-}
-
static int fruit_openat(vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
.chmod_fn = fruit_chmod,
.unlinkat_fn = fruit_unlinkat,
.renameat_fn = fruit_renameat,
- .open_fn = fruit_open,
.openat_fn = fruit_openat,
.close_fn = fruit_close,
.pread_fn = fruit_pread,
return result;
}
-static int smb_full_audit_open(vfs_handle_struct *handle,
- struct smb_filename *smb_fname,
- files_struct *fsp, int flags, mode_t mode)
-{
- int result;
-
- result = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
-
- do_log(SMB_VFS_OP_OPEN, (result >= 0), handle, "%s|%s",
- ((flags & O_WRONLY) || (flags & O_RDWR))?"w":"r",
- smb_fname_str_do_log(handle->conn, smb_fname));
-
- return result;
-}
-
static int smb_full_audit_openat(vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
.rewind_dir_fn = smb_full_audit_rewinddir,
.mkdirat_fn = smb_full_audit_mkdirat,
.closedir_fn = smb_full_audit_closedir,
- .open_fn = smb_full_audit_open,
.openat_fn = smb_full_audit_openat,
.create_file_fn = smb_full_audit_create_file,
.close_fn = smb_full_audit_close,
return ret;
}
-static int vfs_gluster_open(struct vfs_handle_struct *handle,
- struct smb_filename *smb_fname, files_struct *fsp,
- int flags, mode_t mode)
-{
- glfs_fd_t *glfd;
- glfs_fd_t **p_tmp;
-
- START_PROFILE(syscall_open);
-
- p_tmp = VFS_ADD_FSP_EXTENSION(handle, fsp, glfs_fd_t *, NULL);
- if (p_tmp == NULL) {
- END_PROFILE(syscall_open);
- errno = ENOMEM;
- return -1;
- }
-
- if (flags & O_DIRECTORY) {
- glfd = glfs_opendir(handle->data, smb_fname->base_name);
- } else if (flags & O_CREAT) {
- glfd = glfs_creat(handle->data, smb_fname->base_name, flags,
- mode);
- } else {
- glfd = glfs_open(handle->data, smb_fname->base_name, flags);
- }
-
- if (glfd == NULL) {
- END_PROFILE(syscall_open);
- /* no extension destroy_fn, so no need to save errno */
- VFS_REMOVE_FSP_EXTENSION(handle, fsp);
- return -1;
- }
-
- *p_tmp = glfd;
-
- END_PROFILE(syscall_open);
- /* An arbitrary value for error reporting, so you know its us. */
- return 13371337;
-}
-
static int vfs_gluster_openat(struct vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
/* File Operations */
- .open_fn = vfs_gluster_open,
.openat_fn = vfs_gluster_openat,
.create_file_fn = NULL,
.close_fn = vfs_gluster_close,
return next;
}
-static int vfs_gpfs_open(struct vfs_handle_struct *handle,
- struct smb_filename *smb_fname, files_struct *fsp,
- int flags, mode_t mode)
-{
- struct gpfs_config_data *config;
- int ret;
- struct gpfs_fsp_extension *ext;
-
- SMB_VFS_HANDLE_GET_DATA(handle, config,
- struct gpfs_config_data,
- return -1);
-
- if (config->hsm && !config->recalls &&
- vfs_gpfs_fsp_is_offline(handle, fsp)) {
- DEBUG(10, ("Refusing access to offline file %s\n",
- fsp_str_dbg(fsp)));
- errno = EACCES;
- return -1;
- }
-
- if (config->syncio) {
- flags |= O_SYNC;
- }
-
- ext = VFS_ADD_FSP_EXTENSION(handle, fsp, struct gpfs_fsp_extension,
- NULL);
- if (ext == NULL) {
- errno = ENOMEM;
- return -1;
- }
-
- /*
- * Assume the file is offline until gpfs tells us it's online.
- */
- *ext = (struct gpfs_fsp_extension) { .offline = true };
-
- ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- if (ret == -1) {
- VFS_REMOVE_FSP_EXTENSION(handle, fsp);
- }
- return ret;
-}
-
static int vfs_gpfs_openat(struct vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
.aio_force_fn = vfs_gpfs_aio_force,
.sendfile_fn = vfs_gpfs_sendfile,
.fallocate_fn = vfs_gpfs_fallocate,
- .open_fn = vfs_gpfs_open,
.openat_fn = vfs_gpfs_openat,
.pread_fn = vfs_gpfs_pread,
.pread_send_fn = vfs_gpfs_pread_send,
return SMB_VFS_NEXT_CLOSEDIR(handle, realdirp);
}
-/*
- * Success: return non-negative file descriptor
- * Failure: set errno, return -1
- */
-static int mh_open(vfs_handle_struct *handle,
- struct smb_filename *smb_fname,
- files_struct *fsp,
- int flags,
- mode_t mode)
-{
- int ret;
- struct smb_filename *clientFname;
- TALLOC_CTX *ctx;
-
-
- DEBUG(MH_INFO_DEBUG, ("Entering with smb_fname->base_name '%s'\n",
- smb_fname->base_name));
-
- if (!is_in_media_files(smb_fname->base_name))
- {
- ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags,
- mode);
- goto out;
- }
-
- clientFname = NULL;
- ctx = talloc_tos();
-
- if(alloc_get_client_smb_fname(handle, ctx,
- smb_fname,
- &clientFname))
- {
- ret = -1;
- goto err;
- }
-
- // What about fsp->fsp_name?
- // We also have to get correct stat info into fsp and smb_fname
- // for DB files, don't we?
-
- DEBUG(MH_INFO_DEBUG, ("Leaving with smb_fname->base_name '%s' "
- "smb_fname->st.st_ex_mtime %s"
- " fsp->fsp_name->st.st_ex_mtime %s",
- smb_fname->base_name,
- ctime(&(smb_fname->st.st_ex_mtime.tv_sec)),
- ctime(&(fsp->fsp_name->st.st_ex_mtime.tv_sec))));
-
- ret = SMB_VFS_NEXT_OPEN(handle, clientFname, fsp, flags, mode);
-err:
- TALLOC_FREE(clientFname);
-out:
- DEBUG(MH_INFO_DEBUG, ("Leaving with smb_fname->base_name '%s'\n",
- smb_fname->base_name));
- return ret;
-}
-
/*
* Success: return non-negative file descriptor
* Failure: set errno, return -1
/* File operations */
- .open_fn = mh_open,
.openat_fn = mh_openat,
.create_file_fn = mh_create_file,
.renameat_fn = mh_renameat,
return -1;
}
-int vfs_not_implemented_open(vfs_handle_struct *handle,
- struct smb_filename *smb_fname,
- files_struct *fsp, int flags, mode_t mode)
-{
- errno = ENOSYS;
- return -1;
-}
-
int vfs_not_implemented_openat(vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
/* File operations */
- .open_fn = vfs_not_implemented_open,
.openat_fn = vfs_not_implemented_openat,
.create_file_fn = vfs_not_implemented_create_file,
.close_fn = vfs_not_implemented_close_fn,
return 0;
}
-static int prealloc_open(vfs_handle_struct* handle,
- struct smb_filename *smb_fname,
- files_struct * fsp,
- int flags,
- mode_t mode)
-{
- int fd;
- off_t size = 0;
-
- const char * dot;
- char fext[10];
-
- if (!(flags & (O_CREAT|O_TRUNC))) {
- /* Caller is not intending to rewrite the file. Let's not mess
- * with the allocation in this case.
- */
- goto normal_open;
- }
-
- *fext = '\0';
- dot = strrchr(smb_fname->base_name, '.');
- if (dot && *++dot) {
- if (strlen(dot) < sizeof(fext)) {
- strncpy(fext, dot, sizeof(fext));
- if (!strnorm(fext, CASE_LOWER)) {
- goto normal_open;
- }
- }
- }
-
- if (*fext == '\0') {
- goto normal_open;
- }
-
- /* Syntax for specifying preallocation size is:
- * MODULE: <extension> = <size>
- * where
- * <extension> is the file extension in lower case
- * <size> is a size like 10, 10K, 10M
- */
- size = conv_str_size(lp_parm_const_string(SNUM(handle->conn), MODULE,
- fext, NULL));
- if (size <= 0) {
- /* No need to preallocate this file. */
- goto normal_open;
- }
-
- fd = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- if (fd < 0) {
- return fd;
- }
-
- /* Prellocate only if the file is being created or replaced. Note that
- * Samba won't ever pass down O_TRUNC, which is why we have to handle
- * truncate calls specially.
- */
- if ((flags & O_CREAT) || (flags & O_TRUNC)) {
- off_t * psize;
-
- psize = VFS_ADD_FSP_EXTENSION(handle, fsp, off_t, NULL);
- if (psize == NULL || *psize == -1) {
- return fd;
- }
-
- DEBUG(module_debug,
- ("%s: preallocating %s (fd=%d) to %lld bytes\n",
- MODULE, smb_fname_str_dbg(smb_fname), fd,
- (long long)size));
-
- *psize = size;
- if (preallocate_space(fd, *psize) < 0) {
- VFS_REMOVE_FSP_EXTENSION(handle, fsp);
- }
- }
-
- return fd;
-
-normal_open:
- /* We are not creating or replacing a file. Skip the
- * preallocation.
- */
- DEBUG(module_debug, ("%s: skipping preallocation for %s\n",
- MODULE, smb_fname_str_dbg(smb_fname)));
- return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
-}
-
static int prealloc_openat(struct vfs_handle_struct* handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
}
static struct vfs_fn_pointers prealloc_fns = {
- .open_fn = prealloc_open,
.openat_fn = prealloc_openat,
.ftruncate_fn = prealloc_ftruncate,
.connect_fn = prealloc_connect,
return true;
}
-static int preopen_open(vfs_handle_struct *handle,
- struct smb_filename *smb_fname, files_struct *fsp,
- int flags, mode_t mode)
-{
- struct preopen_state *state;
- int res;
- unsigned long num;
-
- DEBUG(10, ("preopen_open called on %s\n", smb_fname_str_dbg(smb_fname)));
-
- state = preopen_state_get(handle);
- if (state == NULL) {
- return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- }
-
- res = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- if (res == -1) {
- return -1;
- }
-
- if ((flags & O_ACCMODE) != O_RDONLY) {
- return res;
- }
-
- if (!is_in_path(smb_fname->base_name, state->preopen_names, true)) {
- DEBUG(10, ("%s does not match the preopen:names list\n",
- smb_fname_str_dbg(smb_fname)));
- return res;
- }
-
- TALLOC_FREE(state->template_fname);
- state->template_fname = talloc_asprintf(
- state, "%s/%s",
- fsp->conn->cwd_fsp->fsp_name->base_name, smb_fname->base_name);
-
- if (state->template_fname == NULL) {
- return res;
- }
-
- if (!preopen_parse_fname(state->template_fname, &num,
- &state->number_start, &state->num_digits)) {
- TALLOC_FREE(state->template_fname);
- return res;
- }
-
- if (num > state->fnum_sent) {
- /*
- * Helpers were too slow, there's no point in reading
- * files in helpers that we already read in the
- * parent.
- */
- state->fnum_sent = num;
- }
-
- if ((state->fnum_queue_end != 0) /* Something was started earlier */
- && (num < (state->fnum_queue_end - state->queue_max))) {
- /*
- * "num" is before the queue we announced. This means
- * a new run is started.
- */
- state->fnum_sent = num;
- }
-
- state->fnum_queue_end = num + state->queue_max;
-
- preopen_queue_run(state);
-
- return res;
-}
-
static int preopen_openat(struct vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
}
static struct vfs_fn_pointers vfs_preopen_fns = {
- .open_fn = preopen_open,
.openat_fn = preopen_openat,
};
return ret;
}
-static int shadow_copy2_open(vfs_handle_struct *handle,
- struct smb_filename *smb_fname, files_struct *fsp,
- int flags, mode_t mode)
-{
- time_t timestamp = 0;
- char *stripped = NULL;
- char *tmp;
- bool is_converted = false;
- int saved_errno = 0;
- int ret;
-
- if (!shadow_copy2_strip_snapshot_converted(talloc_tos(), handle,
- smb_fname,
- ×tamp, &stripped,
- &is_converted)) {
- return -1;
- }
- if (timestamp == 0) {
- if (is_converted) {
- /*
- * Just pave over the user requested mode and use
- * O_RDONLY. Later attempts by the client to write on
- * the handle will fail in the pwrite() syscall with
- * EINVAL which we carefully map to EROFS. In sum, this
- * matches Windows behaviour.
- */
- flags = O_RDONLY;
- }
- return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- }
-
- tmp = smb_fname->base_name;
- smb_fname->base_name = shadow_copy2_convert(
- talloc_tos(), handle, stripped, timestamp);
- TALLOC_FREE(stripped);
-
- if (smb_fname->base_name == NULL) {
- smb_fname->base_name = tmp;
- return -1;
- }
-
- /*
- * Just pave over the user requested mode and use O_RDONLY. Later
- * attempts by the client to write on the handle will fail in the
- * pwrite() syscall with EINVAL which we carefully map to EROFS. In sum,
- * this matches Windows behaviour.
- */
- flags = O_RDONLY;
-
- ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- if (ret == -1) {
- saved_errno = errno;
- }
-
- TALLOC_FREE(smb_fname->base_name);
- smb_fname->base_name = tmp;
-
- if (saved_errno != 0) {
- errno = saved_errno;
- }
- return ret;
-}
-
static int shadow_copy2_openat(vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname_in,
.stat_fn = shadow_copy2_stat,
.lstat_fn = shadow_copy2_lstat,
.fstat_fn = shadow_copy2_fstat,
- .open_fn = shadow_copy2_open,
.openat_fn = shadow_copy2_openat,
.unlinkat_fn = shadow_copy2_unlinkat,
.chmod_fn = shadow_copy2_chmod,
return ret;
}
-static int snapper_gmt_open(vfs_handle_struct *handle,
- struct smb_filename *smb_fname, files_struct *fsp,
- int flags, mode_t mode)
-{
- time_t timestamp;
- char *stripped, *tmp;
- int ret, saved_errno;
-
- if (!snapper_gmt_strip_snapshot(talloc_tos(), handle,
- smb_fname,
- ×tamp, &stripped)) {
- return -1;
- }
- if (timestamp == 0) {
- return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- }
-
- tmp = smb_fname->base_name;
- smb_fname->base_name = snapper_gmt_convert(talloc_tos(), handle,
- stripped, timestamp);
- TALLOC_FREE(stripped);
-
- if (smb_fname->base_name == NULL) {
- smb_fname->base_name = tmp;
- return -1;
- }
-
- ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- saved_errno = errno;
-
- TALLOC_FREE(smb_fname->base_name);
- smb_fname->base_name = tmp;
-
- errno = saved_errno;
- return ret;
-}
-
static int snapper_gmt_openat(struct vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname_in,
.symlinkat_fn = snapper_gmt_symlinkat,
.stat_fn = snapper_gmt_stat,
.lstat_fn = snapper_gmt_lstat,
- .open_fn = snapper_gmt_open,
.openat_fn = snapper_gmt_openat,
.unlinkat_fn = snapper_gmt_unlinkat,
.chmod_fn = snapper_gmt_chmod,
return ret;
}
-static int streams_depot_open(vfs_handle_struct *handle,
- struct smb_filename *smb_fname,
- files_struct *fsp, int flags, mode_t mode)
-{
- struct smb_filename *smb_fname_stream = NULL;
- struct smb_filename *smb_fname_base = NULL;
- NTSTATUS status;
- int ret = -1;
-
- if (!is_named_stream(smb_fname)) {
- return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- }
-
- /* Ensure the base file still exists. */
- smb_fname_base = synthetic_smb_fname(talloc_tos(),
- smb_fname->base_name,
- NULL,
- NULL,
- smb_fname->twrp,
- smb_fname->flags);
- if (smb_fname_base == NULL) {
- ret = -1;
- errno = ENOMEM;
- goto done;
- }
-
- ret = SMB_VFS_NEXT_STAT(handle, smb_fname_base);
- if (ret == -1) {
- goto done;
- }
-
- /* Determine the stream name, and then open it. */
- status = stream_smb_fname(handle, smb_fname, &smb_fname_stream, true);
- if (!NT_STATUS_IS_OK(status)) {
- ret = -1;
- errno = map_errno_from_nt_status(status);
- goto done;
- }
-
- ret = SMB_VFS_NEXT_OPEN(handle, smb_fname_stream, fsp, flags, mode);
-
- done:
- TALLOC_FREE(smb_fname_stream);
- TALLOC_FREE(smb_fname_base);
- return ret;
-}
-
static int streams_depot_openat(struct vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
static struct vfs_fn_pointers vfs_streams_depot_fns = {
.fs_capabilities_fn = streams_depot_fs_capabilities,
- .open_fn = streams_depot_open,
.openat_fn = streams_depot_openat,
.stat_fn = streams_depot_stat,
.lstat_fn = streams_depot_lstat,
return result;
}
-static int streams_xattr_open(vfs_handle_struct *handle,
- struct smb_filename *smb_fname,
- files_struct *fsp, int flags, mode_t mode)
-{
- NTSTATUS status;
- struct streams_xattr_config *config = NULL;
- struct stream_io *sio = NULL;
- struct ea_struct ea;
- char *xattr_name = NULL;
- int pipe_fds[2];
- int fakefd = -1;
- bool set_empty_xattr = false;
- int ret;
-
- SMB_VFS_HANDLE_GET_DATA(handle, config, struct streams_xattr_config,
- return -1);
-
- DEBUG(10, ("streams_xattr_open called for %s with flags 0x%x\n",
- smb_fname_str_dbg(smb_fname), flags));
-
- if (!is_named_stream(smb_fname)) {
- return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- }
-
- status = streams_xattr_get_name(handle, talloc_tos(),
- smb_fname->stream_name, &xattr_name);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- goto fail;
- }
-
- status = get_ea_value(talloc_tos(), handle->conn, NULL,
- smb_fname, xattr_name, &ea);
-
- DEBUG(10, ("get_ea_value returned %s\n", nt_errstr(status)));
-
- if (!NT_STATUS_IS_OK(status)) {
- if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
- /*
- * The base file is not there. This is an error even if
- * we got O_CREAT, the higher levels should have created
- * the base file for us.
- */
- DBG_DEBUG("streams_xattr_open: base file %s not around, "
- "returning ENOENT\n", smb_fname->base_name);
- errno = ENOENT;
- goto fail;
- }
-
- if (!(flags & O_CREAT)) {
- errno = ENOATTR;
- goto fail;
- }
-
- set_empty_xattr = true;
- }
-
- if (flags & O_TRUNC) {
- set_empty_xattr = true;
- }
-
- if (set_empty_xattr) {
- /*
- * The attribute does not exist or needs to be truncated
- */
-
- /*
- * Darn, xattrs need at least 1 byte
- */
- char null = '\0';
-
- DEBUG(10, ("creating or truncating attribute %s on file %s\n",
- xattr_name, smb_fname->base_name));
-
- ret = SMB_VFS_SETXATTR(fsp->conn,
- smb_fname,
- xattr_name,
- &null, sizeof(null),
- flags & O_EXCL ? XATTR_CREATE : 0);
- if (ret != 0) {
- goto fail;
- }
- }
-
- /*
- * Return a valid fd, but ensure any attempt to use it returns an error
- * (EPIPE).
- */
- ret = pipe(pipe_fds);
- if (ret != 0) {
- goto fail;
- }
-
- close(pipe_fds[1]);
- pipe_fds[1] = -1;
- fakefd = pipe_fds[0];
-
- sio = VFS_ADD_FSP_EXTENSION(handle, fsp, struct stream_io, NULL);
- if (sio == NULL) {
- errno = ENOMEM;
- goto fail;
- }
-
- sio->xattr_name = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp),
- xattr_name);
- if (sio->xattr_name == NULL) {
- errno = ENOMEM;
- goto fail;
- }
-
- /*
- * so->base needs to be a copy of fsp->fsp_name->base_name,
- * making it identical to streams_xattr_recheck(). If the
- * open is changing directories, fsp->fsp_name->base_name
- * will be the full path from the share root, whilst
- * smb_fname will be relative to the $cwd.
- */
- sio->base = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp),
- fsp->fsp_name->base_name);
- if (sio->base == NULL) {
- errno = ENOMEM;
- goto fail;
- }
-
- sio->fsp_name_ptr = fsp->fsp_name;
- sio->handle = handle;
- sio->fsp = fsp;
-
- return fakefd;
-
- fail:
- if (fakefd >= 0) {
- close(fakefd);
- fakefd = -1;
- }
-
- return -1;
-}
-
static int streams_xattr_openat(struct vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
static struct vfs_fn_pointers vfs_streams_xattr_fns = {
.fs_capabilities_fn = streams_xattr_fs_capabilities,
.connect_fn = streams_xattr_connect,
- .open_fn = streams_xattr_open,
.openat_fn = streams_xattr_openat,
.close_fn = streams_xattr_close,
.stat_fn = streams_xattr_stat,
return ret;
}
-
-static int syncops_open(vfs_handle_struct *handle,
- struct smb_filename *smb_fname, files_struct *fsp,
- int flags, mode_t mode)
-{
- SYNCOPS_NEXT_SMB_FNAME(OPEN, (flags&O_CREAT?smb_fname:NULL),
- (handle, smb_fname, fsp, flags, mode));
-}
-
static int syncops_openat(struct vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
static struct vfs_fn_pointers vfs_syncops_fns = {
.connect_fn = syncops_connect,
.mkdirat_fn = syncops_mkdirat,
- .open_fn = syncops_open,
.openat_fn = syncops_openat,
.renameat_fn = syncops_renameat,
.unlinkat_fn = syncops_unlinkat,
return result;
}
-static int smb_time_audit_open(vfs_handle_struct *handle,
- struct smb_filename *fname,
- files_struct *fsp,
- int flags, mode_t mode)
-{
- int result;
- struct timespec ts1,ts2;
- double timediff;
-
- clock_gettime_mono(&ts1);
- result = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
- clock_gettime_mono(&ts2);
- timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
-
- if (timediff > audit_timeout) {
- smb_time_audit_log_fsp("open", timediff, fsp);
- }
-
- return result;
-}
-
static int smb_time_audit_openat(vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
.rewind_dir_fn = smb_time_audit_rewinddir,
.mkdirat_fn = smb_time_audit_mkdirat,
.closedir_fn = smb_time_audit_closedir,
- .open_fn = smb_time_audit_open,
.openat_fn = smb_time_audit_openat,
.create_file_fn = smb_time_audit_create_file,
.close_fn = smb_time_audit_close,
return SMB_VFS_NEXT_CLOSEDIR(handle, realdirp);
}
-static int um_open(vfs_handle_struct *handle,
- struct smb_filename *smb_fname,
- files_struct *fsp,
- int flags,
- mode_t mode)
-{
- int ret;
- struct smb_filename *client_fname = NULL;
-
- DEBUG(10, ("Entering with smb_fname->base_name '%s'\n",
- smb_fname->base_name));
-
- if (!is_in_media_files(smb_fname->base_name)) {
- return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- }
-
- if (alloc_get_client_smb_fname(handle, talloc_tos(),
- smb_fname,
- &client_fname)) {
- ret = -1;
- goto err;
- }
-
- /*
- * FIXME:
- * What about fsp->fsp_name? We also have to get correct stat
- * info into fsp and smb_fname for DB files, don't we?
- */
-
- DEBUG(10, ("Leaving with smb_fname->base_name '%s' "
- "smb_fname->st.st_ex_mtime %s"
- "fsp->fsp_name->st.st_ex_mtime %s",
- smb_fname->base_name,
- ctime(&(smb_fname->st.st_ex_mtime.tv_sec)),
- ctime(&(fsp->fsp_name->st.st_ex_mtime.tv_sec))));
-
- ret = SMB_VFS_NEXT_OPEN(handle, client_fname, fsp, flags, mode);
-err:
- TALLOC_FREE(client_fname);
- DEBUG(10, ("Leaving with smb_fname->base_name '%s'\n",
- smb_fname->base_name));
- return ret;
-}
-
static int um_openat(struct vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
/* File operations */
- .open_fn = um_open,
.openat_fn = um_openat,
.create_file_fn = um_create_file,
.renameat_fn = um_renameat,
return scan_result;
}
-static int virusfilter_vfs_open(
- struct vfs_handle_struct *handle,
- struct smb_filename *smb_fname,
- files_struct *fsp,
- int flags,
- mode_t mode)
-{
- TALLOC_CTX *mem_ctx = talloc_tos();
- struct virusfilter_config *config;
- const char *cwd_fname = fsp->conn->cwd_fsp->fsp_name->base_name;
- virusfilter_result scan_result;
- const char *fname = fsp->fsp_name->base_name;
- char *dir_name = NULL;
- const char *base_name = NULL;
- int scan_errno = 0;
- size_t test_prefix;
- size_t test_suffix;
- int rename_trap_count = 0;
- int ret;
- bool ok1;
- char *sret = NULL;
-
- SMB_VFS_HANDLE_GET_DATA(handle, config,
- struct virusfilter_config, return -1);
-
- if (fsp->fsp_flags.is_directory) {
- DBG_INFO("Not scanned: Directory: %s/\n", cwd_fname);
- goto virusfilter_vfs_open_next;
- }
-
- test_prefix = strlen(config->rename_prefix);
- test_suffix = strlen(config->rename_suffix);
- if (test_prefix > 0) {
- rename_trap_count++;
- }
- if (test_suffix > 0) {
- rename_trap_count++;
- }
-
- if (is_named_stream(smb_fname)) {
- DBG_INFO("Not scanned: only file backed streams can be scanned:"
- " %s/%s\n", cwd_fname, fname);
- goto virusfilter_vfs_open_next;
- }
-
- if (!config->scan_on_open) {
- DBG_INFO("Not scanned: scan on open is disabled: %s/%s\n",
- cwd_fname, fname);
- goto virusfilter_vfs_open_next;
- }
-
- if (flags & O_TRUNC) {
- DBG_INFO("Not scanned: Open flags have O_TRUNC: %s/%s\n",
- cwd_fname, fname);
- goto virusfilter_vfs_open_next;
- }
-
- ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
- if (ret != 0) {
-
- /*
- * Do not return immediately if !(flags & O_CREAT) &&
- * errno != ENOENT.
- * Do not do this here or anywhere else. The module is
- * stackable and there may be modules below, such as audit
- * modules, which should be handled.
- */
- goto virusfilter_vfs_open_next;
- }
- ret = S_ISREG(smb_fname->st.st_ex_mode);
- if (ret == 0) {
- DBG_INFO("Not scanned: Directory or special file: %s/%s\n",
- cwd_fname, fname);
- goto virusfilter_vfs_open_next;
- }
- if (config->max_file_size > 0 &&
- smb_fname->st.st_ex_size > config->max_file_size)
- {
- DBG_INFO("Not scanned: file size > max file size: %s/%s\n",
- cwd_fname, fname);
- goto virusfilter_vfs_open_next;
- }
- if (config->min_file_size > 0 &&
- smb_fname->st.st_ex_size < config->min_file_size)
- {
- DBG_INFO("Not scanned: file size < min file size: %s/%s\n",
- cwd_fname, fname);
- goto virusfilter_vfs_open_next;
- }
-
- ok1 = is_in_path(fname, config->exclude_files, false);
- if (config->exclude_files && ok1)
- {
- DBG_INFO("Not scanned: exclude files: %s/%s\n",
- cwd_fname, fname);
- goto virusfilter_vfs_open_next;
- }
-
- if (config->infected_file_action == VIRUSFILTER_ACTION_QUARANTINE) {
- sret = strstr_m(fname, config->quarantine_dir);
- if (sret != NULL) {
- scan_errno = config->infected_open_errno;
- goto virusfilter_vfs_open_fail;
- }
- }
-
- if (test_prefix > 0 || test_suffix > 0) {
- ok1 = parent_dirname(mem_ctx, fname, &dir_name, &base_name);
- if (ok1)
- {
- if (test_prefix > 0) {
- ret = strncmp(base_name,
- config->rename_prefix, test_prefix);
- if (ret != 0) {
- test_prefix = 0;
- }
- }
- if (test_suffix > 0) {
- ret = strcmp(base_name + (strlen(base_name)
- - test_suffix),
- config->rename_suffix);
- if (ret != 0) {
- test_suffix = 0;
- }
- }
-
- TALLOC_FREE(dir_name);
-
- if ((rename_trap_count == 2 && test_prefix &&
- test_suffix) || (rename_trap_count == 1 &&
- (test_prefix || test_suffix)))
- {
- scan_errno =
- config->infected_open_errno;
- goto virusfilter_vfs_open_fail;
- }
- }
- }
-
- scan_result = virusfilter_scan(handle, config, fsp);
-
- switch (scan_result) {
- case VIRUSFILTER_RESULT_CLEAN:
- break;
- case VIRUSFILTER_RESULT_INFECTED:
- scan_errno = config->infected_open_errno;
- goto virusfilter_vfs_open_fail;
- case VIRUSFILTER_RESULT_ERROR:
- if (config->block_access_on_error) {
- DBG_INFO("Block access\n");
- scan_errno = config->scan_error_open_errno;
- goto virusfilter_vfs_open_fail;
- }
- break;
- default:
- scan_errno = config->scan_error_open_errno;
- goto virusfilter_vfs_open_fail;
- }
-
-virusfilter_vfs_open_next:
- return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
-
-virusfilter_vfs_open_fail:
- errno = (scan_errno != 0) ? scan_errno : EACCES;
- return -1;
-}
-
static int virusfilter_vfs_openat(struct vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname_in,
static struct vfs_fn_pointers vfs_virusfilter_fns = {
.connect_fn = virusfilter_vfs_connect,
.disconnect_fn = virusfilter_vfs_disconnect,
- .open_fn = virusfilter_vfs_open,
.openat_fn = virusfilter_vfs_openat,
.close_fn = virusfilter_vfs_close,
.unlinkat_fn = virusfilter_vfs_unlinkat,
return SMB_VFS_NEXT_STAT(handle, smb_fname);
}
-static int widelinks_open(vfs_handle_struct *handle,
- struct smb_filename *smb_fname,
- files_struct *fsp,
- int flags,
- mode_t mode)
-{
- struct widelinks_config *config = NULL;
-
- SMB_VFS_HANDLE_GET_DATA(handle,
- config,
- struct widelinks_config,
- return -1);
-
- if (!config->active) {
- /* Module not active. */
- return SMB_VFS_NEXT_OPEN(handle,
- smb_fname,
- fsp,
- flags,
- mode);
- }
-
- if (config->cwd == NULL) {
- /* open before chdir. See note 1b above. */
- return SMB_VFS_NEXT_OPEN(handle,
- smb_fname,
- fsp,
- flags,
- mode);
- }
-
- if (smb_fname->flags & SMB_FILENAME_POSIX_PATH) {
- /* POSIX sees symlinks. */
- return SMB_VFS_NEXT_OPEN(handle,
- smb_fname,
- fsp,
- flags,
- mode);
- }
-
- /* Remove O_NOFOLLOW. */
- flags = (flags & ~O_NOFOLLOW);
-
- return SMB_VFS_NEXT_OPEN(handle,
- smb_fname,
- fsp,
- flags,
- mode);
-}
-
static int widelinks_openat(vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
static struct vfs_fn_pointers vfs_widelinks_fns = {
.connect_fn = widelinks_connect,
- .open_fn = widelinks_open,
.openat_fn = widelinks_openat,
.lstat_fn = widelinks_lstat,
/*
return true;
}
-static int xattr_tdb_open(vfs_handle_struct *handle,
- struct smb_filename *smb_fname,
- files_struct *fsp,
- int flags,
- mode_t mode)
-{
- struct db_context *db = NULL;
- TALLOC_CTX *frame = NULL;
- int ret;
-
- fsp->fh->fd = SMB_VFS_NEXT_OPEN(handle,
- smb_fname, fsp,
- flags,
- mode);
-
- if (fsp->fh->fd < 0) {
- return fsp->fh->fd;
- }
-
- if ((flags & (O_CREAT|O_EXCL)) != (O_CREAT|O_EXCL)) {
- return fsp->fh->fd;
- }
-
- /*
- * We know we used O_CREAT|O_EXCL and it worked.
- * We must have created the file.
- */
-
- ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
- if (ret == -1) {
- /* Can't happen... */
- DBG_WARNING("SMB_VFS_FSTAT failed on file %s (%s)\n",
- smb_fname_str_dbg(smb_fname),
- strerror(errno));
- return -1;
- }
- fsp->file_id = SMB_VFS_FILE_ID_CREATE(fsp->conn, &smb_fname->st);
-
- frame = talloc_stackframe();
- SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
- if (!xattr_tdb_init(-1, frame, &db))
- {
- TALLOC_FREE(frame); return -1;
- });
-
- xattr_tdb_remove_all_attrs(db, &fsp->file_id);
- TALLOC_FREE(frame);
- return fsp->fh->fd;
-}
-
static int xattr_tdb_openat(struct vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
.flistxattr_fn = xattr_tdb_flistxattr,
.removexattr_fn = xattr_tdb_removexattr,
.fremovexattr_fn = xattr_tdb_fremovexattr,
- .open_fn = xattr_tdb_open,
.openat_fn = xattr_tdb_openat,
.mkdirat_fn = xattr_tdb_mkdirat,
.unlinkat_fn = xattr_tdb_unlinkat,
head -n 1 <&101
head -n 1 <&102
-echo "error_inject:open = EINTR" > ${error_inject_conf}
-echo "error_inject:openat = EINTR" >> ${error_inject_conf}
+echo "error_inject:openat = EINTR" > ${error_inject_conf}
${SMBCONTROL} ${CONF} 0 reload-config
sleep 1
return handle->fns->closedir_fn(handle, dir);
}
-int smb_vfs_call_open(struct vfs_handle_struct *handle,
- struct smb_filename *smb_fname, struct files_struct *fsp,
- int flags, mode_t mode)
-{
- VFS_FIND(open);
- return handle->fns->open_fn(handle, smb_fname, fsp, flags, mode);
-}
-
int smb_vfs_call_openat(struct vfs_handle_struct *handle,
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,