From: Jeremy Allison Date: Wed, 26 May 2021 17:39:43 +0000 (-0700) Subject: s3: VFS: Add SMB_VFS_PARENT_PATHNAME(). X-Git-Tag: tevent-0.11.0~685 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0e75f9ffabc751231e80f9583837f6afbc2d6233;p=thirdparty%2Fsamba.git 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 Reviewed-by: Ralph Boehme --- diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index 487919f38a8..4ac5e61f1ff 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -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, diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index a0a747d8b57..9138bde0872 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -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, diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 02293c64733..0f01da81148 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -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, diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index 018d60ce914..71492b4db79 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -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)) diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index e384f8885d1..77e709f2449 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -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, diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index 85ba9ef2418..32e7879f7da 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -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, diff --git a/source3/modules/vfs_not_implemented.c b/source3/modules/vfs_not_implemented.c index 9cde162c593..8b93b3444e2 100644 --- a/source3/modules/vfs_not_implemented.c +++ b/source3/modules/vfs_not_implemented.c @@ -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, diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c index d53e97cef49..28196b55a8d 100644 --- a/source3/modules/vfs_time_audit.c +++ b/source3/modules/vfs_time_audit.c @@ -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, diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 281ceeccbbb..e79ca25ab34 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -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,