The Samba-Bugzilla – Attachment 10491 Details for
Bug 10983
Backport AAPL patches from master
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patches for v4-2-test
tmp42.diff.txt (text/plain), 84.56 KB, created by
Stefan Metzmacher
on 2014-12-05 10:25:55 UTC
(
hide
)
Description:
Patches for v4-2-test
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2014-12-05 10:25:55 UTC
Size:
84.56 KB
patch
obsolete
>From 68ac90a6847b8dee49aee821358b0e56fcfeca68 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Wed, 26 Nov 2014 14:30:37 +0100 >Subject: [PATCH 01/12] 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> >(cherry picked from commit b65e37dc01d7afa007768f7cadfcf3b7c1007664) >--- > examples/VFS/skel_opaque.c | 9 +++++++++ > examples/VFS/skel_transparent.c | 9 +++++++++ > source3/include/smb.h | 1 + > source3/include/vfs.h | 10 ++++++++++ > source3/include/vfs_macros.h | 5 +++++ > source3/lib/readdir_attr.h | 37 +++++++++++++++++++++++++++++++++++++ > source3/modules/vfs_default.c | 9 +++++++++ > source3/modules/vfs_full_audit.c | 18 ++++++++++++++++++ > source3/modules/vfs_time_audit.c | 22 ++++++++++++++++++++++ > source3/smbd/vfs.c | 9 +++++++++ > 10 files changed, 129 insertions(+) > create mode 100644 source3/lib/readdir_attr.h > >diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c >index 47b46a4..6e15a06 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 fbb1323..b11e29c 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 7bace88..8af44b2 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 e7dc079..b10e9a5 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 e2d494d..df676ad 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 0000000..d2a814d >--- /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 3a3943b..834c866 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); >@@ -2511,6 +2519,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 a51ab75..489a28c 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 9dbbf8b..243238a 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 8e33f2d..4b96963 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); >+} >-- >1.9.1 > > >From 48d8ed9b35d03641091f6d96bd92150dd9d1c3ab Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Fri, 28 Nov 2014 11:44:09 +0100 >Subject: [PATCH 02/12] s3:smbd: allocate out_context_blobs with talloc > >By tallocing the out_context_blobs instead of using an automatic stack >variable, we can use out_context_blobs as talloc parent for individual >create tag that we add via smb2_create_blob_add(). > >This is in preperation of a SMB_VFS_CREATE_FILE modification where I add >the in and out_context_blobs as additional args. With this change in >place we can add create tags to out_context_blobs from there too. > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit af846264d89f21ac7db8d0cdf6e861ba9cc74151) >--- > source3/smbd/smb2_create.c | 37 +++++++++++++++++++++---------------- > 1 file changed, 21 insertions(+), 16 deletions(-) > >diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c >index 26d285c..77e0c96 100644 >--- a/source3/smbd/smb2_create.c >+++ b/source3/smbd/smb2_create.c >@@ -445,7 +445,7 @@ struct smbd_smb2_create_state { > uint32_t out_file_attributes; > uint64_t out_file_id_persistent; > uint64_t out_file_id_volatile; >- struct smb2_create_blobs out_context_blobs; >+ struct smb2_create_blobs *out_context_blobs; > }; > > static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, >@@ -467,7 +467,6 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, > struct smb_request *smb1req = NULL; > files_struct *result = NULL; > int info; >- struct smb2_create_blobs out_context_blobs; > int requested_oplock_level; > struct smb2_create_blob *dhnc = NULL; > struct smb2_create_blob *dh2c = NULL; >@@ -476,8 +475,6 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, > struct smb2_create_blob *rqls = NULL; > struct smbXsrv_open *op = NULL; > >- ZERO_STRUCT(out_context_blobs); >- > if(lp_fake_oplocks(SNUM(smb2req->tcon->compat))) { > requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE; > } else { >@@ -508,10 +505,16 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, > state = tevent_req_data(req, > struct smbd_smb2_create_state); > smb1req = state->smb1req; >+ TALLOC_FREE(state->out_context_blobs); > DEBUG(10,("smbd_smb2_create_send: reentrant for file %s\n", > in_name )); > } > >+ state->out_context_blobs = talloc_zero(state, struct smb2_create_blobs); >+ if (tevent_req_nomem(state->out_context_blobs, req)) { >+ return tevent_req_post(req, ev); >+ } >+ > dhnq = smb2_create_blob_find(&in_context_blobs, > SMB2_CREATE_TAG_DHNQ); > dhnc = smb2_create_blob_find(&in_context_blobs, >@@ -1105,10 +1108,11 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, > SIVAL(p, 0, NT_STATUS_V(status)); > SIVAL(p, 4, max_access_granted); > >- status = smb2_create_blob_add(state, >- &out_context_blobs, >- SMB2_CREATE_TAG_MXAC, >- blob); >+ status = smb2_create_blob_add( >+ state->out_context_blobs, >+ state->out_context_blobs, >+ SMB2_CREATE_TAG_MXAC, >+ blob); > if (!NT_STATUS_IS_OK(status)) { > tevent_req_nterror(req, status); > return tevent_req_post(req, ev); >@@ -1150,8 +1154,8 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, > uint8_t p[8] = { 0, }; > DATA_BLOB blob = data_blob_const(p, sizeof(p)); > >- status = smb2_create_blob_add(state, >- &out_context_blobs, >+ status = smb2_create_blob_add(state->out_context_blobs, >+ state->out_context_blobs, > SMB2_CREATE_TAG_DHNQ, > blob); > if (!NT_STATUS_IS_OK(status)) { >@@ -1168,7 +1172,8 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, > SIVAL(p, 0, op->global->durable_timeout_msec); > SIVAL(p, 4, durable_v2_response_flags); > >- status = smb2_create_blob_add(state, &out_context_blobs, >+ status = smb2_create_blob_add(state->out_context_blobs, >+ state->out_context_blobs, > SMB2_CREATE_TAG_DH2Q, > blob); > if (!NT_STATUS_IS_OK(status)) { >@@ -1192,7 +1197,8 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, > SBVAL(p, 0, file_index); > SIVAL(p, 8, result->fsp_name->st.st_ex_dev);/* FileIndexHigh */ > >- status = smb2_create_blob_add(state, &out_context_blobs, >+ status = smb2_create_blob_add(state->out_context_blobs, >+ state->out_context_blobs, > SMB2_CREATE_TAG_QFID, > blob); > if (!NT_STATUS_IS_OK(status)) { >@@ -1218,7 +1224,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, > } > > status = smb2_create_blob_add( >- state, &out_context_blobs, >+ state, state->out_context_blobs, > SMB2_CREATE_TAG_RQLS, > data_blob_const(buf, lease_len)); > if (!NT_STATUS_IS_OK(status)) { >@@ -1260,7 +1266,6 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, > } > state->out_file_id_persistent = result->op->global->open_persistent_id; > state->out_file_id_volatile = result->op->global->open_volatile_id; >- state->out_context_blobs = out_context_blobs; > > DEBUG(10,("smbd_smb2_create_send: %s - %s\n", > fsp_str_dbg(result), fsp_fnum_dbg(result))); >@@ -1304,9 +1309,9 @@ static NTSTATUS smbd_smb2_create_recv(struct tevent_req *req, > *out_file_attributes = state->out_file_attributes; > *out_file_id_persistent = state->out_file_id_persistent; > *out_file_id_volatile = state->out_file_id_volatile; >- *out_context_blobs = state->out_context_blobs; >+ *out_context_blobs = *(state->out_context_blobs); > >- talloc_steal(mem_ctx, state->out_context_blobs.blobs); >+ talloc_steal(mem_ctx, state->out_context_blobs->blobs); > > tevent_req_received(req); > return NT_STATUS_OK; >-- >1.9.1 > > >From 48e71d5a4c06e0c0591e82742fa65f3872a16247 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Wed, 26 Nov 2014 14:12:51 +0100 >Subject: [PATCH 03/12] s3:vfs: add create tags to SMB_VFS_CREATEFILE > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 142db4048f41f793d9b919a93877d547ff593c6d) >--- > examples/VFS/skel_opaque.c | 4 +++- > examples/VFS/skel_transparent.c | 7 +++++-- > source3/include/vfs.h | 9 +++++++-- > source3/include/vfs_macros.h | 12 +++++++----- > source3/modules/vfs_default.c | 6 ++++-- > source3/modules/vfs_fruit.c | 7 +++++-- > source3/modules/vfs_full_audit.c | 7 +++++-- > source3/modules/vfs_media_harmony.c | 12 +++++++++--- > source3/modules/vfs_time_audit.c | 7 +++++-- > source3/modules/vfs_worm.c | 7 +++++-- > source3/printing/nt_printing.c | 9 ++++++--- > source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 6 ++++-- > source3/smbd/dosmode.c | 3 ++- > source3/smbd/nttrans.c | 12 ++++++++---- > source3/smbd/open.c | 10 +++++++--- > source3/smbd/proto.h | 6 ++++-- > source3/smbd/reply.c | 30 ++++++++++++++++++++---------- > source3/smbd/smb2_create.c | 4 +++- > source3/smbd/trans2.c | 18 ++++++++++++------ > source3/smbd/vfs.c | 6 ++++-- > 20 files changed, 125 insertions(+), 57 deletions(-) > >diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c >index 6e15a06..b52c381 100644 >--- a/examples/VFS/skel_opaque.c >+++ b/examples/VFS/skel_opaque.c >@@ -174,7 +174,9 @@ static NTSTATUS skel_create_file(struct vfs_handle_struct *handle, > uint32_t private_flags, > struct security_descriptor *sd, > struct ea_list *ea_list, >- files_struct **result, int *pinfo) >+ files_struct **result, int *pinfo, >+ const struct smb2_create_blobs *in_context_blobs, >+ struct smb2_create_blobs *out_context_blobs) > { > return NT_STATUS_NOT_IMPLEMENTED; > } >diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c >index b11e29c..925e520 100644 >--- a/examples/VFS/skel_transparent.c >+++ b/examples/VFS/skel_transparent.c >@@ -169,7 +169,9 @@ static NTSTATUS skel_create_file(struct vfs_handle_struct *handle, > uint32_t private_flags, > struct security_descriptor *sd, > struct ea_list *ea_list, >- files_struct ** result, int *pinfo) >+ files_struct ** result, int *pinfo, >+ const struct smb2_create_blobs *in_context_blobs, >+ struct smb2_create_blobs *out_context_blobs) > { > return SMB_VFS_NEXT_CREATE_FILE(handle, > req, >@@ -184,7 +186,8 @@ static NTSTATUS skel_create_file(struct vfs_handle_struct *handle, > lease, > allocation_size, > private_flags, >- sd, ea_list, result, pinfo); >+ sd, ea_list, result, pinfo, >+ in_context_blobs, out_context_blobs); > } > > static int skel_close_fn(vfs_handle_struct *handle, files_struct *fsp) >diff --git a/source3/include/vfs.h b/source3/include/vfs.h >index b10e9a5..1843ef4 100644 >--- a/source3/include/vfs.h >+++ b/source3/include/vfs.h >@@ -160,6 +160,7 @@ > /* Version 32 - Add "lease" to CREATE_FILE operation */ > /* Version 32 - Add "lease" to struct files_struct */ > /* Version 32 - Add SMB_VFS_READDIR_ATTR() */ >+/* Version 32 - Add in and our create context blobs to create_file */ > > #define SMB_VFS_INTERFACE_VERSION 32 > >@@ -553,7 +554,9 @@ struct vfs_fn_pointers { > struct security_descriptor *sd, > struct ea_list *ea_list, > files_struct **result, >- int *pinfo); >+ int *pinfo, >+ const struct smb2_create_blobs *in_context_blobs, >+ struct smb2_create_blobs *out_context_blobs); > int (*close_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp); > ssize_t (*read_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, void *data, size_t n); > ssize_t (*pread_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, void *data, size_t n, off_t offset); >@@ -964,7 +967,9 @@ NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle, > struct security_descriptor *sd, > struct ea_list *ea_list, > files_struct **result, >- int *pinfo); >+ int *pinfo, >+ const struct smb2_create_blobs *in_context_blobs, >+ struct smb2_create_blobs *out_context_blobs); > int smb_vfs_call_close(struct vfs_handle_struct *handle, > struct files_struct *fsp); > ssize_t smb_vfs_call_read(struct vfs_handle_struct *handle, >diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h >index df676ad..ef97b49 100644 >--- a/source3/include/vfs_macros.h >+++ b/source3/include/vfs_macros.h >@@ -136,13 +136,15 @@ > smb_vfs_call_open((handle)->next, (fname), (fsp), (flags), (mode)) > > #define SMB_VFS_CREATE_FILE(conn, req, root_dir_fid, smb_fname, access_mask, share_access, create_disposition, \ >- create_options, file_attributes, oplock_request, lease, allocation_size, private_flags, sd, ea_list, result, pinfo) \ >- smb_vfs_call_create_file((conn)->vfs_handles, (req), (root_dir_fid), (smb_fname), (access_mask), (share_access), (create_disposition), \ >- (create_options), (file_attributes), (oplock_request), (lease), (allocation_size), (private_flags), (sd), (ea_list), (result), (pinfo)) >+ create_options, file_attributes, oplock_request, lease, allocation_size, private_flags, sd, ea_list, result, pinfo, in_context_blobs, out_context_blobs) \ >+ smb_vfs_call_create_file((conn)->vfs_handles, (req), (root_dir_fid), (smb_fname), (access_mask), (share_access), (create_disposition), \ >+ (create_options), (file_attributes), (oplock_request), (lease), (allocation_size), (private_flags), (sd), (ea_list), (result), (pinfo), \ >+ (in_context_blobs), (out_context_blobs)) > #define SMB_VFS_NEXT_CREATE_FILE(handle, req, root_dir_fid, smb_fname, access_mask, share_access, create_disposition, \ >- create_options, file_attributes, oplock_request, lease, allocation_size, private_flags, sd, ea_list, result, pinfo) \ >+ create_options, file_attributes, oplock_request, lease, allocation_size, private_flags, sd, ea_list, result, pinfo, in_context_blobs, out_context_blobs) \ > smb_vfs_call_create_file((handle)->next, (req), (root_dir_fid), (smb_fname), (access_mask), (share_access), (create_disposition), \ >- (create_options), (file_attributes), (oplock_request), (lease), (allocation_size), (private_flags), (sd), (ea_list), (result), (pinfo)) >+ (create_options), (file_attributes), (oplock_request), (lease), (allocation_size), (private_flags), (sd), (ea_list), (result), (pinfo), \ >+ (in_context_blobs), (out_context_blobs)) > > #define SMB_VFS_CLOSE(fsp) \ > smb_vfs_call_close((fsp)->conn->vfs_handles, (fsp)) >diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c >index 834c866..b740de9 100644 >--- a/source3/modules/vfs_default.c >+++ b/source3/modules/vfs_default.c >@@ -531,7 +531,9 @@ static NTSTATUS vfswrap_create_file(vfs_handle_struct *handle, > struct security_descriptor *sd, > struct ea_list *ea_list, > files_struct **result, >- int *pinfo) >+ int *pinfo, >+ const struct smb2_create_blobs *in_context_blobs, >+ struct smb2_create_blobs *out_context_blobs) > { > return create_file_default(handle->conn, req, root_dir_fid, smb_fname, > access_mask, share_access, >@@ -539,7 +541,7 @@ static NTSTATUS vfswrap_create_file(vfs_handle_struct *handle, > file_attributes, oplock_request, lease, > allocation_size, private_flags, > sd, ea_list, result, >- pinfo); >+ pinfo, in_context_blobs, out_context_blobs); > } > > static int vfswrap_close(vfs_handle_struct *handle, files_struct *fsp) >diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c >index c1555f0..ec75d27 100644 >--- a/source3/modules/vfs_fruit.c >+++ b/source3/modules/vfs_fruit.c >@@ -2874,7 +2874,9 @@ static NTSTATUS fruit_create_file(vfs_handle_struct *handle, > struct security_descriptor *sd, > struct ea_list *ea_list, > files_struct **result, >- int *pinfo) >+ int *pinfo, >+ const struct smb2_create_blobs *in_context_blobs, >+ struct smb2_create_blobs *out_context_blobs) > { > NTSTATUS status; > struct fruit_config_data *config = NULL; >@@ -2887,7 +2889,8 @@ static NTSTATUS fruit_create_file(vfs_handle_struct *handle, > lease, > allocation_size, private_flags, > sd, ea_list, result, >- pinfo); >+ pinfo, >+ in_context_blobs, out_context_blobs); > > if (!NT_STATUS_IS_OK(status)) { > return status; >diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c >index 489a28c..c5a9c0d 100644 >--- a/source3/modules/vfs_full_audit.c >+++ b/source3/modules/vfs_full_audit.c >@@ -871,7 +871,9 @@ static NTSTATUS smb_full_audit_create_file(vfs_handle_struct *handle, > struct security_descriptor *sd, > struct ea_list *ea_list, > files_struct **result_fsp, >- int *pinfo) >+ int *pinfo, >+ const struct smb2_create_blobs *in_context_blobs, >+ struct smb2_create_blobs *out_context_blobs) > { > NTSTATUS result; > const char* str_create_disposition; >@@ -916,7 +918,8 @@ static NTSTATUS smb_full_audit_create_file(vfs_handle_struct *handle, > sd, /* sd */ > ea_list, /* ea_list */ > result_fsp, /* result */ >- pinfo); /* pinfo */ >+ pinfo, /* pinfo */ >+ in_context_blobs, out_context_blobs); /* create context */ > > do_log(SMB_VFS_OP_CREATE_FILE, (NT_STATUS_IS_OK(result)), handle, > "0x%x|%s|%s|%s", access_mask, >diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c >index 2418349..f1264c7 100644 >--- a/source3/modules/vfs_media_harmony.c >+++ b/source3/modules/vfs_media_harmony.c >@@ -1210,7 +1210,9 @@ static NTSTATUS mh_create_file(vfs_handle_struct *handle, > struct security_descriptor *sd, > struct ea_list *ea_list, > files_struct **result_fsp, >- int *pinfo) >+ int *pinfo, >+ const struct smb2_create_blobs *in_context_blobs, >+ struct smb2_create_blobs *out_context_blobs) > { > NTSTATUS status; > struct smb_filename *clientFname; >@@ -1238,7 +1240,9 @@ static NTSTATUS mh_create_file(vfs_handle_struct *handle, > sd, > ea_list, > result_fsp, >- pinfo); >+ pinfo, >+ in_context_blobs, >+ out_context_blobs); > goto out; > } > >@@ -1275,7 +1279,9 @@ static NTSTATUS mh_create_file(vfs_handle_struct *handle, > sd, > ea_list, > result_fsp, >- pinfo); >+ pinfo, >+ in_context_blobs, >+ out_context_blobs); > err: > TALLOC_FREE(clientFname); > out: >diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c >index 243238a..4ce9238 100644 >--- a/source3/modules/vfs_time_audit.c >+++ b/source3/modules/vfs_time_audit.c >@@ -502,7 +502,9 @@ static NTSTATUS smb_time_audit_create_file(vfs_handle_struct *handle, > struct security_descriptor *sd, > struct ea_list *ea_list, > files_struct **result_fsp, >- int *pinfo) >+ int *pinfo, >+ const struct smb2_create_blobs *in_context_blobs, >+ struct smb2_create_blobs *out_context_blobs) > { > NTSTATUS result; > struct timespec ts1,ts2; >@@ -526,7 +528,8 @@ static NTSTATUS smb_time_audit_create_file(vfs_handle_struct *handle, > sd, /* sd */ > ea_list, /* ea_list */ > result_fsp, /* result */ >- pinfo); >+ pinfo, >+ in_context_blobs, out_context_blobs); /* create context */ > clock_gettime_mono(&ts2); > timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9; > >diff --git a/source3/modules/vfs_worm.c b/source3/modules/vfs_worm.c >index 3097419..9638d96 100644 >--- a/source3/modules/vfs_worm.c >+++ b/source3/modules/vfs_worm.c >@@ -38,7 +38,9 @@ static NTSTATUS vfs_worm_create_file(vfs_handle_struct *handle, > struct security_descriptor *sd, > struct ea_list *ea_list, > files_struct **result, >- int *pinfo) >+ int *pinfo, >+ const struct smb2_create_blobs *in_context_blobs, >+ struct smb2_create_blobs *out_context_blobs) > { > bool readonly = false; > const uint32_t write_access_flags = >@@ -64,7 +66,8 @@ static NTSTATUS vfs_worm_create_file(vfs_handle_struct *handle, > handle, req, root_dir_fid, smb_fname, access_mask, > share_access, create_disposition, create_options, > file_attributes, oplock_request, lease, allocation_size, >- private_flags, sd, ea_list, result, pinfo); >+ private_flags, sd, ea_list, result, pinfo, >+ in_context_blobs, out_context_blobs); > if (!NT_STATUS_IS_OK(status)) { > return status; > } >diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c >index 3a3a339..137df16 100644 >--- a/source3/printing/nt_printing.c >+++ b/source3/printing/nt_printing.c >@@ -537,7 +537,8 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr > NULL, /* sd */ > NULL, /* ea_list */ > &fsp, /* result */ >- NULL); /* pinfo */ >+ NULL, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(status)) { > /* Old file not found, so by definition new file is in fact newer */ >@@ -591,7 +592,8 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr > NULL, /* sd */ > NULL, /* ea_list */ > &fsp, /* result */ >- NULL); /* pinfo */ >+ NULL, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(status)) { > /* New file not found, this shouldn't occur if the caller did its job */ >@@ -770,7 +772,8 @@ static uint32 get_correct_cversion(struct auth_session_info *session_info, > NULL, /* sd */ > NULL, /* ea_list */ > &fsp, /* result */ >- NULL); /* pinfo */ >+ NULL, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(nt_status)) { > DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = " >diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c >index eaa70e7..483cafa 100644 >--- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c >+++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c >@@ -2369,7 +2369,8 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p, > NULL, /* sd */ > NULL, /* ea_list */ > &fsp, /* result */ >- NULL); /* pinfo */ >+ NULL, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(nt_status)) { > DEBUG(3,("_srvsvc_NetGetFileSecurity: can't open %s\n", >@@ -2517,7 +2518,8 @@ WERROR _srvsvc_NetSetFileSecurity(struct pipes_struct *p, > NULL, /* sd */ > NULL, /* ea_list */ > &fsp, /* result */ >- NULL); /* pinfo */ >+ NULL, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(nt_status)) { > DEBUG(3,("_srvsvc_NetSetFileSecurity: can't open %s\n", >diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c >index 162684b..6fd5d69 100644 >--- a/source3/smbd/dosmode.c >+++ b/source3/smbd/dosmode.c >@@ -1147,7 +1147,8 @@ static NTSTATUS get_file_handle_for_metadata(connection_struct *conn, > NULL, /* sd */ > NULL, /* ea_list */ > ret_fsp, /* result */ >- NULL); /* pinfo */ >+ NULL, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (NT_STATUS_IS_OK(status)) { > *need_close = true; >diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c >index edad3e4..4423a44 100644 >--- a/source3/smbd/nttrans.c >+++ b/source3/smbd/nttrans.c >@@ -579,7 +579,8 @@ void reply_ntcreate_and_X(struct smb_request *req) > NULL, /* sd */ > NULL, /* ea_list */ > &fsp, /* result */ >- &info); /* pinfo */ >+ &info, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(status)) { > if (open_was_deferred(req->xconn, req->mid)) { >@@ -1186,7 +1187,8 @@ static void call_nt_transact_create(connection_struct *conn, > sd, /* sd */ > ea_list, /* ea_list */ > &fsp, /* result */ >- &info); /* pinfo */ >+ &info, /* pinfo */ >+ NULL, NULL); /* create context */ > > if(!NT_STATUS_IS_OK(status)) { > if (open_was_deferred(req->xconn, req->mid)) { >@@ -1430,7 +1432,8 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx, > NULL, /* sd */ > NULL, /* ea_list */ > &fsp1, /* result */ >- &info); /* pinfo */ >+ &info, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(status)) { > goto out; >@@ -1455,7 +1458,8 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx, > NULL, /* sd */ > NULL, /* ea_list */ > &fsp2, /* result */ >- &info); /* pinfo */ >+ &info, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(status)) { > close_file(NULL, fsp1, ERROR_CLOSE); >diff --git a/source3/smbd/open.c b/source3/smbd/open.c >index f5ad900..c6b67f4 100644 >--- a/source3/smbd/open.c >+++ b/source3/smbd/open.c >@@ -3703,7 +3703,8 @@ NTSTATUS create_directory(connection_struct *conn, struct smb_request *req, > NULL, /* sd */ > NULL, /* ea_list */ > &fsp, /* result */ >- NULL); /* pinfo */ >+ NULL, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (NT_STATUS_IS_OK(status)) { > close_file(req, fsp, NORMAL_CLOSE); >@@ -3882,7 +3883,8 @@ NTSTATUS open_streams_for_delete(connection_struct *conn, > NULL, /* sd */ > NULL, /* ea_list */ > &streams[i], /* result */ >- NULL); /* pinfo */ >+ NULL, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(status)) { > DEBUG(10, ("Could not open stream %s: %s\n", >@@ -4831,7 +4833,9 @@ NTSTATUS create_file_default(connection_struct *conn, > struct security_descriptor *sd, > struct ea_list *ea_list, > files_struct **result, >- int *pinfo) >+ int *pinfo, >+ const struct smb2_create_blobs *in_context_blobs, >+ struct smb2_create_blobs *out_context_blobs) > { > int info = FILE_WAS_OPENED; > files_struct *fsp = NULL; >diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h >index 702da2e..e40a77b 100644 >--- a/source3/smbd/proto.h >+++ b/source3/smbd/proto.h >@@ -648,9 +648,11 @@ NTSTATUS create_file_default(connection_struct *conn, > uint32_t private_flags, > struct security_descriptor *sd, > struct ea_list *ea_list, >- > files_struct **result, >- int *pinfo); >+ int *pinfo, >+ const struct smb2_create_blobs *in_context_blobs, >+ struct smb2_create_blobs *out_context_blobs); >+ > NTSTATUS get_relative_fid_filename(connection_struct *conn, > struct smb_request *req, > uint16_t root_dir_fid, >diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c >index 21be320..8d59412 100644 >--- a/source3/smbd/reply.c >+++ b/source3/smbd/reply.c >@@ -2009,7 +2009,8 @@ void reply_open(struct smb_request *req) > NULL, /* sd */ > NULL, /* ea_list */ > &fsp, /* result */ >- &info); /* pinfo */ >+ &info, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(status)) { > if (open_was_deferred(req->xconn, req->mid)) { >@@ -2178,7 +2179,8 @@ void reply_open_and_X(struct smb_request *req) > NULL, /* sd */ > NULL, /* ea_list */ > &fsp, /* result */ >- &smb_action); /* pinfo */ >+ &smb_action, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(status)) { > if (open_was_deferred(req->xconn, req->mid)) { >@@ -2426,7 +2428,8 @@ void reply_mknew(struct smb_request *req) > NULL, /* sd */ > NULL, /* ea_list */ > &fsp, /* result */ >- NULL); /* pinfo */ >+ NULL, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(status)) { > if (open_was_deferred(req->xconn, req->mid)) { >@@ -2554,7 +2557,8 @@ void reply_ctemp(struct smb_request *req) > NULL, /* sd */ > NULL, /* ea_list */ > &fsp, /* result */ >- NULL); /* pinfo */ >+ NULL, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { > TALLOC_FREE(fname); >@@ -2772,7 +2776,8 @@ static NTSTATUS do_unlink(connection_struct *conn, > NULL, /* sd */ > NULL, /* ea_list */ > &fsp, /* result */ >- NULL); /* pinfo */ >+ NULL, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(status)) { > DEBUG(10, ("SMB_VFS_CREATEFILE failed: %s\n", >@@ -6043,7 +6048,8 @@ void reply_rmdir(struct smb_request *req) > NULL, /* sd */ > NULL, /* ea_list */ > &fsp, /* result */ >- &info); /* pinfo */ >+ &info, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(status)) { > if (open_was_deferred(req->xconn, req->mid)) { >@@ -6811,7 +6817,8 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, > NULL, /* sd */ > NULL, /* ea_list */ > &fsp, /* result */ >- NULL); /* pinfo */ >+ NULL, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(status)) { > DEBUG(3, ("Could not open rename source %s: %s\n", >@@ -6958,7 +6965,8 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx, > NULL, /* sd */ > NULL, /* ea_list */ > &fsp, /* result */ >- NULL); /* pinfo */ >+ NULL, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(status)) { > DEBUG(3,("rename_internals: SMB_VFS_CREATE_FILE " >@@ -7228,7 +7236,8 @@ NTSTATUS copy_file(TALLOC_CTX *ctx, > NULL, /* sd */ > NULL, /* ea_list */ > &fsp1, /* result */ >- NULL); /* psbuf */ >+ NULL, /* psbuf */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(status)) { > goto out; >@@ -7258,7 +7267,8 @@ NTSTATUS copy_file(TALLOC_CTX *ctx, > NULL, /* sd */ > NULL, /* ea_list */ > &fsp2, /* result */ >- NULL); /* psbuf */ >+ NULL, /* psbuf */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(status)) { > close_file(NULL, fsp1, ERROR_CLOSE); >diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c >index 77e0c96..2f9d500 100644 >--- a/source3/smbd/smb2_create.c >+++ b/source3/smbd/smb2_create.c >@@ -1071,7 +1071,9 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, > sec_desc, > ea_list, > &result, >- &info); >+ &info, >+ &in_context_blobs, >+ state->out_context_blobs); > if (!NT_STATUS_IS_OK(status)) { > if (open_was_deferred(smb1req->xconn, smb1req->mid)) { > return req; >diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c >index 60128ef..e2640e4 100644 >--- a/source3/smbd/trans2.c >+++ b/source3/smbd/trans2.c >@@ -1227,7 +1227,8 @@ static void call_trans2open(connection_struct *conn, > NULL, /* sd */ > ea_list, /* ea_list */ > &fsp, /* result */ >- &smb_action); /* psbuf */ >+ &smb_action, /* psbuf */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(status)) { > if (open_was_deferred(req->xconn, req->mid)) { >@@ -5995,7 +5996,8 @@ static NTSTATUS smb_set_file_size(connection_struct *conn, > NULL, /* sd */ > NULL, /* ea_list */ > &new_fsp, /* result */ >- NULL); /* pinfo */ >+ NULL, /* pinfo */ >+ NULL, NULL); /* create context */ > > TALLOC_FREE(smb_fname_tmp); > >@@ -6981,7 +6983,8 @@ static NTSTATUS smb_set_file_allocation_info(connection_struct *conn, > NULL, /* sd */ > NULL, /* ea_list */ > &new_fsp, /* result */ >- NULL); /* pinfo */ >+ NULL, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(status)) { > /* NB. We check for open_was_deferred in the caller. */ >@@ -7497,7 +7500,8 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn, > NULL, /* sd */ > NULL, /* ea_list */ > &fsp, /* result */ >- &info); /* pinfo */ >+ &info, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (NT_STATUS_IS_OK(status)) { > close_file(req, fsp, NORMAL_CLOSE); >@@ -7730,7 +7734,8 @@ static NTSTATUS smb_posix_open(connection_struct *conn, > NULL, /* sd */ > NULL, /* ea_list */ > &fsp, /* result */ >- &info); /* pinfo */ >+ &info, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(status)) { > return status; >@@ -7861,7 +7866,8 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn, > NULL, /* sd */ > NULL, /* ea_list */ > &fsp, /* result */ >- &info); /* pinfo */ >+ &info, /* pinfo */ >+ NULL, NULL); /* create context */ > > if (!NT_STATUS_IS_OK(status)) { > return status; >diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c >index 4b96963..51362c3 100644 >--- a/source3/smbd/vfs.c >+++ b/source3/smbd/vfs.c >@@ -1545,7 +1545,9 @@ NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle, > struct security_descriptor *sd, > struct ea_list *ea_list, > files_struct **result, >- int *pinfo) >+ int *pinfo, >+ const struct smb2_create_blobs *in_context_blobs, >+ struct smb2_create_blobs *out_context_blobs) > { > VFS_FIND(create_file); > return handle->fns->create_file_fn( >@@ -1553,7 +1555,7 @@ NTSTATUS smb_vfs_call_create_file(struct vfs_handle_struct *handle, > share_access, create_disposition, create_options, > file_attributes, oplock_request, lease, allocation_size, > private_flags, sd, ea_list, >- result, pinfo); >+ result, pinfo, in_context_blobs, out_context_blobs); > } > > int smb_vfs_call_close(struct vfs_handle_struct *handle, >-- >1.9.1 > > >From f87c7f09df915c7cf819a4c6c08794864a15cc61 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <rb@sernet.de> >Date: Fri, 22 Aug 2014 03:48:50 +0200 >Subject: [PATCH 04/12] s3:smbd: add SMB2 AAPL create context defines > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 80849d31a1be489c292a82b8abb95d843988154a) >--- > libcli/smb/smb2_constants.h | 1 + > libcli/smb/smb2_create_ctx.h | 46 ++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 47 insertions(+) > create mode 100644 libcli/smb/smb2_create_ctx.h > >diff --git a/libcli/smb/smb2_constants.h b/libcli/smb/smb2_constants.h >index 0b34723..fbab3e1 100644 >--- a/libcli/smb/smb2_constants.h >+++ b/libcli/smb/smb2_constants.h >@@ -207,6 +207,7 @@ > #define SMB2_CREATE_TAG_RQLS "RqLs" > #define SMB2_CREATE_TAG_DH2Q "DH2Q" > #define SMB2_CREATE_TAG_DH2C "DH2C" >+#define SMB2_CREATE_TAG_AAPL "AAPL" > #define SMB2_CREATE_TAG_APP_INSTANCE_ID "\x45\xBC\xA6\x6A\xEF\xA7\xF7\x4A\x90\x08\xFA\x46\x2E\x14\x4D\x74" > > /* SMB2 notify flags */ >diff --git a/libcli/smb/smb2_create_ctx.h b/libcli/smb/smb2_create_ctx.h >new file mode 100644 >index 0000000..cb194f5 >--- /dev/null >+++ b/libcli/smb/smb2_create_ctx.h >@@ -0,0 +1,46 @@ >+/* >+ Unix SMB/CIFS implementation. >+ >+ SMB2 create context specifc stuff >+ >+ 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 __LIBCLI_SMB2_CREATE_CTX_H__ >+#define __LIBCLI_SMB2_CREATE_CTX_H__ >+ >+/* http://opensource.apple.com/source/smb/smb-697.1.1/kernel/netsmb/smb_2.h */ >+ >+/* "AAPL" Context Command Codes */ >+#define SMB2_CRTCTX_AAPL_SERVER_QUERY 1 >+#define SMB2_CRTCTX_AAPL_RESOLVE_ID 2 >+ >+/* "AAPL" Server Query request/response bitmap */ >+#define SMB2_CRTCTX_AAPL_SERVER_CAPS 1 >+#define SMB2_CRTCTX_AAPL_VOLUME_CAPS 2 >+#define SMB2_CRTCTX_AAPL_MODEL_INFO 4 >+ >+/* "AAPL" Client/Server Capabilities bitmap */ >+#define SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR 1 >+#define SMB2_CRTCTX_AAPL_SUPPORTS_OSX_COPYFILE 2 >+#define SMB2_CRTCTX_AAPL_UNIX_BASED 4 >+#define SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE 8 >+ >+/* "AAPL" Volume Capabilities bitmap */ >+#define SMB2_CRTCTX_AAPL_SUPPORT_RESOLVE_ID 1 >+#define SMB2_CRTCTX_AAPL_CASE_SENSITIVE 2 >+ >+#endif >-- >1.9.1 > > >From fdcb66996f757827c992fa2744d9dc9115ae8c1c Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <rb@sernet.de> >Date: Mon, 8 Sep 2014 23:18:35 +0200 >Subject: [PATCH 05/12] libcli/security: add NFS SID mappings > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 549ee51674a3a50f866bcf37b3ae58f5e8a9080e) >--- > libcli/security/dom_sid.h | 5 +++++ > libcli/security/util_sid.c | 17 +++++++++++++++++ > 2 files changed, 22 insertions(+) > >diff --git a/libcli/security/dom_sid.h b/libcli/security/dom_sid.h >index c4a417b..cf3cedea 100644 >--- a/libcli/security/dom_sid.h >+++ b/libcli/security/dom_sid.h >@@ -53,6 +53,11 @@ extern const struct dom_sid global_sid_Builtin_Replicator; > extern const struct dom_sid global_sid_Builtin_PreWin2kAccess; > extern const struct dom_sid global_sid_Unix_Users; > extern const struct dom_sid global_sid_Unix_Groups; >+extern const struct dom_sid global_sid_Unix_NFS; >+extern const struct dom_sid global_sid_Unix_NFS_Users; >+extern const struct dom_sid global_sid_Unix_NFS_Groups; >+extern const struct dom_sid global_sid_Unix_NFS_Mode; >+extern const struct dom_sid global_sid_Unix_NFS_Other; > > int dom_sid_compare_auth(const struct dom_sid *sid1, > const struct dom_sid *sid2); >diff --git a/libcli/security/util_sid.c b/libcli/security/util_sid.c >index 8e42826..5127109 100644 >--- a/libcli/security/util_sid.c >+++ b/libcli/security/util_sid.c >@@ -96,6 +96,23 @@ const struct dom_sid global_sid_Unix_Users = /* Unmapped Unix users */ > const struct dom_sid global_sid_Unix_Groups = /* Unmapped Unix groups */ > { 1, 1, {0,0,0,0,0,22}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; > >+/* >+ * http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx >+ */ >+const struct dom_sid global_sid_Unix_NFS = /* MS NFS and Apple style */ >+{ 1, 1, {0,0,0,0,0,5}, {88,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; >+const struct dom_sid global_sid_Unix_NFS_Users = /* Unix uid, MS NFS and Apple style */ >+{ 1, 2, {0,0,0,0,0,5}, {88,1,0,0,0,0,0,0,0,0,0,0,0,0,0}}; >+const struct dom_sid global_sid_Unix_NFS_Groups = /* Unix gid, MS NFS and Apple style */ >+{ 1, 2, {0,0,0,0,0,5}, {88,2,0,0,0,0,0,0,0,0,0,0,0,0,0}}; >+const struct dom_sid global_sid_Unix_NFS_Mode = /* Unix mode */ >+{ 1, 2, {0,0,0,0,0,5}, {88,3,0,0,0,0,0,0,0,0,0,0,0,0,0}}; >+/* Unused, left here for documentary purposes */ >+#if 0 >+const struct dom_sid global_sid_Unix_NFS_Other = /* Unix other, MS NFS and Apple style */ >+{ 1, 2, {0,0,0,0,0,5}, {88,4,0,0,0,0,0,0,0,0,0,0,0,0,0}}; >+#endif >+ > /* Unused, left here for documentary purposes */ > #if 0 > #define SECURITY_NULL_SID_AUTHORITY 0 >-- >1.9.1 > > >From 75dc39086c110e8750e2e66b76f25d8e43146420 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Tue, 14 Oct 2014 13:54:05 +0200 >Subject: [PATCH 06/12] libcli/security: add a function that checks for MS NFS > ACEs > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 2ab6b43da63715350db8675bd3804e64f4241bca) >--- > libcli/security/security_descriptor.c | 22 ++++++++++++++++++++++ > libcli/security/security_descriptor.h | 2 ++ > 2 files changed, 24 insertions(+) > >diff --git a/libcli/security/security_descriptor.c b/libcli/security/security_descriptor.c >index 8304b20..a75942c 100644 >--- a/libcli/security/security_descriptor.c >+++ b/libcli/security/security_descriptor.c >@@ -595,3 +595,25 @@ struct security_ace *security_ace_create(TALLOC_CTX *mem_ctx, > > return ace; > } >+ >+/******************************************************************* >+ Check for MS NFS ACEs in a sd >+*******************************************************************/ >+bool security_descriptor_with_ms_nfs(const struct security_descriptor *psd) >+{ >+ int i; >+ >+ if (psd->dacl == NULL) { >+ return false; >+ } >+ >+ for (i = 0; i < psd->dacl->num_aces; i++) { >+ if (dom_sid_compare_domain( >+ &global_sid_Unix_NFS, >+ &psd->dacl->aces[i].trustee) == 0) { >+ return true; >+ } >+ } >+ >+ return false; >+} >diff --git a/libcli/security/security_descriptor.h b/libcli/security/security_descriptor.h >index 1c7f893..87643bc 100644 >--- a/libcli/security/security_descriptor.h >+++ b/libcli/security/security_descriptor.h >@@ -81,4 +81,6 @@ struct security_descriptor *create_security_descriptor(TALLOC_CTX *mem_ctx, > struct dom_sid *default_group, /* valid only for DS, NULL for the other RSs */ > uint32_t (*generic_map)(uint32_t access_mask)); > >+bool security_descriptor_with_ms_nfs(const struct security_descriptor *psd); >+ > #endif /* __SECURITY_DESCRIPTOR_H__ */ >-- >1.9.1 > > >From d4784fc966b2780b8866aecda249fcc91cf7be54 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Wed, 26 Nov 2014 18:01:37 +0100 >Subject: [PATCH 07/12] s3:smbd: ignore dacls with MS NFS ACEs > >Ignore NFS ACEs in code the modifies >* default POSIX ACLs >* VFS: NFSv4 ACLs >* VFS: xattr and tdb ACLs > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 5ff72827c3b74f28995b45250fe8efa79495e3b6) >--- > source3/modules/nfs4_acls.c | 3 +++ > source3/modules/vfs_acl_common.c | 9 +++++++++ > source3/smbd/posix_acls.c | 10 ++++++++++ > 3 files changed, 22 insertions(+) > >diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c >index cf61af9..1aa819a 100644 >--- a/source3/modules/nfs4_acls.c >+++ b/source3/modules/nfs4_acls.c >@@ -778,6 +778,9 @@ static bool smbacl4_fill_ace4( > ace_v4->who.gid = gid; > } else if (sid_to_uid(&ace_nt->trustee, &uid)) { > ace_v4->who.uid = uid; >+ } else if (dom_sid_compare_domain(&ace_nt->trustee, >+ &global_sid_Unix_NFS) == 0) { >+ return false; > } else { > DEBUG(1, ("nfs4_acls.c: file [%s]: could not " > "convert %s to uid or gid\n", >diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c >index b749157..920c811 100644 >--- a/source3/modules/vfs_acl_common.c >+++ b/source3/modules/vfs_acl_common.c >@@ -775,6 +775,15 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, > psd->group_sid = orig_psd->group_sid; > } > if (security_info_sent & SECINFO_DACL) { >+ if (security_descriptor_with_ms_nfs(orig_psd)) { >+ /* >+ * If the sd contains a MS NFS SID, do >+ * nothing, it's a chmod() request from OS X >+ * with AAPL context. >+ */ >+ TALLOC_FREE(frame); >+ return NT_STATUS_OK; >+ } > psd->dacl = orig_psd->dacl; > psd->type |= SEC_DESC_DACL_PRESENT; > } >diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c >index 126b822..6a5ec85 100644 >--- a/source3/smbd/posix_acls.c >+++ b/source3/smbd/posix_acls.c >@@ -3666,6 +3666,16 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const struct s > return NT_STATUS_INVALID_PARAMETER; > } > >+ /* >+ * MS NFS mode, here's the deal: the client merely wants to >+ * modify the mode, but roundtripping get_acl/set/acl would >+ * add additional POSIX ACEs. So in case we get a request >+ * containing a MS NFS mode SID, we do nothing here. >+ */ >+ if (security_descriptor_with_ms_nfs(psd_orig)) { >+ return NT_STATUS_OK; >+ } >+ > psd = security_descriptor_copy(talloc_tos(), psd_orig); > if (psd == NULL) { > return NT_STATUS_NO_MEMORY; >-- >1.9.1 > > >From 602abf390879a8011852df40655ecff75dbc9aba Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Wed, 26 Nov 2014 18:11:17 +0100 >Subject: [PATCH 08/12] vfs_fruit: AAPL support > >* readdir_attr VFS functions, used in trans2 when marshalling > metadata associated with a directory entry > >* support for reading and writing UNIX mode via MS NFS ACEs in NT ACL > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 353acb6d294bd32fdaaf1e4d95c663cae30775a0) >--- > source3/modules/vfs_fruit.c | 459 +++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 453 insertions(+), 6 deletions(-) > >diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c >index ec75d27..c5d92ef 100644 >--- a/source3/modules/vfs_fruit.c >+++ b/source3/modules/vfs_fruit.c >@@ -28,6 +28,7 @@ > #include "smbd/globals.h" > #include "messages.h" > #include "libcli/security/security.h" >+#include "../libcli/smb/smb2_create_ctx.h" > > /* > * Enhanced OS X and Netatalk compatibility >@@ -121,6 +122,20 @@ struct fruit_config_data { > enum fruit_meta meta; > enum fruit_locking locking; > enum fruit_encoding encoding; >+ bool use_aapl; >+ bool readdir_attr_enabled; >+ bool unix_info_enabled; >+ >+ /* >+ * Additional undocumented options, all enabled by default, >+ * possibly useful for analyzing performance. The associated >+ * operations with each of them may be expensive, so having >+ * the chance to disable them individually gives a chance >+ * tweaking the setup for the particular usecase. >+ */ >+ bool readdir_attr_rsize; >+ bool readdir_attr_finder_info; >+ bool readdir_attr_max_access; > }; > > static const struct enum_list fruit_rsrc[] = { >@@ -1250,6 +1265,25 @@ static int init_fruit_config(vfs_handle_struct *handle) > } > config->encoding = (enum fruit_encoding)enumval; > >+ if (lp_parm_bool(-1, FRUIT_PARAM_TYPE_NAME, "aapl", true)) { >+ config->use_aapl = true; >+ } >+ >+ if (lp_parm_bool(SNUM(handle->conn), >+ "readdir_attr", "aapl_rsize", true)) { >+ config->readdir_attr_rsize = true; >+ } >+ >+ if (lp_parm_bool(SNUM(handle->conn), >+ "readdir_attr", "aapl_finder_info", true)) { >+ config->readdir_attr_finder_info = true; >+ } >+ >+ if (lp_parm_bool(SNUM(handle->conn), >+ "readdir_attr", "aapl_max_access", true)) { >+ config->readdir_attr_max_access = true; >+ } >+ > SMB_VFS_HANDLE_SET_DATA(handle, config, > NULL, struct fruit_config_data, > return -1); >@@ -1662,6 +1696,231 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle, > return status; > } > >+static NTSTATUS check_aapl(vfs_handle_struct *handle, >+ struct smb_request *req, >+ const struct smb2_create_blobs *in_context_blobs, >+ struct smb2_create_blobs *out_context_blobs) >+{ >+ struct fruit_config_data *config; >+ NTSTATUS status; >+ struct smb2_create_blob *aapl = NULL; >+ uint32_t cmd; >+ bool ok; >+ uint8_t p[16]; >+ DATA_BLOB blob = data_blob_talloc(req, NULL, 0); >+ uint64_t req_bitmap, client_caps; >+ uint64_t server_caps = SMB2_CRTCTX_AAPL_UNIX_BASED; >+ smb_ucs2_t *model; >+ size_t modellen; >+ >+ SMB_VFS_HANDLE_GET_DATA(handle, config, struct fruit_config_data, >+ return NT_STATUS_UNSUCCESSFUL); >+ >+ if (!config->use_aapl >+ || in_context_blobs == NULL >+ || out_context_blobs == NULL) { >+ return NT_STATUS_OK; >+ } >+ >+ aapl = smb2_create_blob_find(in_context_blobs, >+ SMB2_CREATE_TAG_AAPL); >+ if (aapl == NULL) { >+ return NT_STATUS_OK; >+ } >+ >+ if (aapl->data.length != 24) { >+ DEBUG(1, ("unexpected AAPL ctxt legnth: %ju\n", >+ (uintmax_t)aapl->data.length)); >+ return NT_STATUS_INVALID_PARAMETER; >+ } >+ >+ cmd = IVAL(aapl->data.data, 0); >+ if (cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) { >+ DEBUG(1, ("unsupported AAPL cmd: %d\n", cmd)); >+ return NT_STATUS_INVALID_PARAMETER; >+ } >+ >+ req_bitmap = BVAL(aapl->data.data, 8); >+ client_caps = BVAL(aapl->data.data, 16); >+ >+ SIVAL(p, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY); >+ SIVAL(p, 4, 0); >+ SBVAL(p, 8, req_bitmap); >+ ok = data_blob_append(req, &blob, p, 16); >+ if (!ok) { >+ return NT_STATUS_UNSUCCESSFUL; >+ } >+ >+ if (req_bitmap & SMB2_CRTCTX_AAPL_SERVER_CAPS) { >+ if ((client_caps & SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR) && >+ (handle->conn->tcon->compat->fs_capabilities & FILE_NAMED_STREAMS)) { >+ server_caps |= SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR; >+ config->readdir_attr_enabled = true; >+ } >+ >+ /* >+ * The client doesn't set the flag, so we can't check >+ * for it and just set it unconditionally >+ */ >+ server_caps |= SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE; >+ config->unix_info_enabled = true; >+ >+ SBVAL(p, 0, server_caps); >+ ok = data_blob_append(req, &blob, p, 8); >+ if (!ok) { >+ return NT_STATUS_UNSUCCESSFUL; >+ } >+ } >+ >+ if (req_bitmap & SMB2_CRTCTX_AAPL_VOLUME_CAPS) { >+ SBVAL(p, 0, >+ lp_case_sensitive(SNUM(handle->conn->tcon->compat)) ? >+ SMB2_CRTCTX_AAPL_CASE_SENSITIVE : 0); >+ ok = data_blob_append(req, &blob, p, 8); >+ if (!ok) { >+ return NT_STATUS_UNSUCCESSFUL; >+ } >+ } >+ >+ if (req_bitmap & SMB2_CRTCTX_AAPL_MODEL_INFO) { >+ ok = convert_string_talloc(req, >+ CH_UNIX, CH_UTF16LE, >+ "Samba", strlen("Samba"), >+ &model, &modellen); >+ if (!ok) { >+ return NT_STATUS_UNSUCCESSFUL; >+ } >+ >+ SIVAL(p, 0, 0); >+ SIVAL(p + 4, 0, modellen); >+ ok = data_blob_append(req, &blob, p, 8); >+ if (!ok) { >+ talloc_free(model); >+ return NT_STATUS_UNSUCCESSFUL; >+ } >+ >+ ok = data_blob_append(req, &blob, model, modellen); >+ talloc_free(model); >+ if (!ok) { >+ return NT_STATUS_UNSUCCESSFUL; >+ } >+ } >+ >+ status = smb2_create_blob_add(out_context_blobs, >+ out_context_blobs, >+ SMB2_CREATE_TAG_AAPL, >+ blob); >+ >+ return status; >+} >+ >+static NTSTATUS readdir_attr_macmeta(struct vfs_handle_struct *handle, >+ const struct smb_filename *smb_fname, >+ struct readdir_attr_data *attr_data) >+{ >+ NTSTATUS status = NT_STATUS_OK; >+ uint32_t date_added; >+ struct adouble *ad = NULL; >+ struct fruit_config_data *config = NULL; >+ >+ SMB_VFS_HANDLE_GET_DATA(handle, config, >+ struct fruit_config_data, >+ return NT_STATUS_UNSUCCESSFUL); >+ >+ >+ /* Ensure we return a default value in the creation_date field */ >+ RSIVAL(&attr_data->attr_data.aapl.finder_info, 12, AD_DATE_START); >+ >+ /* >+ * Resource fork length >+ */ >+ >+ if (config->readdir_attr_rsize) { >+ ad = ad_get(talloc_tos(), handle, smb_fname->base_name, >+ ADOUBLE_RSRC); >+ if (ad) { >+ attr_data->attr_data.aapl.rfork_size = ad_getentrylen( >+ ad, ADEID_RFORK); >+ TALLOC_FREE(ad); >+ } >+ } >+ >+ /* >+ * FinderInfo >+ */ >+ >+ if (config->readdir_attr_finder_info) { >+ ad = ad_get(talloc_tos(), handle, smb_fname->base_name, >+ ADOUBLE_META); >+ if (ad) { >+ if (S_ISREG(smb_fname->st.st_ex_mode)) { >+ /* finder_type */ >+ memcpy(&attr_data->attr_data.aapl.finder_info[0], >+ ad_entry(ad, ADEID_FINDERI), 4); >+ >+ /* finder_creator */ >+ memcpy(&attr_data->attr_data.aapl.finder_info[0] + 4, >+ ad_entry(ad, ADEID_FINDERI) + 4, 4); >+ } >+ >+ /* finder_flags */ >+ memcpy(&attr_data->attr_data.aapl.finder_info[0] + 8, >+ ad_entry(ad, ADEID_FINDERI) + 8, 2); >+ >+ /* finder_ext_flags */ >+ memcpy(&attr_data->attr_data.aapl.finder_info[0] + 10, >+ ad_entry(ad, ADEID_FINDERI) + 24, 2); >+ >+ /* creation date */ >+ date_added = convert_time_t_to_uint32_t( >+ smb_fname->st.st_ex_btime.tv_sec - AD_DATE_DELTA); >+ RSIVAL(&attr_data->attr_data.aapl.finder_info[0], 12, date_added); >+ >+ TALLOC_FREE(ad); >+ } >+ } >+ >+ TALLOC_FREE(ad); >+ return status; >+} >+ >+/* Search MS NFS style ACE with UNIX mode */ >+static NTSTATUS check_ms_nfs(vfs_handle_struct *handle, >+ files_struct *fsp, >+ const struct security_descriptor *psd, >+ mode_t *pmode, >+ bool *pdo_chmod) >+{ >+ int i; >+ struct fruit_config_data *config = NULL; >+ >+ *pdo_chmod = false; >+ >+ SMB_VFS_HANDLE_GET_DATA(handle, config, >+ struct fruit_config_data, >+ return NT_STATUS_UNSUCCESSFUL); >+ >+ if (psd->dacl == NULL || !config->unix_info_enabled) { >+ return NT_STATUS_OK; >+ } >+ >+ for (i = 0; i < psd->dacl->num_aces; i++) { >+ if (dom_sid_compare_domain( >+ &global_sid_Unix_NFS_Mode, >+ &psd->dacl->aces[i].trustee) == 0) { >+ *pmode = (mode_t)psd->dacl->aces[i].trustee.sub_auths[2]; >+ *pmode &= (S_IRWXU | S_IRWXG | S_IRWXO); >+ *pdo_chmod = true; >+ >+ DEBUG(10, ("MS NFS chmod request %s, %04o\n", >+ fsp_str_dbg(fsp), *pmode)); >+ break; >+ } >+ } >+ >+ return NT_STATUS_OK; >+} >+ > /**************************************************************************** > * VFS ops > ****************************************************************************/ >@@ -2881,6 +3140,14 @@ static NTSTATUS fruit_create_file(vfs_handle_struct *handle, > NTSTATUS status; > struct fruit_config_data *config = NULL; > >+ status = check_aapl(handle, req, in_context_blobs, out_context_blobs); >+ if (!NT_STATUS_IS_OK(status)) { >+ return status; >+ } >+ >+ SMB_VFS_HANDLE_GET_DATA(handle, config, struct fruit_config_data, >+ return NT_STATUS_UNSUCCESSFUL); >+ > status = SMB_VFS_NEXT_CREATE_FILE( > handle, req, root_dir_fid, smb_fname, > access_mask, share_access, >@@ -2889,9 +3156,7 @@ static NTSTATUS fruit_create_file(vfs_handle_struct *handle, > lease, > allocation_size, private_flags, > sd, ea_list, result, >- pinfo, >- in_context_blobs, out_context_blobs); >- >+ pinfo, in_context_blobs, out_context_blobs); > if (!NT_STATUS_IS_OK(status)) { > return status; > } >@@ -2902,9 +3167,6 @@ static NTSTATUS fruit_create_file(vfs_handle_struct *handle, > return status; > } > >- SMB_VFS_HANDLE_GET_DATA(handle, config, struct fruit_config_data, >- return NT_STATUS_UNSUCCESSFUL); >- > if (config->locking == FRUIT_LOCKING_NETATALK) { > status = fruit_check_access( > handle, *result, >@@ -2928,6 +3190,186 @@ fail: > return status; > } > >+static NTSTATUS fruit_readdir_attr(struct vfs_handle_struct *handle, >+ const struct smb_filename *fname, >+ TALLOC_CTX *mem_ctx, >+ struct readdir_attr_data **pattr_data) >+{ >+ struct fruit_config_data *config = NULL; >+ struct readdir_attr_data *attr_data; >+ NTSTATUS status; >+ >+ SMB_VFS_HANDLE_GET_DATA(handle, config, >+ struct fruit_config_data, >+ return NT_STATUS_UNSUCCESSFUL); >+ >+ if (!config->use_aapl) { >+ return SMB_VFS_NEXT_READDIR_ATTR(handle, fname, mem_ctx, pattr_data); >+ } >+ >+ DEBUG(10, ("fruit_readdir_attr %s\n", fname->base_name)); >+ >+ *pattr_data = talloc_zero(mem_ctx, struct readdir_attr_data); >+ if (*pattr_data == NULL) { >+ return NT_STATUS_UNSUCCESSFUL; >+ } >+ attr_data = *pattr_data; >+ attr_data->type = RDATTR_AAPL; >+ >+ /* >+ * Mac metadata: compressed FinderInfo, resource fork length >+ * and creation date >+ */ >+ status = readdir_attr_macmeta(handle, fname, attr_data); >+ if (!NT_STATUS_IS_OK(status)) { >+ /* >+ * Error handling is tricky: if we return failure from >+ * this function, the corresponding directory entry >+ * will to be passed to the client, so we really just >+ * want to error out on fatal errors. >+ */ >+ if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { >+ goto fail; >+ } >+ } >+ >+ /* >+ * UNIX mode >+ */ >+ if (config->unix_info_enabled) { >+ attr_data->attr_data.aapl.unix_mode = fname->st.st_ex_mode; >+ } >+ >+ /* >+ * max_access >+ */ >+ if (!config->readdir_attr_max_access) { >+ attr_data->attr_data.aapl.max_access = FILE_GENERIC_ALL; >+ } else { >+ status = smbd_calculate_access_mask( >+ handle->conn, >+ fname, >+ false, >+ SEC_FLAG_MAXIMUM_ALLOWED, >+ &attr_data->attr_data.aapl.max_access); >+ if (!NT_STATUS_IS_OK(status)) { >+ goto fail; >+ } >+ } >+ >+ return NT_STATUS_OK; >+ >+fail: >+ DEBUG(1, ("fruit_readdir_attr %s, error: %s\n", >+ fname->base_name, nt_errstr(status))); >+ TALLOC_FREE(*pattr_data); >+ return status; >+} >+ >+static NTSTATUS fruit_fget_nt_acl(vfs_handle_struct *handle, >+ files_struct *fsp, >+ uint32 security_info, >+ TALLOC_CTX *mem_ctx, >+ struct security_descriptor **ppdesc) >+{ >+ NTSTATUS status; >+ struct security_ace ace; >+ struct dom_sid sid; >+ struct fruit_config_data *config; >+ >+ SMB_VFS_HANDLE_GET_DATA(handle, config, >+ struct fruit_config_data, >+ return NT_STATUS_UNSUCCESSFUL); >+ >+ status = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, >+ mem_ctx, ppdesc); >+ if (!NT_STATUS_IS_OK(status)) { >+ return status; >+ } >+ >+ /* >+ * Add MS NFS style ACEs with uid, gid and mode >+ */ >+ if (!config->unix_info_enabled) { >+ return NT_STATUS_OK; >+ } >+ >+ /* MS NFS style mode */ >+ sid_compose(&sid, &global_sid_Unix_NFS_Mode, fsp->fsp_name->st.st_ex_mode); >+ init_sec_ace(&ace, &sid, SEC_ACE_TYPE_ACCESS_DENIED, 0, 0); >+ status = security_descriptor_dacl_add(*ppdesc, &ace); >+ if (!NT_STATUS_IS_OK(status)) { >+ DEBUG(1,("failed to add MS NFS style ACE\n")); >+ return status; >+ } >+ >+ /* MS NFS style uid */ >+ sid_compose(&sid, &global_sid_Unix_NFS_Users, fsp->fsp_name->st.st_ex_uid); >+ init_sec_ace(&ace, &sid, SEC_ACE_TYPE_ACCESS_DENIED, 0, 0); >+ status = security_descriptor_dacl_add(*ppdesc, &ace); >+ if (!NT_STATUS_IS_OK(status)) { >+ DEBUG(1,("failed to add MS NFS style ACE\n")); >+ return status; >+ } >+ >+ /* MS NFS style gid */ >+ sid_compose(&sid, &global_sid_Unix_NFS_Groups, fsp->fsp_name->st.st_ex_gid); >+ init_sec_ace(&ace, &sid, SEC_ACE_TYPE_ACCESS_DENIED, 0, 0); >+ status = security_descriptor_dacl_add(*ppdesc, &ace); >+ if (!NT_STATUS_IS_OK(status)) { >+ DEBUG(1,("failed to add MS NFS style ACE\n")); >+ return status; >+ } >+ >+ return NT_STATUS_OK; >+} >+ >+static NTSTATUS fruit_fset_nt_acl(vfs_handle_struct *handle, >+ files_struct *fsp, >+ uint32 security_info_sent, >+ const struct security_descriptor *psd) >+{ >+ NTSTATUS status; >+ bool do_chmod; >+ mode_t ms_nfs_mode; >+ int result; >+ >+ DEBUG(1, ("fruit_fset_nt_acl: %s\n", fsp_str_dbg(fsp))); >+ >+ status = check_ms_nfs(handle, fsp, psd, &ms_nfs_mode, &do_chmod); >+ if (!NT_STATUS_IS_OK(status)) { >+ DEBUG(1, ("fruit_fset_nt_acl: check_ms_nfs failed%s\n", fsp_str_dbg(fsp))); >+ return status; >+ } >+ >+ status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd); >+ if (!NT_STATUS_IS_OK(status)) { >+ DEBUG(1, ("fruit_fset_nt_acl: SMB_VFS_NEXT_FSET_NT_ACL failed%s\n", fsp_str_dbg(fsp))); >+ return status; >+ } >+ >+ if (do_chmod) { >+ if (fsp->fh->fd != -1) { >+ DEBUG(1, ("fchmod: %s\n", fsp_str_dbg(fsp))); >+ result = SMB_VFS_FCHMOD(fsp, ms_nfs_mode); >+ } else { >+ DEBUG(1, ("chmod: %s\n", fsp_str_dbg(fsp))); >+ result = SMB_VFS_CHMOD(fsp->conn, >+ fsp->fsp_name->base_name, >+ ms_nfs_mode); >+ } >+ >+ if (result != 0) { >+ DEBUG(1, ("chmod: %s, result: %d, %04o error %s\n", fsp_str_dbg(fsp), >+ result, ms_nfs_mode, strerror(errno))); >+ status = map_nt_error_from_unix(errno); >+ return status; >+ } >+ } >+ >+ return NT_STATUS_OK; >+} >+ > static struct vfs_fn_pointers vfs_fruit_fns = { > .connect_fn = fruit_connect, > >@@ -2949,6 +3391,11 @@ static struct vfs_fn_pointers vfs_fruit_fns = { > .ftruncate_fn = fruit_ftruncate, > .fallocate_fn = fruit_fallocate, > .create_file_fn = fruit_create_file, >+ .readdir_attr_fn = fruit_readdir_attr, >+ >+ /* NT ACL operations */ >+ .fget_nt_acl_fn = fruit_fget_nt_acl, >+ .fset_nt_acl_fn = fruit_fset_nt_acl, > }; > > NTSTATUS vfs_fruit_init(void); >-- >1.9.1 > > >From 2b660282bd00ed06127535b431098863d2659690 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Wed, 26 Nov 2014 15:21:36 +0100 >Subject: [PATCH 09/12] 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> >(cherry picked from commit 2236883cdeadab02f0ed367e13b41a32b1f85c34) >--- > source3/smbd/trans2.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++----- > 1 file changed, 58 insertions(+), 6 deletions(-) > >diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c >index e2640e4..16498b3 100644 >--- a/source3/smbd/trans2.c >+++ b/source3/smbd/trans2.c >@@ -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), >-- >1.9.1 > > >From a7e296f3cb5baa6b6f8d0afc7a857b61dc92225a Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <rb@sernet.de> >Date: Wed, 1 Oct 2014 14:36:43 +0200 >Subject: [PATCH 10/12] s4:libcli/raw: make short_name available in buffer > >This will be used in smb2/create AAPL context torture tests, where the >server returns an Mac OS X specific data blob in the short name >buffer. It's not a string, so the existing string extraction doesn't >cut it. > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit b942d6b05f5eacfe33631534f559ab8b99369347) >--- > source4/libcli/raw/interfaces.h | 1 + > source4/libcli/raw/rawsearch.c | 1 + > 2 files changed, 2 insertions(+) > >diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h >index 05f5da0..621a5b8 100644 >--- a/source4/libcli/raw/interfaces.h >+++ b/source4/libcli/raw/interfaces.h >@@ -2740,6 +2740,7 @@ union smb_search_data { > uint32_t attrib; > uint32_t ea_size; > uint64_t file_id; >+ uint8_t short_name_buf[24]; > struct smb_wire_string short_name; > struct smb_wire_string name; > } id_both_directory_info; >diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c >index 0705faa..6035cc2 100644 >--- a/source4/libcli/raw/rawsearch.c >+++ b/source4/libcli/raw/rawsearch.c >@@ -456,6 +456,7 @@ NTSTATUS smb_raw_search_common(TALLOC_CTX *mem_ctx, > smbcli_blob_pull_string(NULL, mem_ctx, blob, > &data->id_both_directory_info.short_name, > 68, 70, STR_LEN8BIT | STR_UNICODE); >+ memcpy(data->id_both_directory_info.short_name_buf, blob->data + 70, 24); > data->id_both_directory_info.file_id = BVAL(blob->data, 96); > len = smbcli_blob_pull_string(NULL, mem_ctx, blob, > &data->id_both_directory_info.name, >-- >1.9.1 > > >From 74fc07af094b348f53569784f850ead9b2d66fa9 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <rb@sernet.de> >Date: Sat, 27 Sep 2014 17:21:12 +0200 >Subject: [PATCH 11/12] s4:torture:vfs_fruit: smb2/create context AAPL test > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 9994f1fed885ed6e413dffadf6ea93a97f57ac5a) >--- > source4/torture/vfs/fruit.c | 273 ++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 273 insertions(+) > >diff --git a/source4/torture/vfs/fruit.c b/source4/torture/vfs/fruit.c >index 0c8d3a4..5d4a411 100644 >--- a/source4/torture/vfs/fruit.c >+++ b/source4/torture/vfs/fruit.c >@@ -24,6 +24,7 @@ > #include "libcli/libcli.h" > #include "libcli/smb2/smb2.h" > #include "libcli/smb2/smb2_calls.h" >+#include "libcli/smb/smb2_create_ctx.h" > #include "lib/cmdline/popt_common.h" > #include "param/param.h" > #include "libcli/resolve/resolve.h" >@@ -1358,6 +1359,277 @@ done: > return ret; > } > >+static bool test_aapl(struct torture_context *tctx, >+ struct smb2_tree *tree1, >+ struct smb2_tree *tree2) >+{ >+ TALLOC_CTX *mem_ctx = talloc_new(tctx); >+ const char *fname = BASEDIR "\\test_aapl"; >+ NTSTATUS status; >+ struct smb2_handle testdirh; >+ bool ret = true; >+ struct smb2_create io; >+ DATA_BLOB data; >+ struct smb2_create_blob *aapl = NULL; >+ AfpInfo *info; >+ const char *type_creator = "SMB,OLE!"; >+ char type_creator_buf[9]; >+ uint32_t aapl_cmd; >+ uint32_t aapl_reply_bitmap; >+ uint32_t aapl_server_caps; >+ uint32_t aapl_vol_caps; >+ char *model; >+ struct smb2_find f; >+ unsigned int count; >+ union smb_search_data *d; >+ uint64_t rfork_len; >+ >+ smb2_deltree(tree1, BASEDIR); >+ >+ status = torture_smb2_testdir(tree1, BASEDIR, &testdirh); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ smb2_util_close(tree1, testdirh); >+ >+ ZERO_STRUCT(io); >+ io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED; >+ io.in.file_attributes = FILE_ATTRIBUTE_NORMAL; >+ io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF; >+ io.in.share_access = (NTCREATEX_SHARE_ACCESS_DELETE | >+ NTCREATEX_SHARE_ACCESS_READ | >+ NTCREATEX_SHARE_ACCESS_WRITE); >+ io.in.fname = fname; >+ >+ /* >+ * Issuing an SMB2/CREATE with a suitably formed AAPL context, >+ * controls behaviour of Apple's SMB2 extensions for the whole >+ * session! >+ */ >+ >+ data = data_blob_talloc(mem_ctx, NULL, 3 * sizeof(uint64_t)); >+ SBVAL(data.data, 0, SMB2_CRTCTX_AAPL_SERVER_QUERY); >+ SBVAL(data.data, 8, (SMB2_CRTCTX_AAPL_SERVER_CAPS | >+ SMB2_CRTCTX_AAPL_VOLUME_CAPS | >+ SMB2_CRTCTX_AAPL_MODEL_INFO)); >+ SBVAL(data.data, 16, (SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR | >+ SMB2_CRTCTX_AAPL_UNIX_BASED | >+ SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE)); >+ >+ torture_comment(tctx, "Testing SMB2 create context AAPL\n"); >+ status = smb2_create_blob_add(tctx, &io.in.blobs, "AAPL", data); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ status = smb2_create(tree1, tctx, &io); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ status = smb2_util_close(tree1, io.out.file.handle); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * Now check returned AAPL context >+ */ >+ torture_comment(tctx, "Comparing returned AAPL capabilites\n"); >+ >+ aapl = smb2_create_blob_find(&io.out.blobs, >+ SMB2_CREATE_TAG_AAPL); >+ >+ if (aapl->data.length != 50) { >+ /* >+ * uint32_t CommandCode = kAAPL_SERVER_QUERY >+ * uint32_t Reserved = 0; >+ * uint64_t ReplyBitmap = kAAPL_SERVER_CAPS | >+ * kAAPL_VOLUME_CAPS | >+ * kAAPL_MODEL_INFO; >+ * uint64_t ServerCaps = kAAPL_SUPPORTS_READDIR_ATTR | >+ * kAAPL_SUPPORTS_OSX_COPYFILE; >+ * uint64_t VolumeCaps = kAAPL_SUPPORT_RESOLVE_ID | >+ * kAAPL_CASE_SENSITIVE; >+ * uint32_t Pad2 = 0; >+ * uint32_t ModelStringLen = 10; >+ * ucs2_t ModelString[5] = "Samba"; >+ */ >+ ret = false; >+ goto done; >+ } >+ >+ aapl_cmd = IVAL(aapl->data.data, 0); >+ if (aapl_cmd != SMB2_CRTCTX_AAPL_SERVER_QUERY) { >+ torture_result(tctx, TORTURE_FAIL, >+ "(%s) unexpected cmd: %d", >+ __location__, (int)aapl_cmd); >+ ret = false; >+ goto done; >+ } >+ >+ aapl_reply_bitmap = BVAL(aapl->data.data, 8); >+ if (aapl_reply_bitmap != (SMB2_CRTCTX_AAPL_SERVER_CAPS | >+ SMB2_CRTCTX_AAPL_VOLUME_CAPS | >+ SMB2_CRTCTX_AAPL_MODEL_INFO)) { >+ torture_result(tctx, TORTURE_FAIL, >+ "(%s) unexpected reply_bitmap: %d", >+ __location__, (int)aapl_reply_bitmap); >+ ret = false; >+ goto done; >+ } >+ >+ aapl_server_caps = BVAL(aapl->data.data, 16); >+ if (aapl_server_caps != (SMB2_CRTCTX_AAPL_UNIX_BASED | >+ SMB2_CRTCTX_AAPL_SUPPORTS_READ_DIR_ATTR | >+ SMB2_CRTCTX_AAPL_SUPPORTS_NFS_ACE)) { >+ torture_result(tctx, TORTURE_FAIL, >+ "(%s) unexpected server_caps: %d", >+ __location__, (int)aapl_server_caps); >+ ret = false; >+ goto done; >+ } >+ >+ aapl_vol_caps = BVAL(aapl->data.data, 24); >+ if (aapl_vol_caps != SMB2_CRTCTX_AAPL_CASE_SENSITIVE) { >+ /* this will fail on a case insensitive fs ... */ >+ torture_result(tctx, TORTURE_FAIL, >+ "(%s) unexpected vol_caps: %d", >+ __location__, (int)aapl_vol_caps); >+ ret = false; >+ goto done; >+ } >+ >+ ret = convert_string_talloc(mem_ctx, >+ CH_UTF16LE, CH_UNIX, >+ aapl->data.data + 40, 10, >+ &model, NULL); >+ if (ret == false) { >+ torture_result(tctx, TORTURE_FAIL, >+ "(%s) convert_string_talloc() failed", >+ __location__); >+ goto done; >+ } >+ if (strncmp(model, "Samba", 5) != 0) { >+ torture_result(tctx, TORTURE_FAIL, >+ "(%s) expected model \"Samba\", got: \"%s\"", >+ __location__, model); >+ ret = false; >+ goto done; >+ } >+ >+ /* >+ * Now that Requested AAPL extensions are enabled, setup some >+ * Mac files with metadata and resource fork >+ */ >+ ret = torture_setup_file(mem_ctx, tree1, fname, false); >+ if (ret == false) { >+ torture_result(tctx, TORTURE_FAIL, >+ "(%s) torture_setup_file() failed", >+ __location__); >+ goto done; >+ } >+ >+ info = torture_afpinfo_new(mem_ctx); >+ if (info == NULL) { >+ torture_result(tctx, TORTURE_FAIL, >+ "(%s) torture_afpinfo_new() failed", >+ __location__); >+ ret = false; >+ goto done; >+ } >+ >+ memcpy(info->afpi_FinderInfo, type_creator, 8); >+ ret = torture_write_afpinfo(tree1, tctx, mem_ctx, fname, info); >+ if (ret == false) { >+ torture_result(tctx, TORTURE_FAIL, >+ "(%s) torture_write_afpinfo() failed", >+ __location__); >+ goto done; >+ } >+ >+ ret = write_stream(tree1, __location__, tctx, mem_ctx, >+ fname, AFPRESOURCE_STREAM, >+ 0, 3, "foo"); >+ if (ret == false) { >+ torture_result(tctx, TORTURE_FAIL, >+ "(%s) write_stream() failed", >+ __location__); >+ goto done; >+ } >+ >+ /* >+ * Ok, file is prepared, now call smb2/find >+ */ >+ >+ ZERO_STRUCT(io); >+ io.in.desired_access = SEC_RIGHTS_DIR_ALL; >+ io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; >+ io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY; >+ io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ | >+ NTCREATEX_SHARE_ACCESS_WRITE | >+ NTCREATEX_SHARE_ACCESS_DELETE); >+ io.in.create_disposition = NTCREATEX_DISP_OPEN; >+ io.in.fname = BASEDIR; >+ status = smb2_create(tree1, tctx, &io); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ ZERO_STRUCT(f); >+ f.in.file.handle = io.out.file.handle; >+ f.in.pattern = "test_aapl"; >+ f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE; >+ f.in.max_response_size = 0x1000; >+ f.in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO; >+ >+ status = smb2_find_level(tree1, tree1, &f, &count, &d); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ status = smb2_util_close(tree1, io.out.file.handle); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ if (strcmp(d[0].id_both_directory_info.name.s, "test_aapl") != 0) { >+ torture_result(tctx, TORTURE_FAIL, >+ "(%s) write_stream() failed", >+ __location__); >+ ret = false; >+ goto done; >+ } >+ >+ if (d[0].id_both_directory_info.short_name.private_length != 24) { >+ torture_result(tctx, TORTURE_FAIL, >+ "(%s) bad short_name length %" PRIu32 ", expected 24", >+ __location__, d[0].id_both_directory_info.short_name.private_length); >+ ret = false; >+ goto done; >+ } >+ >+ torture_comment(tctx, "short_name buffer:\n"); >+ dump_data(0, d[0].id_both_directory_info.short_name_buf, 24); >+ >+ /* >+ * Extract data as specified by the AAPL extension: >+ * - ea_size contains max_access >+ * - short_name contains resource fork length + FinderInfo >+ * - reserved2 contains the unix mode >+ */ >+ torture_comment(tctx, "mac_access: %" PRIx32 "\n", >+ d[0].id_both_directory_info.ea_size); >+ >+ rfork_len = BVAL(d[0].id_both_directory_info.short_name_buf, 0); >+ if (rfork_len != 3) { >+ torture_result(tctx, TORTURE_FAIL, >+ "(%s) expected resource fork length 3, got: %" PRIu64, >+ __location__, rfork_len); >+ ret = false; >+ goto done; >+ } >+ >+ memcpy(type_creator_buf, d[0].id_both_directory_info.short_name_buf + 8, 8); >+ type_creator_buf[8] = 0; >+ if (strcmp(type_creator, type_creator_buf) != 0) { >+ torture_result(tctx, TORTURE_FAIL, >+ "(%s) expected type/creator \"%s\" , got: %s", >+ __location__, type_creator, type_creator_buf); >+ ret = false; >+ goto done; >+ } >+ >+done: >+ talloc_free(mem_ctx); >+ return ret; >+} >+ > /* > * Note: This test depends on "vfs objects = catia fruit > * streams_xattr". Note: To run this test, use >@@ -1376,6 +1648,7 @@ struct torture_suite *torture_vfs_fruit(void) > torture_suite_add_2ns_smb2_test(suite, "write metadata", test_write_atalk_metadata); > torture_suite_add_2ns_smb2_test(suite, "resource fork IO", test_write_atalk_rfork_io); > torture_suite_add_2ns_smb2_test(suite, "OS X AppleDouble file conversion", test_adouble_conversion); >+ torture_suite_add_2ns_smb2_test(suite, "SMB2/CREATE context AAPL", test_aapl); > > return suite; > } >-- >1.9.1 > > >From bde896ddd8dee60a683a6fe01a1fb84310f10630 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Fri, 28 Nov 2014 22:44:29 +0100 >Subject: [PATCH 12/12] vfs_fruit: add AAPL options > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Fri Dec 5 00:34:01 CET 2014 on sn-devel-104 > >(cherry picked from commit 8f4813ff3070858cfa7e7da6fb703294bdedabed) >--- > docs-xml/manpages/vfs_fruit.8.xml | 35 +++++++++++++++++++++++++++++++++++ > 1 file changed, 35 insertions(+) > >diff --git a/docs-xml/manpages/vfs_fruit.8.xml b/docs-xml/manpages/vfs_fruit.8.xml >index 47caeb0..a9e2e6d 100644 >--- a/docs-xml/manpages/vfs_fruit.8.xml >+++ b/docs-xml/manpages/vfs_fruit.8.xml >@@ -153,6 +153,41 @@ > </listitem> > </varlistentry> > >+ <varlistentry> >+ <term>fruit:aapl = yes | no</term> >+ <listitem> >+ <para>A global option whether to enable Apple's SMB2+ >+ extension codenamed AAPL. Default >+ <emphasis>yes</emphasis>. This extension enhances >+ several deficiencies when connecting from Macs:</para> >+ >+ <itemizedlist> >+ <listitem><para>directory enumeration is enriched with >+ Mac relevant filesystem metadata (UNIX mode, >+ FinderInfo, resource fork size and effective >+ permission), as a result the Mac client doesn't need >+ to fetch this metadata individuallly per directory >+ entry resulting in an often tremendous performance >+ increase.</para></listitem> >+ >+ <listitem><para>The ability to query and modify the >+ UNIX mode of directory entries.</para></listitem> >+ </itemizedlist> >+ >+ <para>There's a set of per share options that can be >+ used to disable the computation of specific Mac metadata >+ in the directory enumeration context, all are enabled by >+ default:</para> >+ >+ <itemizedlist> >+ <listitem><para>readdir_attr:aapl_rsize = true | false</para></listitem> >+ <listitem><para>readdir_attr:aapl_finder_info = true | false</para></listitem> >+ <listitem><para>readdir_attr:aapl_max_access = true | false</para></listitem> >+ </itemizedlist> >+ >+ </listitem> >+ </varlistentry> >+ > </variablelist> > </refsect1> > >-- >1.9.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
slow
:
review+
jra
:
review+
Actions:
View
Attachments on
bug 10983
: 10491