mirror of
https://github.com/samba-team/samba.git
synced 2025-03-27 22:50:26 +03:00
s3:vfs: add SMB_VFS_READDIR_ATTR()
SMB_VFS_READDIR_ATTR is a last minute hook to fetch additional metadata for a directory entry when we're already marshalling the SMB reply buffer. This would be used, when there's a need to repurpose some fields in the the reply, like it's done with Apple's SMB2 extension "AAPL". Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
parent
46431e390f
commit
b65e37dc01
@ -633,6 +633,14 @@ static NTSTATUS skel_fsctl(struct vfs_handle_struct *handle,
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static NTSTATUS skel_readdir_attr(struct vfs_handle_struct *handle,
|
||||
const struct smb_filename *fname,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct readdir_attr_data **pattr_data)
|
||||
{
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
static NTSTATUS skel_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
|
||||
uint32 security_info,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
@ -896,6 +904,7 @@ struct vfs_fn_pointers skel_opaque_fns = {
|
||||
.strict_unlock_fn = skel_strict_unlock,
|
||||
.translate_name_fn = skel_translate_name,
|
||||
.fsctl_fn = skel_fsctl,
|
||||
.readdir_attr_fn = skel_readdir_attr,
|
||||
|
||||
/* NT ACL operations. */
|
||||
|
||||
|
@ -759,6 +759,14 @@ static NTSTATUS skel_fsctl(struct vfs_handle_struct *handle,
|
||||
in_len, _out_data, max_out_len, out_len);
|
||||
}
|
||||
|
||||
static NTSTATUS skel_readdir_attr(struct vfs_handle_struct *handle,
|
||||
const struct smb_filename *fname,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct readdir_attr_data **pattr_data)
|
||||
{
|
||||
return SMB_VFS_NEXT_READDIR_ATTR(handle, fname, mem_ctx, pattr_data);
|
||||
}
|
||||
|
||||
static NTSTATUS skel_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
|
||||
uint32 security_info,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
@ -1005,6 +1013,7 @@ struct vfs_fn_pointers skel_transparent_fns = {
|
||||
.strict_unlock_fn = skel_strict_unlock,
|
||||
.translate_name_fn = skel_translate_name,
|
||||
.fsctl_fn = skel_fsctl,
|
||||
.readdir_attr_fn = skel_readdir_attr,
|
||||
|
||||
/* NT ACL operations. */
|
||||
|
||||
|
@ -152,6 +152,7 @@ struct sys_notify_context {
|
||||
/* Include VFS stuff */
|
||||
|
||||
#include "smb_acls.h"
|
||||
#include "lib/readdir_attr.h"
|
||||
#include "vfs.h"
|
||||
|
||||
struct current_user {
|
||||
|
@ -159,6 +159,7 @@
|
||||
/* Bump to version 32 - Samba 4.2 will ship with that. */
|
||||
/* Version 32 - Add "lease" to CREATE_FILE operation */
|
||||
/* Version 32 - Add "lease" to struct files_struct */
|
||||
/* Version 32 - Add SMB_VFS_READDIR_ATTR() */
|
||||
|
||||
#define SMB_VFS_INTERFACE_VERSION 32
|
||||
|
||||
@ -789,6 +790,11 @@ struct vfs_fn_pointers {
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct files_struct **fsp,
|
||||
DATA_BLOB *new_cookie);
|
||||
|
||||
NTSTATUS (*readdir_attr_fn)(struct vfs_handle_struct *handle,
|
||||
const struct smb_filename *fname,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct readdir_attr_data **attr_data);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1234,6 +1240,10 @@ NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct files_struct **fsp,
|
||||
DATA_BLOB *new_cookie);
|
||||
NTSTATUS smb_vfs_call_readdir_attr(struct vfs_handle_struct *handle,
|
||||
const struct smb_filename *fname,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct readdir_attr_data **attr_data);
|
||||
|
||||
NTSTATUS smb_register_vfs(int version, const char *name,
|
||||
const struct vfs_fn_pointers *fns);
|
||||
|
@ -565,4 +565,9 @@
|
||||
(smb1req), (op), (old_cookie), \
|
||||
(mem_ctx), (fsp), (new_cookie))
|
||||
|
||||
#define SMB_VFS_READDIR_ATTR(conn, fname, mem_ctx, attr_data) \
|
||||
smb_vfs_call_readdir_attr((conn)->vfs_handles, (fname), (mem_ctx), (attr_data))
|
||||
#define SMB_VFS_NEXT_READDIR_ATTR(conn, fname, mem_ctx, attr_data) \
|
||||
smb_vfs_call_readdir_attr((handle)->next, (fname), (mem_ctx), (attr_data))
|
||||
|
||||
#endif /* _VFS_MACROS_H */
|
||||
|
37
source3/lib/readdir_attr.h
Normal file
37
source3/lib/readdir_attr.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Fetch filesystem metadata in readdir/marshall context
|
||||
*
|
||||
* Copyright (C) Ralph Boehme 2014
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _READDIR_ATTR_H
|
||||
#define _READDIR_ATTR_H
|
||||
|
||||
enum readdir_attr_type {RDATTR_NONE, RDATTR_AAPL};
|
||||
|
||||
struct readdir_attr_data {
|
||||
enum readdir_attr_type type;
|
||||
union attr_data {
|
||||
struct aapl {
|
||||
uint64_t rfork_size;
|
||||
char finder_info[16];
|
||||
uint32_t max_access;
|
||||
mode_t unix_mode;
|
||||
} aapl;
|
||||
} attr_data;
|
||||
};
|
||||
|
||||
#endif /* _READDIR_ATTR_H */
|
@ -403,6 +403,14 @@ static struct dirent *vfswrap_readdir(vfs_handle_struct *handle,
|
||||
return result;
|
||||
}
|
||||
|
||||
static NTSTATUS vfswrap_readdir_attr(struct vfs_handle_struct *handle,
|
||||
const struct smb_filename *fname,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct readdir_attr_data **attr_data)
|
||||
{
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static void vfswrap_seekdir(vfs_handle_struct *handle, DIR *dirp, long offset)
|
||||
{
|
||||
START_PROFILE(syscall_seekdir);
|
||||
@ -2521,6 +2529,7 @@ static struct vfs_fn_pointers vfs_default_fns = {
|
||||
.opendir_fn = vfswrap_opendir,
|
||||
.fdopendir_fn = vfswrap_fdopendir,
|
||||
.readdir_fn = vfswrap_readdir,
|
||||
.readdir_attr_fn = vfswrap_readdir_attr,
|
||||
.seekdir_fn = vfswrap_seekdir,
|
||||
.telldir_fn = vfswrap_telldir,
|
||||
.rewind_dir_fn = vfswrap_rewinddir,
|
||||
|
@ -171,6 +171,7 @@ typedef enum _vfs_op_type {
|
||||
SMB_VFS_OP_COPY_CHUNK_RECV,
|
||||
SMB_VFS_OP_GET_COMPRESSION,
|
||||
SMB_VFS_OP_SET_COMPRESSION,
|
||||
SMB_VFS_OP_READDIR_ATTR,
|
||||
|
||||
/* NT ACL operations. */
|
||||
|
||||
@ -295,6 +296,7 @@ static struct {
|
||||
{ SMB_VFS_OP_COPY_CHUNK_RECV, "copy_chunk_recv" },
|
||||
{ SMB_VFS_OP_GET_COMPRESSION, "get_compression" },
|
||||
{ SMB_VFS_OP_SET_COMPRESSION, "set_compression" },
|
||||
{ SMB_VFS_OP_READDIR_ATTR, "readdir_attr" },
|
||||
{ SMB_VFS_OP_FGET_NT_ACL, "fget_nt_acl" },
|
||||
{ SMB_VFS_OP_GET_NT_ACL, "get_nt_acl" },
|
||||
{ SMB_VFS_OP_FSET_NT_ACL, "fset_nt_acl" },
|
||||
@ -1834,6 +1836,21 @@ static NTSTATUS smb_full_audit_set_compression(vfs_handle_struct *handle,
|
||||
return result;
|
||||
}
|
||||
|
||||
static NTSTATUS smb_full_audit_readdir_attr(struct vfs_handle_struct *handle,
|
||||
const struct smb_filename *fname,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct readdir_attr_data **pattr_data)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
status = SMB_VFS_NEXT_READDIR_ATTR(handle, fname, mem_ctx, pattr_data);
|
||||
|
||||
do_log(SMB_VFS_OP_READDIR_ATTR, NT_STATUS_IS_OK(status), handle, "%s",
|
||||
smb_fname_str_do_log(fname));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
|
||||
uint32 security_info,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
@ -2249,6 +2266,7 @@ static struct vfs_fn_pointers vfs_full_audit_fns = {
|
||||
.copy_chunk_recv_fn = smb_full_audit_copy_chunk_recv,
|
||||
.get_compression_fn = smb_full_audit_get_compression,
|
||||
.set_compression_fn = smb_full_audit_set_compression,
|
||||
.readdir_attr_fn = smb_full_audit_readdir_attr,
|
||||
.fget_nt_acl_fn = smb_full_audit_fget_nt_acl,
|
||||
.get_nt_acl_fn = smb_full_audit_get_nt_acl,
|
||||
.fset_nt_acl_fn = smb_full_audit_fset_nt_acl,
|
||||
|
@ -1802,6 +1802,27 @@ static NTSTATUS smb_time_audit_set_compression(vfs_handle_struct *handle,
|
||||
return result;
|
||||
}
|
||||
|
||||
static NTSTATUS smb_time_audit_readdir_attr(struct vfs_handle_struct *handle,
|
||||
const struct smb_filename *fname,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct readdir_attr_data **pattr_data)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct timespec ts1,ts2;
|
||||
double timediff;
|
||||
|
||||
clock_gettime_mono(&ts1);
|
||||
status = SMB_VFS_NEXT_READDIR_ATTR(handle, fname, mem_ctx, pattr_data);
|
||||
clock_gettime_mono(&ts2);
|
||||
timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
|
||||
|
||||
if (timediff > audit_timeout) {
|
||||
smb_time_audit_log_smb_fname("readdir_attr", timediff, fname);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static NTSTATUS smb_time_audit_fget_nt_acl(vfs_handle_struct *handle,
|
||||
files_struct *fsp,
|
||||
uint32 security_info,
|
||||
@ -2423,6 +2444,7 @@ static struct vfs_fn_pointers vfs_time_audit_fns = {
|
||||
.copy_chunk_recv_fn = smb_time_audit_copy_chunk_recv,
|
||||
.get_compression_fn = smb_time_audit_get_compression,
|
||||
.set_compression_fn = smb_time_audit_set_compression,
|
||||
.readdir_attr_fn = smb_time_audit_readdir_attr,
|
||||
.fget_nt_acl_fn = smb_time_audit_fget_nt_acl,
|
||||
.get_nt_acl_fn = smb_time_audit_get_nt_acl,
|
||||
.fset_nt_acl_fn = smb_time_audit_fset_nt_acl,
|
||||
|
@ -2461,3 +2461,12 @@ NTSTATUS smb_vfs_call_durable_reconnect(struct vfs_handle_struct *handle,
|
||||
old_cookie, mem_ctx, fsp,
|
||||
new_cookie);
|
||||
}
|
||||
|
||||
NTSTATUS smb_vfs_call_readdir_attr(struct vfs_handle_struct *handle,
|
||||
const struct smb_filename *fname,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct readdir_attr_data **attr_data)
|
||||
{
|
||||
VFS_FIND(readdir_attr);
|
||||
return handle->fns->readdir_attr_fn(handle, fname, mem_ctx, attr_data);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user