/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
#include <smbsrv/smb_kproto.h>
#include <smbsrv/smb_fsops.h>
/*
* The maximum number of bytes to return from SMB Core
* SmbRead or SmbLockAndRead.
*/
/*
* The limit in bytes for SmbReadX.
*/
/*
* Read bytes from a file or named pipe (SMB Core).
*
* The requested count specifies the number of bytes desired. Offset
* is limited to 32 bits, so this client request is inappropriate for
* files with 64 bit offsets.
*
* On return, count is the number of bytes actually being returned, which
* may be less than the count requested only if a read specifies bytes
* beyond the current file size. In this case only the bytes that exist
* are returned. A read completely beyond the end of file results in a
* response of length zero. This is the only circumstance when a zero
* length response is generated. A count returned which is less than the
* count requested is the end of file indicator.
*/
{
int rc;
smb_rw_param_t *, param);
}
void
{
}
{
int rc;
return (SDRC_ERROR);
}
return (SDRC_ERROR);
}
}
/*
* Lock and read bytes from a file (SMB Core Plus). The SmbLockAndRead/
* SmbLockAndWrite sub-dialect is only valid on disk files: reject any
* attempt to use it on non-disk shares.
*
* The requested count specifies the number of bytes desired. Offset
* specifies the offset in the file of the first byte to be locked then
* read. Note that offset is limited to 32 bits, so this client request
* is inappropriate for files with 64 bit offsets.
*
* As with SMB_LOCK_BYTE_RANGE request, if the lock cannot be granted
* immediately an error should be returned to the client. If an error
* occurs on the lock, the bytes should not be read.
*
* On return, count is the number of bytes actually being returned, which
* may be less than the count requested only if a read specifies bytes
* beyond the current file size. In this case only the bytes that exist
* are returned. A read completely beyond the end of file results in a
* response of length zero. This is the only circumstance when a zero
* length response is generated. A count returned which is less than the
* count requested is the end of file indicator.
*/
{
int rc;
smb_rw_param_t *, param);
}
void
{
}
{
int rc;
return (SDRC_ERROR);
}
return (SDRC_ERROR);
}
if (status != NT_STATUS_SUCCESS) {
return (SDRC_ERROR);
}
return (SDRC_ERROR);
}
}
/*
* Read bytes from a file (SMB Core). This request was extended in
* LM 0.12 to support 64-bit offsets, indicated by sending a wct of
* 12 and including additional offset information.
*
* MS-SMB 3.3.5.7 update to LM 0.12 4.2.4:
* If wct is 12 and CAP_LARGE_READX is set, the count may be larger
* than the negotiated buffer size. If maxcnt_high is 0xFF, it must
* be ignored. Otherwise, maxcnt_high represents the upper 16 bits
* of rw_count.
*/
{
int rc;
(maxcnt_high < 0xFF))
} else {
&remcnt);
}
smb_rw_param_t *, param);
}
void
{
}
{
int rc;
return (SDRC_ERROR);
}
return (SDRC_ERROR);
}
/*
* If this is a secondary command, the data offset
* includes the previous wct + sizeof(wct).
*/
data_offset += 60;
12, /* wct */
offset2, /* offset to next command */
0, /* set to 0 for named pipes */
datalen_low, /* data byte count */
data_offset, /* offset from start to data */
datalen_high, /* data byte count */
VAR_BCC, /* BCC marker */
0x00, /* padding */
} else {
data_offset += 59;
12, /* wct */
offset2, /* offset to next command */
-1, /* must be -1 for regular files */
datalen_low, /* data byte count */
data_offset, /* offset from start to data */
datalen_high, /* data byte count */
VAR_BCC, /* BCC marker */
}
}
/*
* protocol read functions should lookup the fid before calling this
* function. We can't move the fid lookup here because lock-and-read
* requires the fid to do locking before attempting the read.
*
* Reading from a file should break oplocks on the file to LEVEL_II.
* A call to smb_oplock_break(SMB_OPLOCK_BREAK_TO_LEVEL_II) is not
* required as it is a no-op. If there's anything greater than a
* LEVEL_II oplock on the file, the oplock MUST be owned by the ofile
* on which the read is occuring and therefore would not be broken.
*
* Returns errno values.
*/
int
{
int rc;
case STYPE_DISKTREE:
if (!smb_node_is_dir(node)) {
if (rc != NT_STATUS_SUCCESS) {
break;
}
}
/*
* SMB_FLAGS2_READ_IF_EXECUTE: permit execute-only
* reads.
*
* Reject request if the file has been opened
* execute-only and SMB_FLAGS2_READ_IF_EXECUTE is not
* set.
*/
break;
}
break;
case STYPE_IPC:
break;
default:
break;
}
if (rc != 0)
return (rc);
/*
* mincnt is only used by read-raw and is typically
* zero. If mincnt is greater than zero and the
* number of bytes read is less than mincnt, tell
* the client that we read nothing.
*/
}
return (rc);
}