1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

s3:smbd: add SMB_VFS_READDIR_ATTR() to marshall direntry

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 we used, when there's a need to repurpose some fields in the
the reply, like it's done with Apple's SMB2 extension "AAPL".

We then fetch AAPL metadata with the shiny new SMB_VFS_READDIR_ATTR()
VFS call and marshall appropiately.

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Ralph Boehme 2014-11-26 15:21:36 +01:00 committed by Jeremy Allison
parent 353acb6d29
commit 2236883cde

View File

@ -40,6 +40,7 @@
#include "rpc_server/srv_pipe_hnd.h"
#include "printing.h"
#include "lib/util_ea.h"
#include "lib/readdir_attr.h"
#define DIR_ENTRY_SAFETY_MARGIN 4096
@ -1627,6 +1628,7 @@ static NTSTATUS smbd_marshall_dir_entry(TALLOC_CTX *ctx,
int off;
int pad = 0;
NTSTATUS status;
struct readdir_attr_data *readdir_attr_data = NULL;
ZERO_STRUCT(mdate_ts);
ZERO_STRUCT(adate_ts);
@ -1638,6 +1640,13 @@ static NTSTATUS smbd_marshall_dir_entry(TALLOC_CTX *ctx,
}
allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, NULL, &smb_fname->st);
status = SMB_VFS_READDIR_ATTR(conn, smb_fname, ctx, &readdir_attr_data);
if (!NT_STATUS_IS_OK(status)) {
if (!NT_STATUS_EQUAL(NT_STATUS_NOT_SUPPORTED, status)) {
return status;
}
}
file_index = get_FileIndex(conn, &smb_fname->st);
mdate_ts = smb_fname->st.st_ex_mtime;
@ -2098,17 +2107,41 @@ static NTSTATUS smbd_marshall_dir_entry(TALLOC_CTX *ctx,
q = p; p += 4; /* q is placeholder for name length */
if (mode & FILE_ATTRIBUTE_REPARSE_POINT) {
SIVAL(p, 0, IO_REPARSE_TAG_DFS);
} else if (readdir_attr_data &&
readdir_attr_data->type == RDATTR_AAPL) {
/*
* OS X specific SMB2 extension negotiated via
* AAPL create context: return max_access in
* ea_size field.
*/
SIVAL(p, 0, readdir_attr_data->attr_data.aapl.max_access);
} else {
unsigned int ea_size = estimate_ea_size(conn, NULL,
smb_fname);
SIVAL(p,0,ea_size); /* Extended attributes */
}
p += 4;
/* Clear the short name buffer. This is
* IMPORTANT as not doing so will trigger
* a Win2k client bug. JRA.
*/
if (!was_8_3 && check_mangled_names) {
if (readdir_attr_data &&
readdir_attr_data->type == RDATTR_AAPL) {
/*
* OS X specific SMB2 extension negotiated via
* AAPL create context: return resource fork
* length and compressed FinderInfo in
* shortname field.
*
* According to documentation short_name_len
* should be 0, but on the wire behaviour
* shows its set to 24 by clients.
*/
SSVAL(p, 0, 24);
/* Resourefork length */
SBVAL(p, 2, readdir_attr_data->attr_data.aapl.rfork_size);
/* Compressed FinderInfo */
memcpy(p + 10, &readdir_attr_data->attr_data.aapl.finder_info, 16);
} else if (!was_8_3 && check_mangled_names) {
char mangled_name[13]; /* mangled 8.3 name. */
if (!name_to_8_3(fname,mangled_name,True,
conn->params)) {
@ -2128,10 +2161,29 @@ static NTSTATUS smbd_marshall_dir_entry(TALLOC_CTX *ctx,
}
SSVAL(p, 0, len);
} else {
/* Clear the short name buffer. This is
* IMPORTANT as not doing so will trigger
* a Win2k client bug. JRA.
*/
memset(p,'\0',26);
}
p += 26;
SSVAL(p,0,0); p += 2; /* Reserved ? */
/* Reserved ? */
if (readdir_attr_data &&
readdir_attr_data->type == RDATTR_AAPL) {
/*
* OS X specific SMB2 extension negotiated via
* AAPL create context: return UNIX mode in
* reserved field.
*/
uint16_t aapl_mode = (uint16_t)readdir_attr_data->attr_data.aapl.unix_mode;
SSVAL(p, 0, aapl_mode);
} else {
SSVAL(p, 0, 0);
}
p += 2;
SBVAL(p,0,file_index); p += 8;
status = srvstr_push(base_data, flags2, p,
fname, PTR_DIFF(end_data, p),