xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c (revision fd9ee8b58485b20072eeef1310a88ff348d5e7fa)
1da6c28aaSamw /*
2da6c28aaSamw  * CDDL HEADER START
3da6c28aaSamw  *
4da6c28aaSamw  * The contents of this file are subject to the terms of the
5da6c28aaSamw  * Common Development and Distribution License (the "License").
6da6c28aaSamw  * You may not use this file except in compliance with the License.
7da6c28aaSamw  *
8da6c28aaSamw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9da6c28aaSamw  * or http://www.opensolaris.org/os/licensing.
10da6c28aaSamw  * See the License for the specific language governing permissions
11da6c28aaSamw  * and limitations under the License.
12da6c28aaSamw  *
13da6c28aaSamw  * When distributing Covered Code, include this CDDL HEADER in each
14da6c28aaSamw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15da6c28aaSamw  * If applicable, add the following below this CDDL HEADER, with the
16da6c28aaSamw  * fields enclosed by brackets "[]" replaced with your own identifying
17da6c28aaSamw  * information: Portions Copyright [yyyy] [name of copyright owner]
18da6c28aaSamw  *
19da6c28aaSamw  * CDDL HEADER END
20da6c28aaSamw  */
21da6c28aaSamw /*
22cb174861Sjoyce mcintosh  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23da6c28aaSamw  */
24da6c28aaSamw 
25bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h>
26da6c28aaSamw #include <smbsrv/winioctl.h>
27da6c28aaSamw 
28e3f2c991SKeyur Desai 
29e3f2c991SKeyur Desai static uint32_t smb_nt_trans_ioctl_noop(smb_request_t *, smb_xa_t *);
30*fd9ee8b5Sjoyce mcintosh static uint32_t smb_nt_trans_ioctl_invalid_parm(smb_request_t *, smb_xa_t *);
31*fd9ee8b5Sjoyce mcintosh static uint32_t smb_nt_trans_ioctl_set_sparse(smb_request_t *, smb_xa_t *);
32*fd9ee8b5Sjoyce mcintosh static uint32_t smb_nt_trans_ioctl_query_alloc_ranges(smb_request_t *,
3389dc44ceSjose borrego     smb_xa_t *);
34*fd9ee8b5Sjoyce mcintosh static uint32_t smb_nt_trans_ioctl_set_zero_data(smb_request_t *, smb_xa_t *);
35da6c28aaSamw 
36da6c28aaSamw /*
37e3f2c991SKeyur Desai  * This table defines the list of FSCTL values for which we'll
38e3f2c991SKeyur Desai  * call a funtion to perform specific processing.
39cb174861Sjoyce mcintosh  *
40cb174861Sjoyce mcintosh  * Note: If support is added for FSCTL_SET_ZERO_DATA, it must break
41cb174861Sjoyce mcintosh  * any oplocks on the file to none:
42cb174861Sjoyce mcintosh  *   smb_oplock_break(sr, node, SMB_OPLOCK_BREAK_TO_NONE);
43da6c28aaSamw  */
44da6c28aaSamw static struct {
45da6c28aaSamw 	uint32_t fcode;
4689dc44ceSjose borrego 	uint32_t (*ioctl_func)(smb_request_t *sr, smb_xa_t *xa);
47da6c28aaSamw } ioctl_ret_tbl[] = {
4889dc44ceSjose borrego 	{ FSCTL_GET_OBJECT_ID, smb_nt_trans_ioctl_invalid_parm },
49*fd9ee8b5Sjoyce mcintosh 	{ FSCTL_QUERY_ALLOCATED_RANGES, smb_nt_trans_ioctl_query_alloc_ranges },
50*fd9ee8b5Sjoyce mcintosh 	{ FSCTL_SET_ZERO_DATA, smb_nt_trans_ioctl_set_zero_data },
51e3f2c991SKeyur Desai 	{ FSCTL_SRV_ENUMERATE_SNAPSHOTS, smb_vss_ioctl_enumerate_snaps },
52*fd9ee8b5Sjoyce mcintosh 	{ FSCTL_SET_SPARSE, smb_nt_trans_ioctl_set_sparse },
539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	{ FSCTL_FIND_FILES_BY_SID, smb_nt_trans_ioctl_noop }
54da6c28aaSamw };
55da6c28aaSamw 
56da6c28aaSamw /*
57da6c28aaSamw  * smb_nt_transact_ioctl
58da6c28aaSamw  *
59da6c28aaSamw  * This command allows device and file system control functions to be
60e3f2c991SKeyur Desai  * transferred transparently from client to server.
61da6c28aaSamw  *
62da6c28aaSamw  * Setup Words Encoding        Description
63da6c28aaSamw  * =========================== =========================================
64da6c28aaSamw  * ULONG FunctionCode;         NT device or file system control code
65da6c28aaSamw  * USHORT Fid;                 Handle for io or fs control. Unless BIT0
66da6c28aaSamw  *                             of ISFLAGS is set.
67da6c28aaSamw  * BOOLEAN IsFsctl;            Indicates whether the command is a device
68da6c28aaSamw  *                             control (FALSE) or a file system control
69da6c28aaSamw  *                             (TRUE).
70da6c28aaSamw  * UCHAR   IsFlags;            BIT0 - command is to be applied to share
71da6c28aaSamw  *                             root handle. Share must be a DFS share.
72da6c28aaSamw  *
73da6c28aaSamw  * Data Block Encoding         Description
74da6c28aaSamw  * =========================== =========================================
75da6c28aaSamw  * Data[ TotalDataCount ]      Passed to the Fsctl or Ioctl
76da6c28aaSamw  *
77da6c28aaSamw  * Server Response             Description
78da6c28aaSamw  * =========================== ==================================
79da6c28aaSamw  * SetupCount                  1
80da6c28aaSamw  * Setup[0]                    Length of information returned by
81da6c28aaSamw  *                             io or fs control.
82da6c28aaSamw  * DataCount                   Length of information returned by
83da6c28aaSamw  *                             io or fs control.
84da6c28aaSamw  * Data[ DataCount ]           The results of the io or fs control.
85da6c28aaSamw  */
867b59d02dSjb150015 smb_sdrc_t
8789dc44ceSjose borrego smb_nt_transact_ioctl(smb_request_t *sr, smb_xa_t *xa)
88da6c28aaSamw {
89e3f2c991SKeyur Desai 	uint32_t status = NT_STATUS_NOT_SUPPORTED;
90da6c28aaSamw 	uint32_t fcode;
91da6c28aaSamw 	unsigned char is_fsctl;
92da6c28aaSamw 	unsigned char is_flags;
93da6c28aaSamw 	int i;
94da6c28aaSamw 
953db3f65cSamw 	if (smb_mbc_decodef(&xa->req_setup_mb, "lwbb",
96*fd9ee8b5Sjoyce mcintosh 	    &fcode, &sr->smb_fid, &is_fsctl, &is_flags) != 0) {
97dc20a302Sas200622 		smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
98faa1795aSjb150015 		return (SDRC_ERROR);
99da6c28aaSamw 	}
100da6c28aaSamw 
101e3f2c991SKeyur Desai 	/*
102e3f2c991SKeyur Desai 	 * Invoke handler if specified, otherwise the default
103e3f2c991SKeyur Desai 	 * behavior is to return NT_STATUS_NOT_SUPPORTED
104e3f2c991SKeyur Desai 	 */
1057b59d02dSjb150015 	for (i = 0; i < sizeof (ioctl_ret_tbl) / sizeof (ioctl_ret_tbl[0]);
106da6c28aaSamw 	    i++) {
107da6c28aaSamw 		if (ioctl_ret_tbl[i].fcode == fcode) {
10889dc44ceSjose borrego 			status = ioctl_ret_tbl[i].ioctl_func(sr, xa);
109da6c28aaSamw 			break;
110da6c28aaSamw 		}
111da6c28aaSamw 	}
112da6c28aaSamw 
1137b59d02dSjb150015 	if (status != NT_STATUS_SUCCESS) {
114dc20a302Sas200622 		smbsr_error(sr, status, 0, 0);
115faa1795aSjb150015 		return (SDRC_ERROR);
1167b59d02dSjb150015 	}
117da6c28aaSamw 
1183db3f65cSamw 	(void) smb_mbc_encodef(&xa->rep_param_mb, "l", 0);
119faa1795aSjb150015 	return (SDRC_SUCCESS);
120da6c28aaSamw }
12189dc44ceSjose borrego 
12289dc44ceSjose borrego /* ARGSUSED */
12389dc44ceSjose borrego static uint32_t
124e3f2c991SKeyur Desai smb_nt_trans_ioctl_noop(smb_request_t *sr, smb_xa_t *xa)
125e3f2c991SKeyur Desai {
126e3f2c991SKeyur Desai 	return (NT_STATUS_SUCCESS);
127e3f2c991SKeyur Desai }
128e3f2c991SKeyur Desai 
129e3f2c991SKeyur Desai /* ARGSUSED */
130e3f2c991SKeyur Desai static uint32_t
13189dc44ceSjose borrego smb_nt_trans_ioctl_invalid_parm(smb_request_t *sr, smb_xa_t *xa)
13289dc44ceSjose borrego {
13389dc44ceSjose borrego 	return (NT_STATUS_INVALID_PARAMETER);
13489dc44ceSjose borrego }
135*fd9ee8b5Sjoyce mcintosh 
136*fd9ee8b5Sjoyce mcintosh /*
137*fd9ee8b5Sjoyce mcintosh  * smb_nt_trans_ioctl_set_sparse
138*fd9ee8b5Sjoyce mcintosh  *
139*fd9ee8b5Sjoyce mcintosh  * There may, or may not be a data block in this request.
140*fd9ee8b5Sjoyce mcintosh  * If there IS a data block, the first byte is a boolean
141*fd9ee8b5Sjoyce mcintosh  * specifying whether to set (non zero) or clear (zero)
142*fd9ee8b5Sjoyce mcintosh  * the sparse attribute of the file.
143*fd9ee8b5Sjoyce mcintosh  * If there is no data block, this indicates a request to
144*fd9ee8b5Sjoyce mcintosh  * set the sparse attribute.
145*fd9ee8b5Sjoyce mcintosh  */
146*fd9ee8b5Sjoyce mcintosh static uint32_t
147*fd9ee8b5Sjoyce mcintosh smb_nt_trans_ioctl_set_sparse(smb_request_t *sr, smb_xa_t *xa)
148*fd9ee8b5Sjoyce mcintosh {
149*fd9ee8b5Sjoyce mcintosh 	int		rc = 0;
150*fd9ee8b5Sjoyce mcintosh 	uint8_t		set = 1;
151*fd9ee8b5Sjoyce mcintosh 	smb_node_t	*node;
152*fd9ee8b5Sjoyce mcintosh 	smb_attr_t	attr;
153*fd9ee8b5Sjoyce mcintosh 
154*fd9ee8b5Sjoyce mcintosh 	if (SMB_TREE_IS_READONLY(sr))
155*fd9ee8b5Sjoyce mcintosh 		return (NT_STATUS_ACCESS_DENIED);
156*fd9ee8b5Sjoyce mcintosh 
157*fd9ee8b5Sjoyce mcintosh 	if (STYPE_ISIPC(sr->tid_tree->t_res_type))
158*fd9ee8b5Sjoyce mcintosh 		return (NT_STATUS_INVALID_PARAMETER);
159*fd9ee8b5Sjoyce mcintosh 
160*fd9ee8b5Sjoyce mcintosh 	smbsr_lookup_file(sr);
161*fd9ee8b5Sjoyce mcintosh 	if (sr->fid_ofile == NULL)
162*fd9ee8b5Sjoyce mcintosh 		return (NT_STATUS_INVALID_HANDLE);
163*fd9ee8b5Sjoyce mcintosh 
164*fd9ee8b5Sjoyce mcintosh 	if (!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) {
165*fd9ee8b5Sjoyce mcintosh 		smbsr_release_file(sr);
166*fd9ee8b5Sjoyce mcintosh 		return (NT_STATUS_INVALID_PARAMETER);
167*fd9ee8b5Sjoyce mcintosh 	}
168*fd9ee8b5Sjoyce mcintosh 
169*fd9ee8b5Sjoyce mcintosh 	node = sr->fid_ofile->f_node;
170*fd9ee8b5Sjoyce mcintosh 	if (smb_node_is_dir(node)) {
171*fd9ee8b5Sjoyce mcintosh 		smbsr_release_file(sr);
172*fd9ee8b5Sjoyce mcintosh 		return (NT_STATUS_INVALID_PARAMETER);
173*fd9ee8b5Sjoyce mcintosh 	}
174*fd9ee8b5Sjoyce mcintosh 
175*fd9ee8b5Sjoyce mcintosh 	if (smbsr_decode_data_avail(sr)) {
176*fd9ee8b5Sjoyce mcintosh 		if (smb_mbc_decodef(&xa->req_data_mb, "b", &set) != 0) {
177*fd9ee8b5Sjoyce mcintosh 			smbsr_release_file(sr);
178*fd9ee8b5Sjoyce mcintosh 			return (sr->smb_error.status);
179*fd9ee8b5Sjoyce mcintosh 		}
180*fd9ee8b5Sjoyce mcintosh 	}
181*fd9ee8b5Sjoyce mcintosh 
182*fd9ee8b5Sjoyce mcintosh 	bzero(&attr, sizeof (smb_attr_t));
183*fd9ee8b5Sjoyce mcintosh 	attr.sa_mask = SMB_AT_DOSATTR;
184*fd9ee8b5Sjoyce mcintosh 	if ((rc = smb_node_getattr(sr, node, &attr)) != 0) {
185*fd9ee8b5Sjoyce mcintosh 		smbsr_errno(sr, rc);
186*fd9ee8b5Sjoyce mcintosh 		smbsr_release_file(sr);
187*fd9ee8b5Sjoyce mcintosh 		return (sr->smb_error.status);
188*fd9ee8b5Sjoyce mcintosh 	}
189*fd9ee8b5Sjoyce mcintosh 
190*fd9ee8b5Sjoyce mcintosh 	attr.sa_mask = 0;
191*fd9ee8b5Sjoyce mcintosh 	if ((set == 0) &&
192*fd9ee8b5Sjoyce mcintosh 	    (attr.sa_dosattr & FILE_ATTRIBUTE_SPARSE_FILE)) {
193*fd9ee8b5Sjoyce mcintosh 		attr.sa_dosattr &= ~FILE_ATTRIBUTE_SPARSE_FILE;
194*fd9ee8b5Sjoyce mcintosh 		attr.sa_mask = SMB_AT_DOSATTR;
195*fd9ee8b5Sjoyce mcintosh 	} else if ((set != 0) &&
196*fd9ee8b5Sjoyce mcintosh 	    !(attr.sa_dosattr & FILE_ATTRIBUTE_SPARSE_FILE)) {
197*fd9ee8b5Sjoyce mcintosh 		attr.sa_dosattr |= FILE_ATTRIBUTE_SPARSE_FILE;
198*fd9ee8b5Sjoyce mcintosh 		attr.sa_mask = SMB_AT_DOSATTR;
199*fd9ee8b5Sjoyce mcintosh 	}
200*fd9ee8b5Sjoyce mcintosh 
201*fd9ee8b5Sjoyce mcintosh 	if (attr.sa_mask != 0) {
202*fd9ee8b5Sjoyce mcintosh 		rc = smb_node_setattr(sr, node, sr->user_cr, NULL, &attr);
203*fd9ee8b5Sjoyce mcintosh 		if (rc != 0) {
204*fd9ee8b5Sjoyce mcintosh 			smbsr_errno(sr, rc);
205*fd9ee8b5Sjoyce mcintosh 			smbsr_release_file(sr);
206*fd9ee8b5Sjoyce mcintosh 			return (sr->smb_error.status);
207*fd9ee8b5Sjoyce mcintosh 		}
208*fd9ee8b5Sjoyce mcintosh 	}
209*fd9ee8b5Sjoyce mcintosh 
210*fd9ee8b5Sjoyce mcintosh 	smbsr_release_file(sr);
211*fd9ee8b5Sjoyce mcintosh 	return (NT_STATUS_SUCCESS);
212*fd9ee8b5Sjoyce mcintosh }
213*fd9ee8b5Sjoyce mcintosh 
214*fd9ee8b5Sjoyce mcintosh /*
215*fd9ee8b5Sjoyce mcintosh  * smb_nt_trans_ioctl_set_zero_data
216*fd9ee8b5Sjoyce mcintosh  *
217*fd9ee8b5Sjoyce mcintosh  * Check that the request is valid on the specified file.
218*fd9ee8b5Sjoyce mcintosh  * The implementation is a noop.
219*fd9ee8b5Sjoyce mcintosh  */
220*fd9ee8b5Sjoyce mcintosh /* ARGSUSED */
221*fd9ee8b5Sjoyce mcintosh static uint32_t
222*fd9ee8b5Sjoyce mcintosh smb_nt_trans_ioctl_set_zero_data(smb_request_t *sr, smb_xa_t *xa)
223*fd9ee8b5Sjoyce mcintosh {
224*fd9ee8b5Sjoyce mcintosh 	smb_node_t *node;
225*fd9ee8b5Sjoyce mcintosh 
226*fd9ee8b5Sjoyce mcintosh 	if (SMB_TREE_IS_READONLY(sr))
227*fd9ee8b5Sjoyce mcintosh 		return (NT_STATUS_ACCESS_DENIED);
228*fd9ee8b5Sjoyce mcintosh 
229*fd9ee8b5Sjoyce mcintosh 	if (STYPE_ISIPC(sr->tid_tree->t_res_type))
230*fd9ee8b5Sjoyce mcintosh 		return (NT_STATUS_INVALID_PARAMETER);
231*fd9ee8b5Sjoyce mcintosh 
232*fd9ee8b5Sjoyce mcintosh 	smbsr_lookup_file(sr);
233*fd9ee8b5Sjoyce mcintosh 	if (sr->fid_ofile == NULL)
234*fd9ee8b5Sjoyce mcintosh 		return (NT_STATUS_INVALID_HANDLE);
235*fd9ee8b5Sjoyce mcintosh 
236*fd9ee8b5Sjoyce mcintosh 	if (!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) {
237*fd9ee8b5Sjoyce mcintosh 		smbsr_release_file(sr);
238*fd9ee8b5Sjoyce mcintosh 		return (NT_STATUS_INVALID_PARAMETER);
239*fd9ee8b5Sjoyce mcintosh 	}
240*fd9ee8b5Sjoyce mcintosh 
241*fd9ee8b5Sjoyce mcintosh 	node = sr->fid_ofile->f_node;
242*fd9ee8b5Sjoyce mcintosh 	if (smb_node_is_dir(node)) {
243*fd9ee8b5Sjoyce mcintosh 		smbsr_release_file(sr);
244*fd9ee8b5Sjoyce mcintosh 		return (NT_STATUS_INVALID_PARAMETER);
245*fd9ee8b5Sjoyce mcintosh 	}
246*fd9ee8b5Sjoyce mcintosh 
247*fd9ee8b5Sjoyce mcintosh 	smbsr_release_file(sr);
248*fd9ee8b5Sjoyce mcintosh 	return (NT_STATUS_SUCCESS);
249*fd9ee8b5Sjoyce mcintosh }
250*fd9ee8b5Sjoyce mcintosh 
251*fd9ee8b5Sjoyce mcintosh /*
252*fd9ee8b5Sjoyce mcintosh  * smb_nt_trans_ioctl_query_alloc_ranges
253*fd9ee8b5Sjoyce mcintosh  *
254*fd9ee8b5Sjoyce mcintosh  * Responds with either:
255*fd9ee8b5Sjoyce mcintosh  * - no data if the file is zero size
256*fd9ee8b5Sjoyce mcintosh  * - a single range containing the starting point and length requested
257*fd9ee8b5Sjoyce mcintosh  */
258*fd9ee8b5Sjoyce mcintosh static uint32_t
259*fd9ee8b5Sjoyce mcintosh smb_nt_trans_ioctl_query_alloc_ranges(smb_request_t *sr, smb_xa_t *xa)
260*fd9ee8b5Sjoyce mcintosh {
261*fd9ee8b5Sjoyce mcintosh 	int		rc;
262*fd9ee8b5Sjoyce mcintosh 	uint64_t	offset, len;
263*fd9ee8b5Sjoyce mcintosh 	smb_node_t	*node;
264*fd9ee8b5Sjoyce mcintosh 	smb_attr_t	attr;
265*fd9ee8b5Sjoyce mcintosh 
266*fd9ee8b5Sjoyce mcintosh 	if (STYPE_ISIPC(sr->tid_tree->t_res_type))
267*fd9ee8b5Sjoyce mcintosh 		return (NT_STATUS_INVALID_PARAMETER);
268*fd9ee8b5Sjoyce mcintosh 
269*fd9ee8b5Sjoyce mcintosh 	smbsr_lookup_file(sr);
270*fd9ee8b5Sjoyce mcintosh 	if (sr->fid_ofile == NULL)
271*fd9ee8b5Sjoyce mcintosh 		return (NT_STATUS_INVALID_HANDLE);
272*fd9ee8b5Sjoyce mcintosh 
273*fd9ee8b5Sjoyce mcintosh 	if (!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) {
274*fd9ee8b5Sjoyce mcintosh 		smbsr_release_file(sr);
275*fd9ee8b5Sjoyce mcintosh 		return (NT_STATUS_INVALID_PARAMETER);
276*fd9ee8b5Sjoyce mcintosh 	}
277*fd9ee8b5Sjoyce mcintosh 
278*fd9ee8b5Sjoyce mcintosh 	node = sr->fid_ofile->f_node;
279*fd9ee8b5Sjoyce mcintosh 	if (smb_node_is_dir(node)) {
280*fd9ee8b5Sjoyce mcintosh 		smbsr_release_file(sr);
281*fd9ee8b5Sjoyce mcintosh 		return (NT_STATUS_INVALID_PARAMETER);
282*fd9ee8b5Sjoyce mcintosh 	}
283*fd9ee8b5Sjoyce mcintosh 
284*fd9ee8b5Sjoyce mcintosh 	/* If zero size file don't return any data */
285*fd9ee8b5Sjoyce mcintosh 	bzero(&attr, sizeof (smb_attr_t));
286*fd9ee8b5Sjoyce mcintosh 	attr.sa_mask = SMB_AT_SIZE;
287*fd9ee8b5Sjoyce mcintosh 	if ((rc = smb_node_getattr(sr, node, &attr)) != 0) {
288*fd9ee8b5Sjoyce mcintosh 		smbsr_errno(sr, rc);
289*fd9ee8b5Sjoyce mcintosh 		smbsr_release_file(sr);
290*fd9ee8b5Sjoyce mcintosh 		return (sr->smb_error.status);
291*fd9ee8b5Sjoyce mcintosh 	}
292*fd9ee8b5Sjoyce mcintosh 
293*fd9ee8b5Sjoyce mcintosh 	if (attr.sa_vattr.va_size == 0) {
294*fd9ee8b5Sjoyce mcintosh 		smbsr_release_file(sr);
295*fd9ee8b5Sjoyce mcintosh 		return (NT_STATUS_SUCCESS);
296*fd9ee8b5Sjoyce mcintosh 	}
297*fd9ee8b5Sjoyce mcintosh 
298*fd9ee8b5Sjoyce mcintosh 	if (smb_mbc_decodef(&xa->req_data_mb, "qq", &offset, &len) != 0) {
299*fd9ee8b5Sjoyce mcintosh 		smbsr_release_file(sr);
300*fd9ee8b5Sjoyce mcintosh 		return (sr->smb_error.status);
301*fd9ee8b5Sjoyce mcintosh 	}
302*fd9ee8b5Sjoyce mcintosh 
303*fd9ee8b5Sjoyce mcintosh 	/*
304*fd9ee8b5Sjoyce mcintosh 	 * Return a single range regardless of whether the file
305*fd9ee8b5Sjoyce mcintosh 	 * is sparse or not.
306*fd9ee8b5Sjoyce mcintosh 	 */
307*fd9ee8b5Sjoyce mcintosh 	if (MBC_ROOM_FOR(&xa->rep_data_mb, 16) == 0) {
308*fd9ee8b5Sjoyce mcintosh 		smbsr_release_file(sr);
309*fd9ee8b5Sjoyce mcintosh 		return (NT_STATUS_BUFFER_TOO_SMALL);
310*fd9ee8b5Sjoyce mcintosh 	}
311*fd9ee8b5Sjoyce mcintosh 
312*fd9ee8b5Sjoyce mcintosh 	if (smb_mbc_encodef(&xa->rep_data_mb, "qq", offset, len) != 0) {
313*fd9ee8b5Sjoyce mcintosh 		smbsr_release_file(sr);
314*fd9ee8b5Sjoyce mcintosh 		return (sr->smb_error.status);
315*fd9ee8b5Sjoyce mcintosh 	}
316*fd9ee8b5Sjoyce mcintosh 
317*fd9ee8b5Sjoyce mcintosh 	smbsr_release_file(sr);
318*fd9ee8b5Sjoyce mcintosh 	return (NT_STATUS_SUCCESS);
319*fd9ee8b5Sjoyce mcintosh }
320