smb_read.c revision 037cac007b685e7ea79f6ef7e8e62bfd342a4d56
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
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 *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * or http://www.opensolaris.org/os/licensing.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
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 *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Use is subject to license terms.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/smb_incl.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/smb_fsops.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego/*
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * The maximum number of bytes to return from SMB Core
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * SmbRead or SmbLockAndRead.
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego#define SMB_CORE_READ_MAX 4432
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego/*
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * The limit in bytes for SmbReadX.
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego#define SMB_READX_MAX 0x10000
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregoint smb_common_read(smb_request_t *, smb_rw_param_t *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Read bytes from a file or named pipe (SMB Core).
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
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 *
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 */
7b59d02d2a384be9a08087b14defadd214b3c1ddjbsmb_sdrc_t
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_pre_read(smb_request_t *sr)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *param;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint32_t off_low;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint16_t count;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint16_t remcnt;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb sr->arg.rw = param;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smbsr_decode_vwv(sr, "wwlw", &sr->smb_fid,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego &count, &off_low, &remcnt);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_offset = (uint64_t)off_low;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_count = (uint32_t)count;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_mincnt = 0;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DTRACE_SMB_2(op__Read__start, smb_request_t *, sr,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *, param);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb}
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbvoid
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_post_read(smb_request_t *sr)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DTRACE_SMB_2(op__Read__done, smb_request_t *, sr,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *, sr->arg.rw);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb}
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_sdrc_t
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_com_read(smb_request_t *sr)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *param = sr->arg.rw;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint16_t count;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb int rc;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smbsr_lookup_file(sr);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (sr->fid_ofile == NULL) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if (param->rw_count > SMB_CORE_READ_MAX)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_count = SMB_CORE_READ_MAX;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if ((rc = smb_common_read(sr, param)) != 0) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_errno(sr, rc);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego count = (uint16_t)param->rw_count;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb rc = smbsr_encode_result(sr, 5, VAR_BCC, "bw8.wbwC",
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego 5, count, VAR_BCC, 0x01, count, &sr->raw_data);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
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 *
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 *
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 *
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 */
7b59d02d2a384be9a08087b14defadd214b3c1ddjbsmb_sdrc_t
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_pre_lock_and_read(smb_request_t *sr)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *param;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint32_t off_low;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint16_t count;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint16_t remcnt;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb sr->arg.rw = param;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smbsr_decode_vwv(sr, "wwlw", &sr->smb_fid,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego &count, &off_low, &remcnt);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_offset = (uint64_t)off_low;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_count = (uint32_t)count;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_mincnt = 0;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DTRACE_SMB_2(op__LockAndRead__start, smb_request_t *, sr,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *, param);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb}
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbvoid
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_post_lock_and_read(smb_request_t *sr)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DTRACE_SMB_2(op__LockAndRead__done, smb_request_t *, sr,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *, sr->arg.rw);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_sdrc_t
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_com_lock_and_read(smb_request_t *sr)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *param = sr->arg.rw;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DWORD status;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint16_t count;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb int rc;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smbsr_lookup_file(sr);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (sr->fid_ofile == NULL) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas status = smb_lock_range(sr, param->rw_offset, (uint64_t)param->rw_count,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego 0, SMB_LOCK_TYPE_READWRITE);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (status != NT_STATUS_SUCCESS) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_lock_range_error(sr, status);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if (param->rw_count > SMB_CORE_READ_MAX)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_count = SMB_CORE_READ_MAX;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if ((rc = smb_common_read(sr, param)) != 0) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_errno(sr, rc);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego count = (uint16_t)param->rw_count;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb rc = smbsr_encode_result(sr, 5, VAR_BCC, "bw8.wbwC",
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego 5, count, VAR_BCC, 0x1, count, &sr->raw_data);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
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 *
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 *
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 *
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * Do not return errors from SmbReadRaw.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Read errors are handled by sending a zero length response.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
7b59d02d2a384be9a08087b14defadd214b3c1ddjbsmb_sdrc_t
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_pre_read_raw(smb_request_t *sr)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *param;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb uint32_t off_low;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb uint32_t off_high;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb uint32_t timeout;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint16_t count;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb int rc;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb sr->arg.rw = param;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (sr->smb_wct == 8) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb rc = smbsr_decode_vwv(sr, "wlwwl2.", &sr->smb_fid,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego &off_low, &count, &param->rw_mincnt, &timeout);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if (rc == 0) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_offset = (uint64_t)off_low;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_count = (uint32_t)count;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego }
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb } else {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb rc = smbsr_decode_vwv(sr, "wlwwl2.l", &sr->smb_fid,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego &off_low, &count, &param->rw_mincnt, &timeout, &off_high);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if (rc == 0) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_offset = ((uint64_t)off_high << 32) | off_low;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_count = (uint32_t)count;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego }
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DTRACE_SMB_2(op__ReadRaw__start, smb_request_t *, sr,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *, param);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States smb_rwx_rwenter(&sr->session->s_lock, RW_WRITER);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego return (SDRC_SUCCESS);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbvoid
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_post_read_raw(smb_request_t *sr)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mbuf_chain_t *mbc;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
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
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego while ((mbc = list_head(&sr->session->s_oplock_brkreqs)) !=
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego NULL) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego SMB_MBC_VALID(mbc);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego list_remove(&sr->session->s_oplock_brkreqs, mbc);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego (void) smb_session_send(sr->session, 0, mbc);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_mbc_free(mbc);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego }
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego }
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DTRACE_SMB_2(op__ReadRaw__done, smb_request_t *, sr,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *, sr->arg.rw);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States smb_rwx_rwexit(&sr->session->s_lock);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb}
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_sdrc_t
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_com_read_raw(smb_request_t *sr)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *param = sr->arg.rw;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb switch (sr->session->s_state) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb case SMB_SESSION_STATE_NEGOTIATED:
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego sr->session->s_state = SMB_SESSION_STATE_READ_RAW_ACTIVE;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_SESSION_STATE_OPLOCK_BREAKING:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) smb_session_send(sr->session, 0, NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (SDRC_NO_REPLY);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_SESSION_STATE_TERMINATED:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_SESSION_STATE_DISCONNECTED:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (SDRC_NO_REPLY);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego case SMB_SESSION_STATE_READ_RAW_ACTIVE:
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego sr->session->s_state = SMB_SESSION_STATE_NEGOTIATED;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego return (SDRC_DROP_VC);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb case SMB_SESSION_STATE_WRITE_RAW_ACTIVE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_SESSION_STATE_CONNECTED:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_SESSION_STATE_ESTABLISHED:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw default:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (SDRC_DROP_VC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smbsr_lookup_file(sr);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (sr->fid_ofile == NULL) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego (void) smb_session_send(sr->session, 0, NULL);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego return (SDRC_NO_REPLY);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb }
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if (param->rw_mincnt > param->rw_count)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_mincnt = 0;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if (smb_common_read(sr, param) != 0) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb (void) smb_session_send(sr->session, 0, NULL);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb m_freem(sr->raw_data.chain);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego sr->raw_data.chain = NULL;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb } else {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb (void) smb_session_send(sr->session, 0, &sr->raw_data);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb }
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_NO_REPLY);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
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 *
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.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
7b59d02d2a384be9a08087b14defadd214b3c1ddjbsmb_sdrc_t
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_pre_read_andx(smb_request_t *sr)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *param;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint32_t off_low;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint32_t off_high;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint32_t maxcnt_high;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint16_t maxcnt_low;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint16_t mincnt;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint16_t remcnt;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb sr->arg.rw = param;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (sr->smb_wct == 12) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rc = smbsr_decode_vwv(sr, "b3.wlwwlwl", &param->rw_andx,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego &sr->smb_fid, &off_low, &maxcnt_low, &mincnt, &maxcnt_high,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego &remcnt, &off_high);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_offset = ((uint64_t)off_high << 32) |
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego (uint64_t)off_low;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_count = (uint32_t)maxcnt_low;
3a6c5f83d4cb79e49561f3fad2b016450f0e6fecAlan Wright
3a6c5f83d4cb79e49561f3fad2b016450f0e6fecAlan Wright if ((sr->session->capabilities & CAP_LARGE_READX) &&
3a6c5f83d4cb79e49561f3fad2b016450f0e6fecAlan Wright (maxcnt_high < 0xFF))
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_count |= maxcnt_high << 16;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rc = smbsr_decode_vwv(sr, "b3.wlwwlw", &param->rw_andx,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego &sr->smb_fid, &off_low, &maxcnt_low, &mincnt, &maxcnt_high,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego &remcnt);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_offset = (uint64_t)off_low;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_count = (uint32_t)maxcnt_low;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_mincnt = 0;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DTRACE_SMB_2(op__ReadX__start, smb_request_t *, sr,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *, param);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbvoid
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_post_read_andx(smb_request_t *sr)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DTRACE_SMB_2(op__ReadX__done, smb_request_t *, sr,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *, sr->arg.rw);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb}
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_sdrc_t
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_com_read_andx(smb_request_t *sr)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *param = sr->arg.rw;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint16_t datalen_high;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint16_t datalen_low;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint16_t data_offset;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb uint16_t offset2;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb int rc;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smbsr_lookup_file(sr);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (sr->fid_ofile == NULL) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
b89a8333f5e1f75ec0c269b22524bd2eccb972banatalie li - Sun Microsystems - Irvine United States
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if (param->rw_count >= SMB_READX_MAX)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_count = 0;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if ((rc = smb_common_read(sr, param)) != 0) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_errno(sr, rc);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego datalen_low = param->rw_count & 0xFFFF;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego datalen_high = (param->rw_count >> 16) & 0xFF;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * If this is a secondary command, the data offset
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * includes the previous wct + sizeof(wct).
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego data_offset = (sr->andx_prev_wct == 0) ? 0 : sr->andx_prev_wct + 1;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (STYPE_ISIPC(sr->tid_tree->t_res_type)) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego data_offset += 60;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego offset2 = (param->rw_andx == 0xFF) ? 0 : param->rw_count + 60;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rc = smbsr_encode_result(sr, 12, VAR_BCC, "bb1.ww4.www8.wbC",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 12, /* wct */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_andx, /* secondary andx command */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego offset2, /* offset to next command */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego 0, /* set to 0 for named pipes */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego datalen_low, /* data byte count */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego data_offset, /* offset from start to data */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego datalen_high, /* data byte count */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw VAR_BCC, /* BCC marker */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego 0x00, /* padding */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw &sr->raw_data);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego data_offset += 59;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego offset2 = (param->rw_andx == 0xFF) ? 0 : param->rw_count + 59;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rc = smbsr_encode_result(sr, 12, VAR_BCC, "bb1.ww4.www8.wC",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw 12, /* wct */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_andx, /* secondary andx command */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego offset2, /* offset to next command */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego -1, /* must be -1 for regular files */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego datalen_low, /* data byte count */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego data_offset, /* offset from start to data */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego datalen_high, /* data byte count */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw VAR_BCC, /* BCC marker */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw &sr->raw_data);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
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 *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns errno values.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwint
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_common_read(smb_request_t *sr, smb_rw_param_t *param)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_ofile_t *ofile = sr->fid_ofile;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_t *node;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_vdb_t *vdb = &param->rw_vdb;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct mbuf *top;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego vdb->vdb_tag = 0;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego vdb->vdb_uio.uio_iov = &vdb->vdb_iovec[0];
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego vdb->vdb_uio.uio_iovcnt = MAX_IOVEC;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego vdb->vdb_uio.uio_resid = param->rw_count;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego vdb->vdb_uio.uio_loffset = (offset_t)param->rw_offset;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego vdb->vdb_uio.uio_segflg = UIO_SYSSPACE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (sr->tid_tree->t_res_type & STYPE_MASK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case STYPE_DISKTREE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw node = ofile->f_node;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh if (!smb_node_is_dir(node)) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb rc = smb_lock_range_access(sr, node, param->rw_offset,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_count, B_FALSE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != NT_STATUS_SUCCESS) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = ERANGE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if ((ofile->f_flags & SMB_OFLAGS_EXECONLY) &&
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego !(sr->smb_flg2 & SMB_FLAGS2_PAGING_IO)) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego /*
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * SMB_FLAGS2_PAGING_IO: permit execute-only reads.
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego *
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * Reject request if the file has been opened
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * execute-only and SMB_FLAGS2_PAGING_IO is not set.
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rc = EACCES;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego break;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego }
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego sr->raw_data.max_bytes = vdb->vdb_uio.uio_resid;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego top = smb_mbuf_allocate(&vdb->vdb_uio);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh rc = smb_fsop_read(sr, sr->user_cr, node, &vdb->vdb_uio);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego sr->raw_data.max_bytes -= vdb->vdb_uio.uio_resid;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_mbuf_trim(top, sr->raw_data.max_bytes);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw MBC_ATTACH_MBUF(&sr->raw_data, top);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case STYPE_IPC:
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rc = smb_opipe_read(sr, &vdb->vdb_uio);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw default:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = EACCES;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_count -= vdb->vdb_uio.uio_resid;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (rc);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (param->rw_mincnt != 0 && param->rw_count < param->rw_mincnt) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
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.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_count = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_offset += param->rw_count;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_enter(&sr->fid_ofile->f_mutex);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb ofile->f_seek_pos = param->rw_offset;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&sr->fid_ofile->f_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (rc);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}