smb_read.c revision 6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2e
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The contents of this file are subject to the terms of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Common Development and Distribution License (the "License").
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You may not use this file except in compliance with the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * When distributing Covered Code, include this CDDL HEADER in each
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If applicable, add the following below this CDDL HEADER, with the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fields enclosed by brackets "[]" replaced with your own identifying
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * information: Portions Copyright [yyyy] [name of copyright owner]
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Use is subject to license terms.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#pragma ident "%Z%%M% %I% %E% SMI"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Read bytes from a file or named pipe (SMB Core).
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The requested count specifies the number of bytes desired. Offset
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * is limited to 32 bits, so this client request is inappropriate for
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * files with 64 bit offsets.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * On return, count is the number of bytes actually being returned, which
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * may be less than the count requested only if a read specifies bytes
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * beyond the current file size. In this case only the bytes that exist
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * are returned. A read completely beyond the end of file results in a
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * response of length zero. This is the only circumstance when a zero
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * length response is generated. A count returned which is less than the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * count requested is the end of file indicator.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb 5, param->rw_count, VAR_BCC, 0x01, param->rw_count, &sr->raw_data);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Lock and read bytes from a file (SMB Core Plus). The SmbLockAndRead/
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * SmbLockAndWrite sub-dialect is only valid on disk files: reject any
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * attempt to use it on non-disk shares.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The requested count specifies the number of bytes desired. Offset
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * specifies the offset in the file of the first byte to be locked then
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * read. Note that offset is limited to 32 bits, so this client request
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * is inappropriate for files with 64 bit offsets.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * As with SMB_LOCK_BYTE_RANGE request, if the lock cannot be granted
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * immediately an error should be returned to the client. If an error
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * occurs on the lock, the bytes should not be read.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * On return, count is the number of bytes actually being returned, which
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * may be less than the count requested only if a read specifies bytes
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * beyond the current file size. In this case only the bytes that exist
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * are returned. A read completely beyond the end of file results in a
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * response of length zero. This is the only circumstance when a zero
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * length response is generated. A count returned which is less than the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * count requested is the end of file indicator.
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DTRACE_SMB_2(op__LockAndRead__start, smb_request_t *, sr,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas status = smb_lock_range(sr, param->rw_offset, (uint64_t)param->rw_count,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb 5, param->rw_count, VAR_BCC, 0x1, param->rw_count, &sr->raw_data);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The SMB_COM_READ_RAW protocol is a negotiated option introduced in
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * SMB Core Plus to maximize performance when reading a large block
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * of data from a server. This request was extended in LM 0.12 to
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * support 64-bit offsets; the server can indicate support by setting
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CAP_LARGE_FILES in the negotiated capabilities.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The client must guarantee that there is (and will be) no other request
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to the server for the duration of the SMB_COM_READ_RAW, since the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * server response has no header or trailer. To help ensure that there
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * are no interruptions, we block all I/O for the session during read raw.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If this is the first SMB request received since we sent an oplock break
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to this client, we don't know if it's safe to send the raw data because
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the requests may have crossed on the wire and the client may have
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * interpreted the oplock break as part of the raw data. To avoid problems,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * we send a zero length session packet, which will force the client to
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * retry the read.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Read errors are handled by sending a zero length response.
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (rc != 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Read bytes from a file (SMB Core). This request was extended in
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * LM 0.12 to support 64-bit offsets, indicated by sending a wct of
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * 12 and including additional offset information.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Ensure that the next response offset is zero
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * if there is no secondary command.
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb offset2 = (param->rw_andx == 0xFF) ? 0 : param->rw_count + 59;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The STYPE_IPC response format is different.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The unknown value (2) may be to indicate that it
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * is a follow-up to an earlier RPC transaction.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb rc = smbsr_encode_result(sr, 12, VAR_BCC, "bb1.ww4.ww10.wbC",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 0, /* must be 0 */
7b59d02d2a384be9a08087b14defadd214b3c1ddjb rc = smbsr_encode_result(sr, 12, VAR_BCC, "bb1.ww4.ww10.wC",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Common function for reading files or IPC/MSRPC named pipes. All
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * protocol read functions should lookup the fid before calling this
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * function. We can't move the fid lookup here because lock-and-read
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * requires the fid to do locking before attempting the read.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns errno values.
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (param->rw_mincnt != 0 && param->rw_count < param->rw_mincnt) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * mincnt is only used by read-raw and is typically
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * zero. If mincnt is greater than zero and the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * number of bytes read is less than mincnt, tell
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the client that we read nothing.