summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/VFS/skel_opaque.c9
-rw-r--r--examples/VFS/skel_transparent.c9
-rw-r--r--source3/include/smb.h1
-rw-r--r--source3/include/vfs.h10
-rw-r--r--source3/include/vfs_macros.h5
-rw-r--r--source3/lib/readdir_attr.h37
-rw-r--r--source3/modules/vfs_default.c9
-rw-r--r--source3/modules/vfs_full_audit.c18
-rw-r--r--source3/modules/vfs_time_audit.c22
-rw-r--r--source3/smbd/vfs.c9
10 files changed, 129 insertions, 0 deletions
diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index 47b46a4db7..6e15a0675b 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -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. */
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index fbb1323a6e..b11e29c342 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -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. */
diff --git a/source3/include/smb.h b/source3/include/smb.h
index a6589dbac7..46e05c064d 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -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 {
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index e7dc07998d..b10e9a54be 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -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);
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index e2d494dca6..df676adaca 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -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 */
diff --git a/source3/lib/readdir_attr.h b/source3/lib/readdir_attr.h
new file mode 100644
index 0000000000..d2a814dba3
--- /dev/null
+++ b/source3/lib/readdir_attr.h
@@ -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 */
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 2ac7100cd7..7610e65906 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -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,
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index a51ab75815..489a28c58b 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -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,
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index 9dbbf8bdea..243238a99e 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -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,
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 8e33f2d1a8..4b9696393a 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -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);
+}