return NT_STATUS_NOT_IMPLEMENTED;
}
+static NTSTATUS skel_get_real_filename_at(struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
static const char *skel_connectpath(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname)
{
.fstreaminfo_fn = skel_fstreaminfo,
.get_real_filename_fn = skel_get_real_filename,
+ .get_real_filename_at_fn = skel_get_real_filename_at,
.connectpath_fn = skel_connectpath,
.brl_lock_windows_fn = skel_brl_lock_windows,
.brl_unlock_windows_fn = skel_brl_unlock_windows,
path, name, mem_ctx, found_name);
}
+static NTSTATUS skel_get_real_filename_at(struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name)
+{
+ return SMB_VFS_NEXT_GET_REAL_FILENAME_AT(
+ handle, dirfsp, name, mem_ctx, found_name);
+}
+
static const char *skel_connectpath(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname)
{
.fstreaminfo_fn = skel_fstreaminfo,
.get_real_filename_fn = skel_get_real_filename,
+ .get_real_filename_at_fn = skel_get_real_filename_at,
.connectpath_fn = skel_connectpath,
.brl_lock_windows_fn = skel_brl_lock_windows,
.brl_unlock_windows_fn = skel_brl_unlock_windows,
* Version 47 - remove st_ex_itime from struct stat_ex
* Version 47 - remove (unused) struct lock_struct last_lock_failure
from files_struct.
+ * Version 47 - Add SMB_VFS_GET_REAL_FILENAME_AT
*/
#define SMB_VFS_INTERFACE_VERSION 47
TALLOC_CTX *mem_ctx,
char **found_name);
+ NTSTATUS (*get_real_filename_at_fn)(struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name);
+
const char *(*connectpath_fn)(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname);
const char *name,
TALLOC_CTX *mem_ctx,
char **found_name);
+NTSTATUS smb_vfs_call_get_real_filename_at(struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name);
const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname);
NTSTATUS smb_vfs_call_brl_lock_windows(struct vfs_handle_struct *handle,
const char *name,
TALLOC_CTX *mem_ctx,
char **found_name);
+NTSTATUS vfs_not_implemented_get_real_filename_at(
+ struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name);
const char *vfs_not_implemented_connectpath(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname);
NTSTATUS vfs_not_implemented_brl_lock_windows(struct vfs_handle_struct *handle,
#define SMB_VFS_NEXT_GET_REAL_FILENAME(handle, path, name, mem_ctx, found_name) \
smb_vfs_call_get_real_filename((handle)->next, (path), (name), (mem_ctx), (found_name))
+#define SMB_VFS_GET_REAL_FILENAME_AT(conn, dirfsp, name, mem_ctx, found_name) \
+ smb_vfs_call_get_real_filename_at( \
+ (conn)->vfs_handles, \
+ (dirfsp), \
+ (name), \
+ (mem_ctx), \
+ (found_name))
+#define SMB_VFS_NEXT_GET_REAL_FILENAME_AT( \
+ handle, dirfsp, name, mem_ctx, found_name) \
+ smb_vfs_call_get_real_filename_at( \
+ (handle)->next, \
+ (dirfsp), \
+ (name), \
+ (mem_ctx), \
+ (found_name))
+
#define SMB_VFS_CONNECTPATH(conn, smb_fname) \
smb_vfs_call_connectpath((conn)->vfs_handles, (smb_fname))
#define SMB_VFS_NEXT_CONNECTPATH(conn, smb_fname) \
return NT_STATUS_NOT_SUPPORTED;
}
+static NTSTATUS cephwrap_get_real_filename_at(
+ struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name)
+{
+ /*
+ * Don't fall back to get_real_filename so callers can differentiate
+ * between a full directory scan and an actual case-insensitive stat.
+ */
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
static const char *cephwrap_connectpath(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname)
{
.realpath_fn = cephwrap_realpath,
.fchflags_fn = cephwrap_fchflags,
.get_real_filename_fn = cephwrap_get_real_filename,
+ .get_real_filename_at_fn = cephwrap_get_real_filename_at,
.connectpath_fn = cephwrap_connectpath,
/* EA operations. */
return status;
}
+static NTSTATUS ceph_snap_gmt_get_real_filename_at(
+ struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name)
+{
+ NTSTATUS status = ceph_snap_gmt_get_real_filename(
+ handle, dirfsp->fsp_name, name, mem_ctx, found_name);
+ return status;
+}
+
static uint64_t ceph_snap_gmt_disk_free(vfs_handle_struct *handle,
const struct smb_filename *csmb_fname,
uint64_t *bsize,
.fsetxattr_fn = ceph_snap_gmt_fsetxattr,
.fchflags_fn = ceph_snap_gmt_fchflags,
.get_real_filename_fn = ceph_snap_gmt_get_real_filename,
+ .get_real_filename_at_fn = ceph_snap_gmt_get_real_filename_at,
};
static_decl_vfs;
return NT_STATUS_NOT_SUPPORTED;
}
+static NTSTATUS vfswrap_get_real_filename_at(
+ struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name)
+{
+ /*
+ * Don't fall back to get_real_filename so callers can differentiate
+ * between a full directory scan and an actual case-insensitive stat.
+ */
+ return NT_STATUS_NOT_SUPPORTED;
+}
+
static const char *vfswrap_connectpath(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname)
{
.fs_file_id_fn = vfswrap_fs_file_id,
.fstreaminfo_fn = vfswrap_fstreaminfo,
.get_real_filename_fn = vfswrap_get_real_filename,
+ .get_real_filename_at_fn = vfswrap_get_real_filename_at,
.connectpath_fn = vfswrap_connectpath,
.brl_lock_windows_fn = vfswrap_brl_lock_windows,
.brl_unlock_windows_fn = vfswrap_brl_unlock_windows,
SMB_VFS_OP_FS_FILE_ID,
SMB_VFS_OP_FSTREAMINFO,
SMB_VFS_OP_GET_REAL_FILENAME,
+ SMB_VFS_OP_GET_REAL_FILENAME_AT,
SMB_VFS_OP_CONNECTPATH,
SMB_VFS_OP_BRL_LOCK_WINDOWS,
SMB_VFS_OP_BRL_UNLOCK_WINDOWS,
{ SMB_VFS_OP_FS_FILE_ID, "fs_file_id" },
{ SMB_VFS_OP_FSTREAMINFO, "fstreaminfo" },
{ SMB_VFS_OP_GET_REAL_FILENAME, "get_real_filename" },
+ { SMB_VFS_OP_GET_REAL_FILENAME_AT, "get_real_filename_at" },
{ SMB_VFS_OP_CONNECTPATH, "connectpath" },
{ SMB_VFS_OP_BRL_LOCK_WINDOWS, "brl_lock_windows" },
{ SMB_VFS_OP_BRL_UNLOCK_WINDOWS, "brl_unlock_windows" },
return result;
}
+static NTSTATUS smb_full_audit_get_real_filename_at(
+ struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name)
+{
+ NTSTATUS result;
+
+ result = SMB_VFS_NEXT_GET_REAL_FILENAME_AT(
+ handle, dirfsp, name, mem_ctx, found_name);
+
+ do_log(SMB_VFS_OP_GET_REAL_FILENAME_AT,
+ NT_STATUS_IS_OK(result),
+ handle,
+ "%s/%s->%s",
+ fsp_str_dbg(dirfsp),
+ name,
+ NT_STATUS_IS_OK(result) ? *found_name : "");
+
+ return result;
+}
+
static const char *smb_full_audit_connectpath(vfs_handle_struct *handle,
const struct smb_filename *smb_fname)
{
.snap_delete_fn = smb_full_audit_snap_delete,
.fstreaminfo_fn = smb_full_audit_fstreaminfo,
.get_real_filename_fn = smb_full_audit_get_real_filename,
+ .get_real_filename_at_fn = smb_full_audit_get_real_filename_at,
.connectpath_fn = smb_full_audit_connectpath,
.brl_lock_windows_fn = smb_full_audit_brl_lock_windows,
.brl_unlock_windows_fn = smb_full_audit_brl_unlock_windows,
return NT_STATUS_OK;
}
+static NTSTATUS vfs_gluster_get_real_filename_at(
+ struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name)
+{
+ NTSTATUS status = vfs_gluster_get_real_filename(
+ handle, dirfsp->fsp_name, name, mem_ctx, found_name);
+ return status;
+}
+
static const char *vfs_gluster_connectpath(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname)
{
.file_id_create_fn = NULL,
.fstreaminfo_fn = NULL,
.get_real_filename_fn = vfs_gluster_get_real_filename,
+ .get_real_filename_at_fn = vfs_gluster_get_real_filename_at,
.connectpath_fn = vfs_gluster_connectpath,
.create_dfs_pathat_fn = vfs_gluster_create_dfs_pathat,
.read_dfs_pathat_fn = vfs_gluster_read_dfs_pathat,
return NT_STATUS_OK;
}
+static NTSTATUS vfs_gluster_fuse_get_real_filename_at(
+ struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **_found_name)
+{
+ NTSTATUS status = vfs_gluster_fuse_get_real_filename(
+ handle, dirfsp->fsp_name, name, mem_ctx, _found_name);
+ return status;
+}
+
struct device_mapping_entry {
SMB_DEV_T device; /* the local device, for reference */
uint64_t mapped_device; /* the mapped device */
.connect_fn = vfs_glusterfs_fuse_connect,
.get_real_filename_fn = vfs_gluster_fuse_get_real_filename,
+ .get_real_filename_at_fn = vfs_gluster_fuse_get_real_filename_at,
.file_id_create_fn = vfs_glusterfs_fuse_file_id_create,
};
return NT_STATUS_OK;
}
+static NTSTATUS vfs_gpfs_get_real_filename_at(struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name)
+{
+ NTSTATUS status = vfs_gpfs_get_real_filename(
+ handle, dirfsp->fsp_name, name, mem_ctx, found_name);
+ return status;
+}
+
static void sd2gpfs_control(uint16_t control, struct gpfs_acl *gacl)
{
unsigned int gpfs_aclflags = 0;
.filesystem_sharemode_fn = vfs_gpfs_filesystem_sharemode,
.linux_setlease_fn = vfs_gpfs_setlease,
.get_real_filename_fn = vfs_gpfs_get_real_filename,
+ .get_real_filename_at_fn = vfs_gpfs_get_real_filename_at,
.get_dos_attributes_send_fn = vfs_not_implemented_get_dos_attributes_send,
.get_dos_attributes_recv_fn = vfs_not_implemented_get_dos_attributes_recv,
.fget_dos_attributes_fn = vfs_gpfs_fget_dos_attributes,
return NT_STATUS_NOT_IMPLEMENTED;
}
+_PUBLIC_
+NTSTATUS vfs_not_implemented_get_real_filename_at(
+ struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name)
+{
+ return NT_STATUS_NOT_IMPLEMENTED;
+}
+
_PUBLIC_
const char *vfs_not_implemented_connectpath(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname)
.fstreaminfo_fn = vfs_not_implemented_fstreaminfo,
.get_real_filename_fn = vfs_not_implemented_get_real_filename,
+ .get_real_filename_at_fn = vfs_not_implemented_get_real_filename_at,
.connectpath_fn = vfs_not_implemented_connectpath,
.brl_lock_windows_fn = vfs_not_implemented_brl_lock_windows,
.brl_unlock_windows_fn = vfs_not_implemented_brl_unlock_windows,
return NT_STATUS_OK;
}
+static NTSTATUS shadow_copy2_get_real_filename_at(
+ struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name)
+{
+ NTSTATUS status = shadow_copy2_get_real_filename(
+ handle, dirfsp->fsp_name, name, mem_ctx, found_name);
+ return status;
+}
+
static const char *shadow_copy2_connectpath(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname_in)
{
.fsetxattr_fn = shadow_copy2_fsetxattr,
.fchflags_fn = shadow_copy2_fchflags,
.get_real_filename_fn = shadow_copy2_get_real_filename,
+ .get_real_filename_at_fn = shadow_copy2_get_real_filename_at,
.pwrite_fn = shadow_copy2_pwrite,
.pwrite_send_fn = shadow_copy2_pwrite_send,
.pwrite_recv_fn = shadow_copy2_pwrite_recv,
return status;
}
+static NTSTATUS snapper_gmt_get_real_filename_at(
+ struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name)
+{
+ NTSTATUS status = snapper_gmt_get_real_filename(
+ handle, dirfsp->fsp_name, name, mem_ctx, found_name);
+ return status;
+}
+
static uint64_t snapper_gmt_disk_free(vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
uint64_t *bsize,
.fsetxattr_fn = snapper_gmt_fsetxattr,
.fchflags_fn = snapper_gmt_fchflags,
.get_real_filename_fn = snapper_gmt_get_real_filename,
+ .get_real_filename_at_fn = snapper_gmt_get_real_filename_at,
};
static_decl_vfs;
return result;
}
+static NTSTATUS smb_time_audit_get_real_filename_at(
+ struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name)
+{
+ NTSTATUS result;
+ struct timespec ts1,ts2;
+ double timediff;
+
+ clock_gettime_mono(&ts1);
+ result = SMB_VFS_NEXT_GET_REAL_FILENAME_AT(
+ handle, dirfsp, name, mem_ctx, found_name);
+ clock_gettime_mono(&ts2);
+ timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
+
+ if (timediff > audit_timeout) {
+ smb_time_audit_log_fname("get_real_filename_at",
+ timediff,
+ fsp_str_dbg(dirfsp));
+ }
+
+ return result;
+}
+
static const char *smb_time_audit_connectpath(vfs_handle_struct *handle,
const struct smb_filename *smb_fname)
{
.snap_delete_fn = smb_time_audit_snap_delete,
.fstreaminfo_fn = smb_time_audit_fstreaminfo,
.get_real_filename_fn = smb_time_audit_get_real_filename,
+ .get_real_filename_at_fn = smb_time_audit_get_real_filename_at,
.connectpath_fn = smb_time_audit_connectpath,
.brl_lock_windows_fn = smb_time_audit_brl_lock_windows,
.brl_unlock_windows_fn = smb_time_audit_brl_unlock_windows,
found_name);
}
+NTSTATUS smb_vfs_call_get_real_filename_at(struct vfs_handle_struct *handle,
+ struct files_struct *dirfsp,
+ const char *name,
+ TALLOC_CTX *mem_ctx,
+ char **found_name)
+{
+ VFS_FIND(get_real_filename_at);
+ return handle->fns->get_real_filename_at_fn(
+ handle, dirfsp, name, mem_ctx, found_name);
+}
+
const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname)
{