1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-21 18:04:06 +03:00

s3: VFS: Add SMB_VFS_PARENT_PATHNAME().

Not yet used.

Default is NTSTATUS version of parent_smb_fname(). Now
to replace all users of parent_smb_fname() with
SMB_VFS_PARENT_PATHNAME() and then remove parent_smb_fname().

Needed due to snapdirseverywhere code in vfs_shadow_copy2.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
This commit is contained in:
Jeremy Allison 2021-05-26 10:39:43 -07:00 committed by Ralph Boehme
parent c500d99e2f
commit 0e75f9ffab
9 changed files with 189 additions and 0 deletions

View File

@ -684,6 +684,15 @@ static NTSTATUS skel_translate_name(struct vfs_handle_struct *handle,
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS skel_parent_pathname(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const struct smb_filename *smb_fname_in,
struct smb_filename **parent_dir_out,
struct smb_filename **atname_out)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
static NTSTATUS skel_fsctl(struct vfs_handle_struct *handle,
struct files_struct *fsp,
TALLOC_CTX *ctx,
@ -1063,6 +1072,7 @@ static struct vfs_fn_pointers skel_opaque_fns = {
.brl_unlock_windows_fn = skel_brl_unlock_windows,
.strict_lock_check_fn = skel_strict_lock_check,
.translate_name_fn = skel_translate_name,
.parent_pathname_fn = skel_parent_pathname,
.fsctl_fn = skel_fsctl,
.freaddir_attr_fn = skel_freaddir_attr,
.audit_file_fn = skel_audit_file,

View File

@ -898,6 +898,19 @@ static NTSTATUS skel_translate_name(struct vfs_handle_struct *handle,
mem_ctx, pmapped_name);
}
static NTSTATUS skel_parent_pathname(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const struct smb_filename *smb_fname_in,
struct smb_filename **parent_dir_out,
struct smb_filename **atname_out)
{
return SMB_VFS_NEXT_PARENT_PATHNAME(handle,
mem_ctx,
smb_fname_in,
parent_dir_out,
atname_out);
}
static NTSTATUS skel_fsctl(struct vfs_handle_struct *handle,
struct files_struct *fsp,
TALLOC_CTX *ctx,
@ -1368,6 +1381,7 @@ static struct vfs_fn_pointers skel_transparent_fns = {
.brl_unlock_windows_fn = skel_brl_unlock_windows,
.strict_lock_check_fn = skel_strict_lock_check,
.translate_name_fn = skel_translate_name,
.parent_pathname_fn = skel_parent_pathname,
.fsctl_fn = skel_fsctl,
.freaddir_attr_fn = skel_freaddir_attr,
.audit_file_fn = skel_audit_file,

View File

@ -354,6 +354,7 @@
* Version 45 - Remove SMB_VFS_READDIR_ATTR
* Version 45 - Add SMB_VFS_SYS_ACL_DELETE_DEF_FD
* Version 45 - Remove SMB_VFS_SYS_ACL_DELETE_DEF_FILE
* Version 45 - Add SMB_VFS_PARENT_PATHNAME
*/
#define SMB_VFS_INTERFACE_VERSION 45
@ -1150,6 +1151,12 @@ struct vfs_fn_pointers {
TALLOC_CTX *mem_ctx,
char **mapped_name);
NTSTATUS (*parent_pathname_fn)(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const struct smb_filename *smb_fname_in,
struct smb_filename **parent_dir_out,
struct smb_filename **atname_out);
NTSTATUS (*fsctl_fn)(struct vfs_handle_struct *handle,
struct files_struct *fsp,
TALLOC_CTX *ctx,
@ -1616,6 +1623,11 @@ NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
enum vfs_translate_direction direction,
TALLOC_CTX *mem_ctx,
char **mapped_name);
NTSTATUS smb_vfs_call_parent_pathname(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const struct smb_filename *smb_fname_in,
struct smb_filename **parent_dir_out,
struct smb_filename **atname_out);
NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
struct files_struct *fsp,
TALLOC_CTX *ctx,
@ -2075,6 +2087,11 @@ NTSTATUS vfs_not_implemented_translate_name(struct vfs_handle_struct *handle,
const char *mapped_name,
enum vfs_translate_direction direction,
TALLOC_CTX *mem_ctx, char **pmapped_name);
NTSTATUS vfs_not_implemented_parent_pathname(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const struct smb_filename *smb_fname_in,
struct smb_filename **parent_dir_out,
struct smb_filename **atname_out);
NTSTATUS vfs_not_implemented_fsctl(struct vfs_handle_struct *handle,
struct files_struct *fsp,
TALLOC_CTX *ctx,

View File

@ -388,6 +388,11 @@
#define SMB_VFS_NEXT_TRANSLATE_NAME(handle, name, direction, mem_ctx, mapped_name) \
smb_vfs_call_translate_name((handle)->next, (name), (direction), (mem_ctx), (mapped_name))
#define SMB_VFS_PARENT_PATHNAME(conn, mem_ctx, smb_fname_in, parent_dir_out, atname_out) \
smb_vfs_call_parent_pathname((conn)->vfs_handles, (mem_ctx), (smb_fname_in), (parent_dir_out), (atname_out))
#define SMB_VFS_NEXT_PARENT_PATHNAME(handle, mem_ctx, smb_fname_in, parent_dir_out, atname_out) \
smb_vfs_call_parent_pathname((handle)->next, (mem_ctx), (smb_fname_in), (parent_dir_out), (atname_out))
#define SMB_VFS_FSCTL(fsp, ctx, function, req_flags, in_data, in_len, out_data, max_out_len, out_len) \
smb_vfs_call_fsctl((fsp)->conn->vfs_handles, (fsp), (ctx), (function), (req_flags), (in_data), (in_len), (out_data), (max_out_len), (out_len))

View File

@ -1325,6 +1325,70 @@ static NTSTATUS vfswrap_translate_name(struct vfs_handle_struct *handle,
return NT_STATUS_NONE_MAPPED;
}
/**
* Return allocated parent directory and basename of path
*
* Note: if requesting name, it is returned as talloc child of the
* parent. Freeing the parent is thus sufficient to free both.
*/
static NTSTATUS vfswrap_parent_pathname(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const struct smb_filename *smb_fname_in,
struct smb_filename **parent_dir_out,
struct smb_filename **atname_out)
{
TALLOC_CTX *frame = talloc_stackframe();
struct smb_filename *parent = NULL;
struct smb_filename *name = NULL;
char *p = NULL;
parent = cp_smb_filename(frame, smb_fname_in);
if (parent == NULL) {
TALLOC_FREE(frame);
return NT_STATUS_NO_MEMORY;
}
TALLOC_FREE(parent->stream_name);
SET_STAT_INVALID(parent->st);
p = strrchr_m(parent->base_name, '/'); /* Find final '/', if any */
if (p == NULL) {
TALLOC_FREE(parent->base_name);
parent->base_name = talloc_strdup(parent, ".");
if (parent->base_name == NULL) {
TALLOC_FREE(frame);
return NT_STATUS_NO_MEMORY;
}
p = smb_fname_in->base_name;
} else {
*p = '\0';
p++;
}
if (atname_out == NULL) {
*parent_dir_out = talloc_move(mem_ctx, &parent);
TALLOC_FREE(frame);
return NT_STATUS_OK;
}
name = cp_smb_filename(frame, smb_fname_in);
if (name == NULL) {
TALLOC_FREE(frame);
return NT_STATUS_NO_MEMORY;
}
TALLOC_FREE(name->base_name);
name->base_name = talloc_strdup(name, p);
if (name->base_name == NULL) {
TALLOC_FREE(frame);
return NT_STATUS_NO_MEMORY;
}
*parent_dir_out = talloc_move(mem_ctx, &parent);
*atname_out = talloc_move(*parent_dir_out, &name);
TALLOC_FREE(frame);
return NT_STATUS_OK;
}
/*
* Implement the default fsctl operation.
*/
@ -3824,6 +3888,7 @@ static struct vfs_fn_pointers vfs_default_fns = {
.brl_unlock_windows_fn = vfswrap_brl_unlock_windows,
.strict_lock_check_fn = vfswrap_strict_lock_check,
.translate_name_fn = vfswrap_translate_name,
.parent_pathname_fn = vfswrap_parent_pathname,
.fsctl_fn = vfswrap_fsctl,
.fset_dos_attributes_fn = vfswrap_fset_dos_attributes,
.get_dos_attributes_send_fn = vfswrap_get_dos_attributes_send,

View File

@ -170,6 +170,7 @@ typedef enum _vfs_op_type {
SMB_VFS_OP_BRL_UNLOCK_WINDOWS,
SMB_VFS_OP_STRICT_LOCK_CHECK,
SMB_VFS_OP_TRANSLATE_NAME,
SMB_VFS_OP_PARENT_PATHNAME,
SMB_VFS_OP_FSCTL,
SMB_VFS_OP_OFFLOAD_READ_SEND,
SMB_VFS_OP_OFFLOAD_READ_RECV,
@ -309,6 +310,7 @@ static struct {
{ SMB_VFS_OP_BRL_UNLOCK_WINDOWS, "brl_unlock_windows" },
{ SMB_VFS_OP_STRICT_LOCK_CHECK, "strict_lock_check" },
{ SMB_VFS_OP_TRANSLATE_NAME, "translate_name" },
{ SMB_VFS_OP_PARENT_PATHNAME, "parent_pathname" },
{ SMB_VFS_OP_FSCTL, "fsctl" },
{ SMB_VFS_OP_OFFLOAD_READ_SEND, "offload_read_send" },
{ SMB_VFS_OP_OFFLOAD_READ_RECV, "offload_read_recv" },
@ -2128,6 +2130,28 @@ static NTSTATUS smb_full_audit_translate_name(struct vfs_handle_struct *handle,
return result;
}
static NTSTATUS smb_full_audit_parent_pathname(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const struct smb_filename *smb_fname_in,
struct smb_filename **parent_dir_out,
struct smb_filename **atname_out)
{
NTSTATUS result;
result = SMB_VFS_NEXT_PARENT_PATHNAME(handle,
mem_ctx,
smb_fname_in,
parent_dir_out,
atname_out);
do_log(SMB_VFS_OP_CONNECTPATH,
NT_STATUS_IS_OK(result),
handle,
"%s",
smb_fname_str_do_log(handle->conn, smb_fname_in));
return result;
}
static NTSTATUS smb_full_audit_fsctl(struct vfs_handle_struct *handle,
struct files_struct *fsp,
TALLOC_CTX *ctx,
@ -2990,6 +3014,7 @@ static struct vfs_fn_pointers vfs_full_audit_fns = {
.brl_unlock_windows_fn = smb_full_audit_brl_unlock_windows,
.strict_lock_check_fn = smb_full_audit_strict_lock_check,
.translate_name_fn = smb_full_audit_translate_name,
.parent_pathname_fn = smb_full_audit_parent_pathname,
.fsctl_fn = smb_full_audit_fsctl,
.get_dos_attributes_send_fn = smb_full_audit_get_dos_attributes_send,
.get_dos_attributes_recv_fn = smb_full_audit_get_dos_attributes_recv,

View File

@ -687,6 +687,15 @@ NTSTATUS vfs_not_implemented_translate_name(struct vfs_handle_struct *handle,
return NT_STATUS_NOT_IMPLEMENTED;
}
NTSTATUS vfs_not_implemented_parent_pathname(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const struct smb_filename *smb_fname_in,
struct smb_filename **parent_dir_out,
struct smb_filename **atname_out)
{
return NT_STATUS_NOT_IMPLEMENTED;
}
NTSTATUS vfs_not_implemented_fsctl(struct vfs_handle_struct *handle,
struct files_struct *fsp,
TALLOC_CTX *ctx,
@ -1067,6 +1076,7 @@ static struct vfs_fn_pointers vfs_not_implemented_fns = {
.brl_unlock_windows_fn = vfs_not_implemented_brl_unlock_windows,
.strict_lock_check_fn = vfs_not_implemented_strict_lock_check,
.translate_name_fn = vfs_not_implemented_translate_name,
.parent_pathname_fn = vfs_not_implemented_parent_pathname,
.fsctl_fn = vfs_not_implemented_fsctl,
.freaddir_attr_fn = vfs_not_implemented_freaddir_attr,
.audit_file_fn = vfs_not_implemented_audit_file,

View File

@ -1797,6 +1797,34 @@ static NTSTATUS smb_time_audit_translate_name(struct vfs_handle_struct *handle,
return result;
}
static NTSTATUS smb_time_audit_parent_pathname(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const struct smb_filename *smb_fname_in,
struct smb_filename **parent_dir_out,
struct smb_filename **atname_out)
{
NTSTATUS result;
struct timespec ts1,ts2;
double timediff;
clock_gettime_mono(&ts1);
result = SMB_VFS_NEXT_PARENT_PATHNAME(handle,
mem_ctx,
smb_fname_in,
parent_dir_out,
atname_out);
clock_gettime_mono(&ts2);
timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
if (timediff > audit_timeout) {
smb_time_audit_log_fname("parent_pathname",
timediff,
smb_fname_in->base_name);
}
return result;
}
static NTSTATUS smb_time_audit_fsctl(struct vfs_handle_struct *handle,
struct files_struct *fsp,
TALLOC_CTX *ctx,
@ -2821,6 +2849,7 @@ static struct vfs_fn_pointers vfs_time_audit_fns = {
.brl_unlock_windows_fn = smb_time_audit_brl_unlock_windows,
.strict_lock_check_fn = smb_time_audit_strict_lock_check,
.translate_name_fn = smb_time_audit_translate_name,
.parent_pathname_fn = smb_time_audit_parent_pathname,
.fsctl_fn = smb_time_audit_fsctl,
.get_dos_attributes_send_fn = smb_time_audit_get_dos_attributes_send,
.get_dos_attributes_recv_fn = smb_time_audit_get_dos_attributes_recv,

View File

@ -2449,6 +2449,20 @@ NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
mapped_name);
}
NTSTATUS smb_vfs_call_parent_pathname(struct vfs_handle_struct *handle,
TALLOC_CTX *mem_ctx,
const struct smb_filename *smb_fname_in,
struct smb_filename **parent_dir_out,
struct smb_filename **atname_out)
{
VFS_FIND(parent_pathname);
return handle->fns->parent_pathname_fn(handle,
mem_ctx,
smb_fname_in,
parent_dir_out,
atname_out);
}
NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
struct files_struct *fsp,
TALLOC_CTX *ctx,