((req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) && \
(fsp->access_mask & FILE_EXECUTE))))
+/*
+ * This is not documented in revision 49 of [MS-SMB2] but should be added in a
+ * later revision (and torture test smb2.read.access as well as
+ * smb2.ioctl_copy_chunk_bad_access against Server 2012R2 confirms this)
+ *
+ * If FILE_EXECUTE is granted to a handle then the SMB2 server acts as if
+ * FILE_READ_DATA has also been granted. We must still keep the original granted
+ * mask, because with ioctl requests, access checks are made on the file handle,
+ * "below" the SMB2 server, and the object store below the SMB layer is not
+ * aware of this arrangement (see smb2.ioctl.copy_chunk_bad_access torture
+ * test).
+ */
+#define CHECK_READ_SMB2(fsp) \
+ (((fsp)->fh->fd != -1) && \
+ ((fsp)->can_read || (fsp->access_mask & FILE_EXECUTE)))
+
/* An IOCTL readability check (validating read access
* when the IOCTL code requires it)
* http://social.technet.microsoft.com/wiki/contents/articles/24653.decoding-io-control-codes-ioctl-fsctl-and-deviceiocodes-with-table-of-known-values.aspx
FLAGS2_LONG_PATH_COMPONENTS |
FLAGS2_IS_LONG_NAME;
- /* This is not documented in revision 49 of [MS-SMB2] but should be
- * added in a later revision (and torture test smb2.read.access
- * as well as smb2.ioctl_copy_chunk_bad_access against
- * Server 2012R2 confirms this)
- *
- * If FILE_EXECUTE is granted to a handle then the SMB2 server
- * acts as if FILE_READ_DATA has also been granted. We must still
- * keep the original granted mask, because with ioctl requests,
- * access checks are made on the file handle, "below" the SMB2
- * server, and the object store below the SMB layer is not aware
- * of this arrangement (see smb2.ioctl.copy_chunk_bad_access
- * torture test).
- */
- smbreq->flags2 |= FLAGS2_READ_PERMIT_EXECUTE;
-
if (IVAL(inhdr, SMB2_HDR_FLAGS) & SMB2_HDR_FLAG_DFS) {
smbreq->flags2 |= FLAGS2_DFS_PATHNAMES;
}
* - The Open.GrantedAccess of the source file does not include
* FILE_READ_DATA access.
*/
- if (!CHECK_READ(src_fsp, smb1req)) {
+ if (!CHECK_READ_SMB2(src_fsp)) {
DEBUG(5, ("copy chunk no read on src handle (%s).\n",
smb_fname_str_dbg(src_fsp->fsp_name) ));
return NT_STATUS_ACCESS_DENIED;
return req;
}
- if (!CHECK_READ(fsp, smbreq)) {
+ if (!CHECK_READ_SMB2(fsp)) {
tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
return tevent_req_post(req, ev);
}