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 */
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
1fb4a876cbadf3a151ab8a149be6956199e83e22Gordon Ross * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <sys/sdt.h>
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#include <smbsrv/smb_kproto.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/smb_fsops.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/netbios.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbstatic int smb_write_truncate(smb_request_t *, smb_rw_param_t *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Write count bytes at the specified offset in a file. The offset is
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * limited to 32-bits. If the count is zero, the file is truncated to
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the length specified by the offset.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The response count indicates the actual number of bytes written, which
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * will equal the requested count on success. If request and response
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * counts differ but there is no error, the client will assume that the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * server encountered a resource issue.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
7b59d02d2a384be9a08087b14defadd214b3c1ddjbsmb_sdrc_t
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_pre_write(smb_request_t *sr)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *param;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint32_t off;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint16_t count;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb sr->arg.rw = param;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_magic = SMB_RW_MAGIC;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rc = smbsr_decode_vwv(sr, "wwl", &sr->smb_fid, &count, &off);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_count = (uint32_t)count;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_offset = (uint64_t)off;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_vdb.vdb_uio.uio_loffset = (offset_t)param->rw_offset;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DTRACE_SMB_2(op__Write__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_write(smb_request_t *sr)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DTRACE_SMB_2(op__Write__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_write(smb_request_t *sr)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *param = sr->arg.rw;
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
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (param->rw_count == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smb_write_truncate(sr, param);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb rc = smbsr_decode_data(sr, "D", &param->rw_vdb);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if ((rc != 0) || (param->rw_vdb.vdb_len != param->rw_count)) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb ERRDOS, ERROR_INVALID_PARAMETER);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_vdb.vdb_uio.uio_loffset = (offset_t)param->rw_offset;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright rc = smb_common_write(sr, param);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != 0) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (sr->smb_error.status != NT_STATUS_FILE_LOCK_CONFLICT)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smbsr_errno(sr, rc);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rc = smbsr_encode_result(sr, 1, 0, "bww", 1,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego (uint16_t)param->rw_count, 0);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Write count bytes to a file and then close the file. This function
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * can only be used to write to 32-bit offsets and the client must set
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * WordCount (6 or 12) correctly in order to locate the data to be
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * written. If an error occurs on the write, the file should still be
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * closed. If Count is 0, the file is truncated (or extended) to offset.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If the last_write time is non-zero, last_write should be used to set
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the mtime. Otherwise the file system stamps the mtime. Failure to
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * set mtime should not result in an error response.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
7b59d02d2a384be9a08087b14defadd214b3c1ddjbsmb_sdrc_t
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_pre_write_and_close(smb_request_t *sr)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *param;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint32_t off;
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;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_magic = SMB_RW_MAGIC;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (sr->smb_wct == 12) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smbsr_decode_vwv(sr, "wwll12.", &sr->smb_fid,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego &count, &off, &param->rw_last_write);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smbsr_decode_vwv(sr, "wwll", &sr->smb_fid,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego &count, &off, &param->rw_last_write);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_count = (uint32_t)count;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_offset = (uint64_t)off;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DTRACE_SMB_2(op__WriteAndClose__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_write_and_close(smb_request_t *sr)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DTRACE_SMB_2(op__WriteAndClose__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_write_and_close(smb_request_t *sr)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *param = sr->arg.rw;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint16_t count;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb int rc = 0;
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
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (param->rw_count == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smb_write_truncate(sr, param);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * There may be a bug here: should this be "3.#B"?
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb rc = smbsr_decode_data(sr, ".#B", param->rw_count,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb &param->rw_vdb);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if ((rc != 0) || (param->rw_vdb.vdb_len != param->rw_count)) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb ERRDOS, ERROR_INVALID_PARAMETER);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_vdb.vdb_uio.uio_loffset = (offset_t)param->rw_offset;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright rc = smb_common_write(sr, param);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != 0) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (sr->smb_error.status != NT_STATUS_FILE_LOCK_CONFLICT)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smbsr_errno(sr, rc);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego smb_ofile_close(sr->fid_ofile, param->rw_last_write);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego count = (uint16_t)param->rw_count;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rc = smbsr_encode_result(sr, 1, 0, "bww", 1, count, 0);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Write count bytes to a file at the specified offset and then unlock
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * them. Write behind is safe because the client should have the range
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * locked and this request is allowed to extend the file - note that
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * offset is limited to 32-bits.
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb *
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * Spec advice: it is an error for count to be zero. For compatibility,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * we take no action and return success.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The SmbLockAndRead/SmbWriteAndUnlock sub-dialect is only valid on disk
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * files. Reject any attempt to use it on other shares.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The response count indicates the actual number of bytes written, which
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * will equal the requested count on success. If request and response
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * counts differ but there is no error, the client will assume that the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * server encountered a resource issue.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
7b59d02d2a384be9a08087b14defadd214b3c1ddjbsmb_sdrc_t
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_pre_write_and_unlock(smb_request_t *sr)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *param;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint32_t off;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint16_t count;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint16_t remcnt;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb int rc;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb sr->arg.rw = param;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_magic = SMB_RW_MAGIC;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rc = smbsr_decode_vwv(sr, "wwlw", &sr->smb_fid, &count, &off, &remcnt);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_count = (uint32_t)count;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_offset = (uint64_t)off;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DTRACE_SMB_2(op__WriteAndUnlock__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_write_and_unlock(smb_request_t *sr)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DTRACE_SMB_2(op__WriteAndUnlock__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_write_and_unlock(smb_request_t *sr)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *param = sr->arg.rw;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb uint32_t status;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
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
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (param->rw_count == 0) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb rc = smbsr_encode_result(sr, 1, 0, "bww", 1, 0, 0);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb rc = smbsr_decode_data(sr, "D", &param->rw_vdb);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if ((rc != 0) || (param->rw_count != param->rw_vdb.vdb_len)) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb ERRDOS, ERROR_INVALID_PARAMETER);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_vdb.vdb_uio.uio_loffset = (offset_t)param->rw_offset;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright if ((rc = smb_common_write(sr, param)) != 0) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (sr->smb_error.status != NT_STATUS_FILE_LOCK_CONFLICT)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smbsr_errno(sr, rc);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb status = smb_unlock_range(sr, sr->fid_ofile->f_node, param->rw_offset,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb (uint64_t)param->rw_count);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (status != NT_STATUS_SUCCESS) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright ERRDOS, ERROR_NOT_LOCKED);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rc = smbsr_encode_result(sr, 1, 0, "bww", 1,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego (uint16_t)param->rw_count, 0);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Write bytes to 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 * 14, instead of 12, and including additional offset information.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * A ByteCount of 0 does not truncate the file - use SMB_COM_WRITE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to truncate a file. A zero length merely transfers zero bytes.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If bit 0 of WriteMode is set, Fid must refer to a disk file and
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the data must be on stable storage before responding.
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego *
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * MS-SMB 3.3.5.8 update to LM 0.12 4.2.5:
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * If CAP_LARGE_WRITEX is set, the byte count may be larger than the
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * negotiated buffer size and the server is expected to write the
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * number of bytes specified.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
7b59d02d2a384be9a08087b14defadd214b3c1ddjbsmb_sdrc_t
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_pre_write_andx(smb_request_t *sr)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *param;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint32_t off_low;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint32_t off_high;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint16_t datalen_low;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint16_t datalen_high;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint16_t remcnt;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb int rc;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb sr->arg.rw = param;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_magic = SMB_RW_MAGIC;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (sr->smb_wct == 14) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rc = smbsr_decode_vwv(sr, "4.wl4.wwwwwl", &sr->smb_fid,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego &off_low, &param->rw_mode, &remcnt, &datalen_high,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego &datalen_low, &param->rw_dsoff, &off_high);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1fb4a876cbadf3a151ab8a149be6956199e83e22Gordon Ross if (param->rw_dsoff >= 63)
1fb4a876cbadf3a151ab8a149be6956199e83e22Gordon Ross param->rw_dsoff -= 63;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_offset = ((uint64_t)off_high << 32) | off_low;
1fb4a876cbadf3a151ab8a149be6956199e83e22Gordon Ross } else if (sr->smb_wct == 12) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rc = smbsr_decode_vwv(sr, "4.wl4.wwwww", &sr->smb_fid,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego &off_low, &param->rw_mode, &remcnt, &datalen_high,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego &datalen_low, &param->rw_dsoff);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1fb4a876cbadf3a151ab8a149be6956199e83e22Gordon Ross if (param->rw_dsoff >= 59)
1fb4a876cbadf3a151ab8a149be6956199e83e22Gordon Ross param->rw_dsoff -= 59;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_offset = (uint64_t)off_low;
1fb4a876cbadf3a151ab8a149be6956199e83e22Gordon Ross /* off_high not present */
1fb4a876cbadf3a151ab8a149be6956199e83e22Gordon Ross } else {
1fb4a876cbadf3a151ab8a149be6956199e83e22Gordon Ross rc = -1;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
3a6c5f83d4cb79e49561f3fad2b016450f0e6fecAlan Wright param->rw_count = (uint32_t)datalen_low;
3a6c5f83d4cb79e49561f3fad2b016450f0e6fecAlan Wright
1fb4a876cbadf3a151ab8a149be6956199e83e22Gordon Ross /*
1fb4a876cbadf3a151ab8a149be6956199e83e22Gordon Ross * Work-around a Win7 bug, where it fails to set the
1fb4a876cbadf3a151ab8a149be6956199e83e22Gordon Ross * CAP_LARGE_WRITEX flag during session setup. Assume
1fb4a876cbadf3a151ab8a149be6956199e83e22Gordon Ross * a large write if the data remaining is >= 64k.
1fb4a876cbadf3a151ab8a149be6956199e83e22Gordon Ross */
1fb4a876cbadf3a151ab8a149be6956199e83e22Gordon Ross if ((sr->session->capabilities & CAP_LARGE_WRITEX) != 0 ||
1fb4a876cbadf3a151ab8a149be6956199e83e22Gordon Ross (sr->smb_data.max_bytes > (sr->smb_data.chain_offset + 0xFFFF)))
3a6c5f83d4cb79e49561f3fad2b016450f0e6fecAlan Wright param->rw_count |= ((uint32_t)datalen_high << 16);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DTRACE_SMB_2(op__WriteX__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_write_andx(smb_request_t *sr)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb DTRACE_SMB_2(op__WriteX__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_write_andx(smb_request_t *sr)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_rw_param_t *param = sr->arg.rw;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint16_t count_high;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint16_t count_low;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb int rc;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb ASSERT(param);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb ASSERT(param->rw_magic == SMB_RW_MAGIC);
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
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (SMB_WRMODE_IS_STABLE(param->rw_mode) &&
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright STYPE_ISIPC(sr->tid_tree->t_res_type)) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, 0, ERRSRV, ERRaccess);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb rc = smbsr_decode_data(sr, "#.#B", param->rw_dsoff, param->rw_count,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb &param->rw_vdb);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if ((rc != 0) || (param->rw_vdb.vdb_len != param->rw_count)) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb ERRDOS, ERROR_INVALID_PARAMETER);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_vdb.vdb_uio.uio_loffset = (offset_t)param->rw_offset;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (param->rw_count != 0) {
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright if ((rc = smb_common_write(sr, param)) != 0) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (sr->smb_error.status !=
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb NT_STATUS_FILE_LOCK_CONFLICT)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smbsr_errno(sr, rc);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego count_low = param->rw_count & 0xFFFF;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego count_high = (param->rw_count >> 16) & 0xFF;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rc = smbsr_encode_result(sr, 6, 0, "bb1.wwwwww",
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego 6, sr->andx_com, 15, count_low, 0, count_high, 0, 0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Common function for writing files or IPC/MSRPC named pipes.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns errno values.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wrightint
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wrightsmb_common_write(smb_request_t *sr, smb_rw_param_t *param)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_ofile_t *ofile = sr->fid_ofile;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_t *node;
3db3f65c6274eb042354801a308c8e9bc4994553amw int stability = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint32_t lcount;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (sr->tid_tree->t_res_type & STYPE_MASK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case STYPE_DISKTREE:
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright case STYPE_PRINTQ:
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_TRUE);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (rc != NT_STATUS_SUCCESS) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smbsr_error(sr, NT_STATUS_FILE_LOCK_CONFLICT,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb ERRDOS, ERROR_LOCK_VIOLATION);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (EACCES);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (SMB_WRMODE_IS_STABLE(param->rw_mode) ||
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (node->flags & NODE_FLAGS_WRITE_THROUGH)) {
3db3f65c6274eb042354801a308c8e9bc4994553amw stability = FSYNC;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smb_fsop_write(sr, sr->user_cr, node,
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh &param->rw_vdb.vdb_uio, &lcount, stability);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (rc);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross /*
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Used to have code here to set mtime.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * We have just done a write, so we know
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * the file system will update mtime.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * No need to do it again here.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross *
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * However, keep track of the fact that
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * we have written data via this handle.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross ofile->f_written = B_TRUE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh if (!smb_node_is_dir(node))
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh smb_oplock_break_levelII(node);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_count = lcount;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case STYPE_IPC:
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego param->rw_count = param->rw_vdb.vdb_uio.uio_resid;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if ((rc = smb_opipe_write(sr, &param->rw_vdb.vdb_uio)) != 0)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_count = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw default:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = EACCES;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (rc);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_enter(&ofile->f_mutex);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb ofile->f_seek_pos = param->rw_offset + param->rw_count;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&ofile->f_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (rc);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Truncate a disk file to the specified offset.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Typically, w_count will be zero here.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * Note that smb_write_andx cannot be used to reduce the file size so,
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * if this is required, smb_write is called with a count of zero and
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * the appropriate file length in offset. The file should be resized
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * to the length specified by the offset.
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns errno values.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
7b59d02d2a384be9a08087b14defadd214b3c1ddjbstatic int
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_write_truncate(smb_request_t *sr, smb_rw_param_t *param)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_ofile_t *ofile = sr->fid_ofile;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_t *node = ofile->f_node;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_attr_t attr;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb uint32_t status;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright if (STYPE_ISIPC(sr->tid_tree->t_res_type))
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mutex_enter(&node->n_mutex);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh if (!smb_node_is_dir(node)) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb status = smb_lock_range_access(sr, node, param->rw_offset,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb param->rw_count, B_TRUE);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb if (status != NT_STATUS_SUCCESS) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mutex_exit(&node->n_mutex);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smbsr_error(sr, NT_STATUS_FILE_LOCK_CONFLICT,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb ERRDOS, ERROR_LOCK_VIOLATION);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (EACCES);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as }
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as }
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mutex_exit(&node->n_mutex);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh bzero(&attr, sizeof (smb_attr_t));
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh attr.sa_mask = SMB_AT_SIZE;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh attr.sa_vattr.va_size = param->rw_offset;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh rc = smb_node_setattr(sr, node, sr->user_cr, ofile, &attr);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh if (rc != 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (rc);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_enter(&ofile->f_mutex);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb ofile->f_seek_pos = param->rw_offset + param->rw_count;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&ofile->f_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}