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/*
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#include <smbsrv/smb_kproto.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/winioctl.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desaistatic uint32_t smb_nt_trans_ioctl_noop(smb_request_t *, smb_xa_t *);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic uint32_t smb_nt_trans_ioctl_invalid_parm(smb_request_t *, smb_xa_t *);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic uint32_t smb_nt_trans_ioctl_set_sparse(smb_request_t *, smb_xa_t *);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic uint32_t smb_nt_trans_ioctl_query_alloc_ranges(smb_request_t *,
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego smb_xa_t *);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic uint32_t smb_nt_trans_ioctl_set_zero_data(smb_request_t *, smb_xa_t *);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rossstatic uint32_t smb_nt_trans_ioctl_enum_snaps(smb_request_t *, smb_xa_t *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai * This table defines the list of FSCTL values for which we'll
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai * call a funtion to perform specific processing.
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh *
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * Note: If support is added for FSCTL_SET_ZERO_DATA, it must break
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * any oplocks on the file to none:
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * smb_oplock_break(sr, node, SMB_OPLOCK_BREAK_TO_NONE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
8622ec4569457733001d4982ef7f5b44427069beGordon Rossstatic const struct {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint32_t fcode;
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego uint32_t (*ioctl_func)(smb_request_t *sr, smb_xa_t *xa);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw} ioctl_ret_tbl[] = {
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai { FSCTL_GET_OBJECT_ID, smb_nt_trans_ioctl_invalid_parm },
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh { FSCTL_QUERY_ALLOCATED_RANGES, smb_nt_trans_ioctl_query_alloc_ranges },
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh { FSCTL_SET_ZERO_DATA, smb_nt_trans_ioctl_set_zero_data },
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross { FSCTL_SRV_ENUMERATE_SNAPSHOTS, smb_nt_trans_ioctl_enum_snaps },
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh { FSCTL_SET_SPARSE, smb_nt_trans_ioctl_set_sparse },
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States { FSCTL_FIND_FILES_BY_SID, smb_nt_trans_ioctl_noop }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw};
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_nt_transact_ioctl
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This command allows device and file system control functions to be
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai * transferred transparently from client to server.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Setup Words Encoding Description
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * =========================== =========================================
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * ULONG FunctionCode; NT device or file system control code
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * USHORT Fid; Handle for io or fs control. Unless BIT0
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * of ISFLAGS is set.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * BOOLEAN IsFsctl; Indicates whether the command is a device
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * control (FALSE) or a file system control
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * (TRUE).
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * UCHAR IsFlags; BIT0 - command is to be applied to share
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * root handle. Share must be a DFS share.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Data Block Encoding Description
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * =========================== =========================================
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Data[ TotalDataCount ] Passed to the Fsctl or Ioctl
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Server Response Description
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * =========================== ==================================
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * SetupCount 1
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Setup[0] Length of information returned by
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * io or fs control.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * DataCount Length of information returned by
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * io or fs control.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Data[ DataCount ] The results of the io or fs control.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
7b59d02d2a384be9a08087b14defadd214b3c1ddjbsmb_sdrc_t
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borregosmb_nt_transact_ioctl(smb_request_t *sr, smb_xa_t *xa)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai uint32_t status = NT_STATUS_NOT_SUPPORTED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint32_t fcode;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw unsigned char is_fsctl;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw unsigned char is_flags;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int i;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
3db3f65c6274eb042354801a308c8e9bc4994553amw if (smb_mbc_decodef(&xa->req_setup_mb, "lwbb",
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh &fcode, &sr->smb_fid, &is_fsctl, &is_flags) != 0) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai /*
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai * Invoke handler if specified, otherwise the default
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai * behavior is to return NT_STATUS_NOT_SUPPORTED
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai */
7b59d02d2a384be9a08087b14defadd214b3c1ddjb for (i = 0; i < sizeof (ioctl_ret_tbl) / sizeof (ioctl_ret_tbl[0]);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw i++) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ioctl_ret_tbl[i].fcode == fcode) {
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego status = ioctl_ret_tbl[i].ioctl_func(sr, xa);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
7b59d02d2a384be9a08087b14defadd214b3c1ddjb if (status != NT_STATUS_SUCCESS) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, status, 0, 0);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_ERROR);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
3db3f65c6274eb042354801a308c8e9bc4994553amw (void) smb_mbc_encodef(&xa->rep_param_mb, "l", 0);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return (SDRC_SUCCESS);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai/* ARGSUSED */
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desaistatic uint32_t
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desaismb_nt_trans_ioctl_noop(smb_request_t *sr, smb_xa_t *xa)
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai{
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai return (NT_STATUS_SUCCESS);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai}
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego/* ARGSUSED */
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borregostatic uint32_t
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borregosmb_nt_trans_ioctl_invalid_parm(smb_request_t *sr, smb_xa_t *xa)
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego{
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego return (NT_STATUS_INVALID_PARAMETER);
89dc44ce9705974a8bc4a39f1e878a0491a5be61jose borrego}
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh/*
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * smb_nt_trans_ioctl_set_sparse
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh *
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * There may, or may not be a data block in this request.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * If there IS a data block, the first byte is a boolean
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * specifying whether to set (non zero) or clear (zero)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * the sparse attribute of the file.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * If there is no data block, this indicates a request to
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * set the sparse attribute.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic uint32_t
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshsmb_nt_trans_ioctl_set_sparse(smb_request_t *sr, smb_xa_t *xa)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh{
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh int rc = 0;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh uint8_t set = 1;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross smb_ofile_t *of;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_attr_t attr;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (SMB_TREE_IS_READONLY(sr))
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NT_STATUS_ACCESS_DENIED);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (STYPE_ISIPC(sr->tid_tree->t_res_type))
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NT_STATUS_INVALID_PARAMETER);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_lookup_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (sr->fid_ofile == NULL)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NT_STATUS_INVALID_HANDLE);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_release_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NT_STATUS_INVALID_PARAMETER);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross of = sr->fid_ofile;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (smb_node_is_dir(of->f_node)) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_release_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NT_STATUS_INVALID_PARAMETER);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (smbsr_decode_data_avail(sr)) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (smb_mbc_decodef(&xa->req_data_mb, "b", &set) != 0) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_release_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (sr->smb_error.status);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross /*
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Using kcred because we just want the DOS attrs
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * and don't want access errors for this.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh bzero(&attr, sizeof (smb_attr_t));
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh attr.sa_mask = SMB_AT_DOSATTR;
8622ec4569457733001d4982ef7f5b44427069beGordon Ross rc = smb_node_getattr(sr, of->f_node, zone_kcred(), of, &attr);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (rc != 0) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_errno(sr, rc);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_release_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (sr->smb_error.status);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh attr.sa_mask = 0;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if ((set == 0) &&
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (attr.sa_dosattr & FILE_ATTRIBUTE_SPARSE_FILE)) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh attr.sa_dosattr &= ~FILE_ATTRIBUTE_SPARSE_FILE;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh attr.sa_mask = SMB_AT_DOSATTR;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh } else if ((set != 0) &&
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh !(attr.sa_dosattr & FILE_ATTRIBUTE_SPARSE_FILE)) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh attr.sa_dosattr |= FILE_ATTRIBUTE_SPARSE_FILE;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh attr.sa_mask = SMB_AT_DOSATTR;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (attr.sa_mask != 0) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross rc = smb_node_setattr(sr, of->f_node, of->f_cr, of, &attr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (rc != 0) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_errno(sr, rc);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_release_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (sr->smb_error.status);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_release_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NT_STATUS_SUCCESS);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh}
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh/*
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * smb_nt_trans_ioctl_set_zero_data
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh *
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * Check that the request is valid on the specified file.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * The implementation is a noop.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh/* ARGSUSED */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic uint32_t
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshsmb_nt_trans_ioctl_set_zero_data(smb_request_t *sr, smb_xa_t *xa)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh{
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_node_t *node;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (SMB_TREE_IS_READONLY(sr))
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NT_STATUS_ACCESS_DENIED);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (STYPE_ISIPC(sr->tid_tree->t_res_type))
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NT_STATUS_INVALID_PARAMETER);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_lookup_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (sr->fid_ofile == NULL)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NT_STATUS_INVALID_HANDLE);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_release_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NT_STATUS_INVALID_PARAMETER);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh node = sr->fid_ofile->f_node;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (smb_node_is_dir(node)) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_release_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NT_STATUS_INVALID_PARAMETER);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_release_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NT_STATUS_SUCCESS);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh}
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh/*
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * smb_nt_trans_ioctl_query_alloc_ranges
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh *
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * Responds with either:
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * - no data if the file is zero size
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * - a single range containing the starting point and length requested
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic uint32_t
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshsmb_nt_trans_ioctl_query_alloc_ranges(smb_request_t *sr, smb_xa_t *xa)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh{
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh int rc;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh uint64_t offset, len;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross smb_ofile_t *of;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_attr_t attr;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (STYPE_ISIPC(sr->tid_tree->t_res_type))
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NT_STATUS_INVALID_PARAMETER);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_lookup_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (sr->fid_ofile == NULL)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NT_STATUS_INVALID_HANDLE);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_release_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NT_STATUS_INVALID_PARAMETER);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross of = sr->fid_ofile;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (smb_node_is_dir(of->f_node)) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_release_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NT_STATUS_INVALID_PARAMETER);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh /* If zero size file don't return any data */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh bzero(&attr, sizeof (smb_attr_t));
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh attr.sa_mask = SMB_AT_SIZE;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross rc = smb_node_getattr(sr, of->f_node, of->f_cr, of, &attr);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (rc != 0) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_errno(sr, rc);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_release_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (sr->smb_error.status);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (attr.sa_vattr.va_size == 0) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_release_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NT_STATUS_SUCCESS);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (smb_mbc_decodef(&xa->req_data_mb, "qq", &offset, &len) != 0) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_release_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (sr->smb_error.status);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh /*
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * Return a single range regardless of whether the file
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * is sparse or not.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (MBC_ROOM_FOR(&xa->rep_data_mb, 16) == 0) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_release_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NT_STATUS_BUFFER_TOO_SMALL);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (smb_mbc_encodef(&xa->rep_data_mb, "qq", offset, len) != 0) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_release_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (sr->smb_error.status);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbsr_release_file(sr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NT_STATUS_SUCCESS);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh}
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rossstatic uint32_t
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rosssmb_nt_trans_ioctl_enum_snaps(smb_request_t *sr, smb_xa_t *xa)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross{
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb_fsctl_t fsctl;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross uint32_t status;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (STYPE_ISIPC(sr->tid_tree->t_res_type))
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (NT_STATUS_INVALID_PARAMETER);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smbsr_lookup_file(sr);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (sr->fid_ofile == NULL)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (NT_STATUS_INVALID_HANDLE);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smbsr_release_file(sr);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (NT_STATUS_INVALID_PARAMETER);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross fsctl.CtlCode = FSCTL_SRV_ENUMERATE_SNAPSHOTS;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross fsctl.InputCount = xa->smb_tpscnt;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross fsctl.OutputCount = 0;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross fsctl.MaxOutputResp = xa->smb_mdrcnt;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross fsctl.in_mbc = &xa->req_param_mb;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross fsctl.out_mbc = &xa->rep_data_mb;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = smb_vss_enum_snapshots(sr, &fsctl);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smbsr_release_file(sr);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (status);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross}