smb_read.c revision 2c2961f8403049d948b9f3e6c35d6488b6b7e1aa
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
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Use is subject to license terms.
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * The maximum number of bytes to return from SMB Core
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * SmbRead or SmbLockAndRead.
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * The limit in bytes for SmbReadX.
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregoint smb_common_read(smb_request_t *, smb_rw_param_t *);
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.
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego 5, count, VAR_BCC, 0x01, 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);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas status = smb_lock_range(sr, param->rw_offset, (uint64_t)param->rw_count,
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.
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * Do not return errors from SmbReadRaw.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Read errors are handled by sending a zero length response.
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego &off_low, &count, ¶m->rw_mincnt, &timeout);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego &off_low, &count, ¶m->rw_mincnt, &timeout, &off_high);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_offset = ((uint64_t)off_high << 32) | off_low;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if (sr->session->s_state == SMB_SESSION_STATE_READ_RAW_ACTIVE) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego sr->session->s_state = SMB_SESSION_STATE_NEGOTIATED;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego while ((mbc = list_head(&sr->session->s_oplock_brkreqs)) !=
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego list_remove(&sr->session->s_oplock_brkreqs, mbc);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego sr->session->s_state = SMB_SESSION_STATE_READ_RAW_ACTIVE;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego sr->session->s_state = SMB_SESSION_STATE_NEGOTIATED;
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
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.
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * MS-SMB 3.3.5.7 update to LM 0.12 4.2.4:
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * If wct is 12 and CAP_LARGE_READX is set, the count may be larger
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * than the negotiated buffer size. If maxcnt_high is 0xFF, it must
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * be ignored. Otherwise, maxcnt_high represents the upper 16 bits
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * of rw_count.
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rc = smbsr_decode_vwv(sr, "b3.wlwwlwl", ¶m->rw_andx,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego &sr->smb_fid, &off_low, &maxcnt_low, &mincnt, &maxcnt_high,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_offset = ((uint64_t)off_high << 32) |
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rc = smbsr_decode_vwv(sr, "b3.wlwwlw", ¶m->rw_andx,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego &sr->smb_fid, &off_low, &maxcnt_low, &mincnt, &maxcnt_high,
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * If this is a secondary command, the data offset
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * includes the previous wct + sizeof(wct).
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego data_offset = (sr->andx_prev_wct == 0) ? 0 : sr->andx_prev_wct + 1;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego offset2 = (param->rw_andx == 0xFF) ? 0 : param->rw_count + 60;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rc = smbsr_encode_result(sr, 12, VAR_BCC, "bb1.ww4.www8.wbC",
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego 0, /* set to 0 for named pipes */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego offset2 = (param->rw_andx == 0xFF) ? 0 : param->rw_count + 59;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rc = smbsr_encode_result(sr, 12, VAR_BCC, "bb1.ww4.www8.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.
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego vdb->vdb_uio.uio_loffset = (offset_t)param->rw_offset;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * SMB_FLAGS2_PAGING_IO: permit execute-only reads.
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * Reject request if the file has been opened
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * execute-only and SMB_FLAGS2_PAGING_IO is not set.
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego sr->raw_data.max_bytes = vdb->vdb_uio.uio_resid;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rc = smb_fsop_read(sr, sr->user_cr, node, &vdb->vdb_uio,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego sr->raw_data.max_bytes -= vdb->vdb_uio.uio_resid;
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.