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.
23adee6784SGordon Ross * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
24da6c28aaSamw */
25da6c28aaSamw
26bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h>
27adee6784SGordon Ross #include <smb/winioctl.h>
28da6c28aaSamw
29e3f2c991SKeyur Desai
30e3f2c991SKeyur Desai static uint32_t smb_nt_trans_ioctl_noop(smb_request_t *, smb_xa_t *);
31fd9ee8b5Sjoyce mcintosh static uint32_t smb_nt_trans_ioctl_invalid_parm(smb_request_t *, smb_xa_t *);
32fd9ee8b5Sjoyce mcintosh static uint32_t smb_nt_trans_ioctl_set_sparse(smb_request_t *, smb_xa_t *);
33fd9ee8b5Sjoyce mcintosh static uint32_t smb_nt_trans_ioctl_query_alloc_ranges(smb_request_t *,
3489dc44ceSjose borrego smb_xa_t *);
35fd9ee8b5Sjoyce mcintosh static uint32_t smb_nt_trans_ioctl_set_zero_data(smb_request_t *, smb_xa_t *);
36a90cf9f2SGordon Ross static uint32_t smb_nt_trans_ioctl_enum_snaps(smb_request_t *, smb_xa_t *);
37da6c28aaSamw
38da6c28aaSamw /*
39e3f2c991SKeyur Desai * This table defines the list of FSCTL values for which we'll
40e3f2c991SKeyur Desai * call a funtion to perform specific processing.
41da6c28aaSamw */
428622ec45SGordon Ross static const struct {
43da6c28aaSamw uint32_t fcode;
4489dc44ceSjose borrego uint32_t (*ioctl_func)(smb_request_t *sr, smb_xa_t *xa);
45da6c28aaSamw } ioctl_ret_tbl[] = {
46e3f2c991SKeyur Desai { FSCTL_GET_OBJECT_ID, smb_nt_trans_ioctl_invalid_parm },
47fd9ee8b5Sjoyce mcintosh { FSCTL_QUERY_ALLOCATED_RANGES, smb_nt_trans_ioctl_query_alloc_ranges },
48fd9ee8b5Sjoyce mcintosh { FSCTL_SET_ZERO_DATA, smb_nt_trans_ioctl_set_zero_data },
49a90cf9f2SGordon Ross { FSCTL_SRV_ENUMERATE_SNAPSHOTS, smb_nt_trans_ioctl_enum_snaps },
50fd9ee8b5Sjoyce mcintosh { FSCTL_SET_SPARSE, smb_nt_trans_ioctl_set_sparse },
519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { FSCTL_FIND_FILES_BY_SID, smb_nt_trans_ioctl_noop }
52da6c28aaSamw };
53da6c28aaSamw
54da6c28aaSamw /*
55da6c28aaSamw * smb_nt_transact_ioctl
56da6c28aaSamw *
57da6c28aaSamw * This command allows device and file system control functions to be
58e3f2c991SKeyur Desai * transferred transparently from client to server.
59da6c28aaSamw *
60da6c28aaSamw * Setup Words Encoding Description
61da6c28aaSamw * =========================== =========================================
62da6c28aaSamw * ULONG FunctionCode; NT device or file system control code
63da6c28aaSamw * USHORT Fid; Handle for io or fs control. Unless BIT0
64da6c28aaSamw * of ISFLAGS is set.
65da6c28aaSamw * BOOLEAN IsFsctl; Indicates whether the command is a device
66da6c28aaSamw * control (FALSE) or a file system control
67da6c28aaSamw * (TRUE).
68da6c28aaSamw * UCHAR IsFlags; BIT0 - command is to be applied to share
69da6c28aaSamw * root handle. Share must be a DFS share.
70da6c28aaSamw *
71da6c28aaSamw * Data Block Encoding Description
72da6c28aaSamw * =========================== =========================================
73da6c28aaSamw * Data[ TotalDataCount ] Passed to the Fsctl or Ioctl
74da6c28aaSamw *
75da6c28aaSamw * Server Response Description
76da6c28aaSamw * =========================== ==================================
77da6c28aaSamw * SetupCount 1
78da6c28aaSamw * Setup[0] Length of information returned by
79da6c28aaSamw * io or fs control.
80da6c28aaSamw * DataCount Length of information returned by
81da6c28aaSamw * io or fs control.
82da6c28aaSamw * Data[ DataCount ] The results of the io or fs control.
83da6c28aaSamw */
847b59d02dSjb smb_sdrc_t
smb_nt_transact_ioctl(smb_request_t * sr,smb_xa_t * xa)8589dc44ceSjose borrego smb_nt_transact_ioctl(smb_request_t *sr, smb_xa_t *xa)
86da6c28aaSamw {
87e3f2c991SKeyur Desai uint32_t status = NT_STATUS_NOT_SUPPORTED;
88da6c28aaSamw uint32_t fcode;
89da6c28aaSamw unsigned char is_fsctl;
90da6c28aaSamw unsigned char is_flags;
91da6c28aaSamw int i;
92da6c28aaSamw
933db3f65cSamw if (smb_mbc_decodef(&xa->req_setup_mb, "lwbb",
94fd9ee8b5Sjoyce mcintosh &fcode, &sr->smb_fid, &is_fsctl, &is_flags) != 0) {
95dc20a302Sas smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
96faa1795aSjb return (SDRC_ERROR);
97da6c28aaSamw }
98da6c28aaSamw
99e3f2c991SKeyur Desai /*
100e3f2c991SKeyur Desai * Invoke handler if specified, otherwise the default
101e3f2c991SKeyur Desai * behavior is to return NT_STATUS_NOT_SUPPORTED
102e3f2c991SKeyur Desai */
1037b59d02dSjb for (i = 0; i < sizeof (ioctl_ret_tbl) / sizeof (ioctl_ret_tbl[0]);
104da6c28aaSamw i++) {
105da6c28aaSamw if (ioctl_ret_tbl[i].fcode == fcode) {
10689dc44ceSjose borrego status = ioctl_ret_tbl[i].ioctl_func(sr, xa);
107da6c28aaSamw break;
108da6c28aaSamw }
109da6c28aaSamw }
110da6c28aaSamw
1117b59d02dSjb if (status != NT_STATUS_SUCCESS) {
112dc20a302Sas smbsr_error(sr, status, 0, 0);
113faa1795aSjb return (SDRC_ERROR);
1147b59d02dSjb }
115da6c28aaSamw
1163db3f65cSamw (void) smb_mbc_encodef(&xa->rep_param_mb, "l", 0);
117faa1795aSjb return (SDRC_SUCCESS);
118da6c28aaSamw }
11989dc44ceSjose borrego
120e3f2c991SKeyur Desai /* ARGSUSED */
121e3f2c991SKeyur Desai static uint32_t
smb_nt_trans_ioctl_noop(smb_request_t * sr,smb_xa_t * xa)122e3f2c991SKeyur Desai smb_nt_trans_ioctl_noop(smb_request_t *sr, smb_xa_t *xa)
123e3f2c991SKeyur Desai {
124e3f2c991SKeyur Desai return (NT_STATUS_SUCCESS);
125e3f2c991SKeyur Desai }
126e3f2c991SKeyur Desai
12789dc44ceSjose borrego /* ARGSUSED */
12889dc44ceSjose borrego static uint32_t
smb_nt_trans_ioctl_invalid_parm(smb_request_t * sr,smb_xa_t * xa)12989dc44ceSjose borrego smb_nt_trans_ioctl_invalid_parm(smb_request_t *sr, smb_xa_t *xa)
13089dc44ceSjose borrego {
13189dc44ceSjose borrego return (NT_STATUS_INVALID_PARAMETER);
13289dc44ceSjose borrego }
133fd9ee8b5Sjoyce mcintosh
134fd9ee8b5Sjoyce mcintosh /*
135fd9ee8b5Sjoyce mcintosh * smb_nt_trans_ioctl_set_sparse
136fd9ee8b5Sjoyce mcintosh *
137fd9ee8b5Sjoyce mcintosh * There may, or may not be a data block in this request.
138fd9ee8b5Sjoyce mcintosh * If there IS a data block, the first byte is a boolean
139fd9ee8b5Sjoyce mcintosh * specifying whether to set (non zero) or clear (zero)
140fd9ee8b5Sjoyce mcintosh * the sparse attribute of the file.
141fd9ee8b5Sjoyce mcintosh * If there is no data block, this indicates a request to
142fd9ee8b5Sjoyce mcintosh * set the sparse attribute.
143fd9ee8b5Sjoyce mcintosh */
144fd9ee8b5Sjoyce mcintosh static uint32_t
smb_nt_trans_ioctl_set_sparse(smb_request_t * sr,smb_xa_t * xa)145fd9ee8b5Sjoyce mcintosh smb_nt_trans_ioctl_set_sparse(smb_request_t *sr, smb_xa_t *xa)
146fd9ee8b5Sjoyce mcintosh {
147fd9ee8b5Sjoyce mcintosh int rc = 0;
148fd9ee8b5Sjoyce mcintosh uint8_t set = 1;
1495fd03bc0SGordon Ross smb_ofile_t *of;
150fd9ee8b5Sjoyce mcintosh smb_attr_t attr;
151fd9ee8b5Sjoyce mcintosh
152fd9ee8b5Sjoyce mcintosh if (SMB_TREE_IS_READONLY(sr))
153fd9ee8b5Sjoyce mcintosh return (NT_STATUS_ACCESS_DENIED);
154fd9ee8b5Sjoyce mcintosh
155fd9ee8b5Sjoyce mcintosh if (STYPE_ISIPC(sr->tid_tree->t_res_type))
156fd9ee8b5Sjoyce mcintosh return (NT_STATUS_INVALID_PARAMETER);
157fd9ee8b5Sjoyce mcintosh
158fd9ee8b5Sjoyce mcintosh smbsr_lookup_file(sr);
159fd9ee8b5Sjoyce mcintosh if (sr->fid_ofile == NULL)
160fd9ee8b5Sjoyce mcintosh return (NT_STATUS_INVALID_HANDLE);
161fd9ee8b5Sjoyce mcintosh
162fd9ee8b5Sjoyce mcintosh if (!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) {
163fd9ee8b5Sjoyce mcintosh smbsr_release_file(sr);
164fd9ee8b5Sjoyce mcintosh return (NT_STATUS_INVALID_PARAMETER);
165fd9ee8b5Sjoyce mcintosh }
166fd9ee8b5Sjoyce mcintosh
1675fd03bc0SGordon Ross of = sr->fid_ofile;
1685fd03bc0SGordon Ross if (smb_node_is_dir(of->f_node)) {
169fd9ee8b5Sjoyce mcintosh smbsr_release_file(sr);
170fd9ee8b5Sjoyce mcintosh return (NT_STATUS_INVALID_PARAMETER);
171fd9ee8b5Sjoyce mcintosh }
172fd9ee8b5Sjoyce mcintosh
173fd9ee8b5Sjoyce mcintosh if (smbsr_decode_data_avail(sr)) {
174fd9ee8b5Sjoyce mcintosh if (smb_mbc_decodef(&xa->req_data_mb, "b", &set) != 0) {
175fd9ee8b5Sjoyce mcintosh smbsr_release_file(sr);
176fd9ee8b5Sjoyce mcintosh return (sr->smb_error.status);
177fd9ee8b5Sjoyce mcintosh }
178fd9ee8b5Sjoyce mcintosh }
179fd9ee8b5Sjoyce mcintosh
1805fd03bc0SGordon Ross /*
1815fd03bc0SGordon Ross * Using kcred because we just want the DOS attrs
1825fd03bc0SGordon Ross * and don't want access errors for this.
1835fd03bc0SGordon Ross */
184fd9ee8b5Sjoyce mcintosh bzero(&attr, sizeof (smb_attr_t));
185fd9ee8b5Sjoyce mcintosh attr.sa_mask = SMB_AT_DOSATTR;
1868622ec45SGordon Ross rc = smb_node_getattr(sr, of->f_node, zone_kcred(), of, &attr);
1875fd03bc0SGordon Ross if (rc != 0) {
188fd9ee8b5Sjoyce mcintosh smbsr_errno(sr, rc);
189fd9ee8b5Sjoyce mcintosh smbsr_release_file(sr);
190fd9ee8b5Sjoyce mcintosh return (sr->smb_error.status);
191fd9ee8b5Sjoyce mcintosh }
192fd9ee8b5Sjoyce mcintosh
193fd9ee8b5Sjoyce mcintosh attr.sa_mask = 0;
194fd9ee8b5Sjoyce mcintosh if ((set == 0) &&
195fd9ee8b5Sjoyce mcintosh (attr.sa_dosattr & FILE_ATTRIBUTE_SPARSE_FILE)) {
196fd9ee8b5Sjoyce mcintosh attr.sa_dosattr &= ~FILE_ATTRIBUTE_SPARSE_FILE;
197fd9ee8b5Sjoyce mcintosh attr.sa_mask = SMB_AT_DOSATTR;
198fd9ee8b5Sjoyce mcintosh } else if ((set != 0) &&
199fd9ee8b5Sjoyce mcintosh !(attr.sa_dosattr & FILE_ATTRIBUTE_SPARSE_FILE)) {
200fd9ee8b5Sjoyce mcintosh attr.sa_dosattr |= FILE_ATTRIBUTE_SPARSE_FILE;
201fd9ee8b5Sjoyce mcintosh attr.sa_mask = SMB_AT_DOSATTR;
202fd9ee8b5Sjoyce mcintosh }
203fd9ee8b5Sjoyce mcintosh
204fd9ee8b5Sjoyce mcintosh if (attr.sa_mask != 0) {
2055fd03bc0SGordon Ross rc = smb_node_setattr(sr, of->f_node, of->f_cr, of, &attr);
206fd9ee8b5Sjoyce mcintosh if (rc != 0) {
207fd9ee8b5Sjoyce mcintosh smbsr_errno(sr, rc);
208fd9ee8b5Sjoyce mcintosh smbsr_release_file(sr);
209fd9ee8b5Sjoyce mcintosh return (sr->smb_error.status);
210fd9ee8b5Sjoyce mcintosh }
211fd9ee8b5Sjoyce mcintosh }
212fd9ee8b5Sjoyce mcintosh
213fd9ee8b5Sjoyce mcintosh smbsr_release_file(sr);
214fd9ee8b5Sjoyce mcintosh return (NT_STATUS_SUCCESS);
215fd9ee8b5Sjoyce mcintosh }
216fd9ee8b5Sjoyce mcintosh
217fd9ee8b5Sjoyce mcintosh /*
218fd9ee8b5Sjoyce mcintosh * smb_nt_trans_ioctl_set_zero_data
219fd9ee8b5Sjoyce mcintosh *
220fd9ee8b5Sjoyce mcintosh * Check that the request is valid on the specified file.
221*94047d49SGordon Ross * The implementation is a noop. XXX - bug!
222*94047d49SGordon Ross * XXX: We have this in the fsclt module now. Call that.
223*94047d49SGordon Ross *
224*94047d49SGordon Ross * Note: When support is added for FSCTL_SET_ZERO_DATA, it must
225*94047d49SGordon Ross * break any oplocks on the file to none:
226*94047d49SGordon Ross * (void) smb_oplock_break_WRITE(node, ofile);
227fd9ee8b5Sjoyce mcintosh */
228fd9ee8b5Sjoyce mcintosh /* ARGSUSED */
229fd9ee8b5Sjoyce mcintosh static uint32_t
smb_nt_trans_ioctl_set_zero_data(smb_request_t * sr,smb_xa_t * xa)230fd9ee8b5Sjoyce mcintosh smb_nt_trans_ioctl_set_zero_data(smb_request_t *sr, smb_xa_t *xa)
231fd9ee8b5Sjoyce mcintosh {
232fd9ee8b5Sjoyce mcintosh smb_node_t *node;
233fd9ee8b5Sjoyce mcintosh
234fd9ee8b5Sjoyce mcintosh if (SMB_TREE_IS_READONLY(sr))
235fd9ee8b5Sjoyce mcintosh return (NT_STATUS_ACCESS_DENIED);
236fd9ee8b5Sjoyce mcintosh
237fd9ee8b5Sjoyce mcintosh if (STYPE_ISIPC(sr->tid_tree->t_res_type))
238fd9ee8b5Sjoyce mcintosh return (NT_STATUS_INVALID_PARAMETER);
239fd9ee8b5Sjoyce mcintosh
240fd9ee8b5Sjoyce mcintosh smbsr_lookup_file(sr);
241fd9ee8b5Sjoyce mcintosh if (sr->fid_ofile == NULL)
242fd9ee8b5Sjoyce mcintosh return (NT_STATUS_INVALID_HANDLE);
243fd9ee8b5Sjoyce mcintosh
244fd9ee8b5Sjoyce mcintosh if (!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) {
245fd9ee8b5Sjoyce mcintosh smbsr_release_file(sr);
246fd9ee8b5Sjoyce mcintosh return (NT_STATUS_INVALID_PARAMETER);
247fd9ee8b5Sjoyce mcintosh }
248fd9ee8b5Sjoyce mcintosh
249fd9ee8b5Sjoyce mcintosh node = sr->fid_ofile->f_node;
250fd9ee8b5Sjoyce mcintosh if (smb_node_is_dir(node)) {
251fd9ee8b5Sjoyce mcintosh smbsr_release_file(sr);
252fd9ee8b5Sjoyce mcintosh return (NT_STATUS_INVALID_PARAMETER);
253fd9ee8b5Sjoyce mcintosh }
254fd9ee8b5Sjoyce mcintosh
255fd9ee8b5Sjoyce mcintosh smbsr_release_file(sr);
256fd9ee8b5Sjoyce mcintosh return (NT_STATUS_SUCCESS);
257fd9ee8b5Sjoyce mcintosh }
258fd9ee8b5Sjoyce mcintosh
259fd9ee8b5Sjoyce mcintosh /*
260fd9ee8b5Sjoyce mcintosh * smb_nt_trans_ioctl_query_alloc_ranges
261fd9ee8b5Sjoyce mcintosh *
262fd9ee8b5Sjoyce mcintosh * Responds with either:
263fd9ee8b5Sjoyce mcintosh * - no data if the file is zero size
264fd9ee8b5Sjoyce mcintosh * - a single range containing the starting point and length requested
265fd9ee8b5Sjoyce mcintosh */
266fd9ee8b5Sjoyce mcintosh static uint32_t
smb_nt_trans_ioctl_query_alloc_ranges(smb_request_t * sr,smb_xa_t * xa)267fd9ee8b5Sjoyce mcintosh smb_nt_trans_ioctl_query_alloc_ranges(smb_request_t *sr, smb_xa_t *xa)
268fd9ee8b5Sjoyce mcintosh {
269fd9ee8b5Sjoyce mcintosh int rc;
270fd9ee8b5Sjoyce mcintosh uint64_t offset, len;
2715fd03bc0SGordon Ross smb_ofile_t *of;
272fd9ee8b5Sjoyce mcintosh smb_attr_t attr;
273fd9ee8b5Sjoyce mcintosh
274fd9ee8b5Sjoyce mcintosh if (STYPE_ISIPC(sr->tid_tree->t_res_type))
275fd9ee8b5Sjoyce mcintosh return (NT_STATUS_INVALID_PARAMETER);
276fd9ee8b5Sjoyce mcintosh
277fd9ee8b5Sjoyce mcintosh smbsr_lookup_file(sr);
278fd9ee8b5Sjoyce mcintosh if (sr->fid_ofile == NULL)
279fd9ee8b5Sjoyce mcintosh return (NT_STATUS_INVALID_HANDLE);
280fd9ee8b5Sjoyce mcintosh
281fd9ee8b5Sjoyce mcintosh if (!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) {
282fd9ee8b5Sjoyce mcintosh smbsr_release_file(sr);
283fd9ee8b5Sjoyce mcintosh return (NT_STATUS_INVALID_PARAMETER);
284fd9ee8b5Sjoyce mcintosh }
285fd9ee8b5Sjoyce mcintosh
2865fd03bc0SGordon Ross of = sr->fid_ofile;
2875fd03bc0SGordon Ross if (smb_node_is_dir(of->f_node)) {
288fd9ee8b5Sjoyce mcintosh smbsr_release_file(sr);
289fd9ee8b5Sjoyce mcintosh return (NT_STATUS_INVALID_PARAMETER);
290fd9ee8b5Sjoyce mcintosh }
291fd9ee8b5Sjoyce mcintosh
292fd9ee8b5Sjoyce mcintosh /* If zero size file don't return any data */
293fd9ee8b5Sjoyce mcintosh bzero(&attr, sizeof (smb_attr_t));
294fd9ee8b5Sjoyce mcintosh attr.sa_mask = SMB_AT_SIZE;
2955fd03bc0SGordon Ross rc = smb_node_getattr(sr, of->f_node, of->f_cr, of, &attr);
2965fd03bc0SGordon Ross if (rc != 0) {
297fd9ee8b5Sjoyce mcintosh smbsr_errno(sr, rc);
298fd9ee8b5Sjoyce mcintosh smbsr_release_file(sr);
299fd9ee8b5Sjoyce mcintosh return (sr->smb_error.status);
300fd9ee8b5Sjoyce mcintosh }
301fd9ee8b5Sjoyce mcintosh
302fd9ee8b5Sjoyce mcintosh if (attr.sa_vattr.va_size == 0) {
303fd9ee8b5Sjoyce mcintosh smbsr_release_file(sr);
304fd9ee8b5Sjoyce mcintosh return (NT_STATUS_SUCCESS);
305fd9ee8b5Sjoyce mcintosh }
306fd9ee8b5Sjoyce mcintosh
307fd9ee8b5Sjoyce mcintosh if (smb_mbc_decodef(&xa->req_data_mb, "qq", &offset, &len) != 0) {
308fd9ee8b5Sjoyce mcintosh smbsr_release_file(sr);
309fd9ee8b5Sjoyce mcintosh return (sr->smb_error.status);
310fd9ee8b5Sjoyce mcintosh }
311fd9ee8b5Sjoyce mcintosh
312fd9ee8b5Sjoyce mcintosh /*
313fd9ee8b5Sjoyce mcintosh * Return a single range regardless of whether the file
314fd9ee8b5Sjoyce mcintosh * is sparse or not.
315fd9ee8b5Sjoyce mcintosh */
316fd9ee8b5Sjoyce mcintosh if (MBC_ROOM_FOR(&xa->rep_data_mb, 16) == 0) {
317fd9ee8b5Sjoyce mcintosh smbsr_release_file(sr);
318fd9ee8b5Sjoyce mcintosh return (NT_STATUS_BUFFER_TOO_SMALL);
319fd9ee8b5Sjoyce mcintosh }
320fd9ee8b5Sjoyce mcintosh
321fd9ee8b5Sjoyce mcintosh if (smb_mbc_encodef(&xa->rep_data_mb, "qq", offset, len) != 0) {
322fd9ee8b5Sjoyce mcintosh smbsr_release_file(sr);
323fd9ee8b5Sjoyce mcintosh return (sr->smb_error.status);
324fd9ee8b5Sjoyce mcintosh }
325fd9ee8b5Sjoyce mcintosh
326fd9ee8b5Sjoyce mcintosh smbsr_release_file(sr);
327fd9ee8b5Sjoyce mcintosh return (NT_STATUS_SUCCESS);
328fd9ee8b5Sjoyce mcintosh }
329a90cf9f2SGordon Ross
330a90cf9f2SGordon Ross static uint32_t
smb_nt_trans_ioctl_enum_snaps(smb_request_t * sr,smb_xa_t * xa)331a90cf9f2SGordon Ross smb_nt_trans_ioctl_enum_snaps(smb_request_t *sr, smb_xa_t *xa)
332a90cf9f2SGordon Ross {
333a90cf9f2SGordon Ross smb_fsctl_t fsctl;
334a90cf9f2SGordon Ross uint32_t status;
335a90cf9f2SGordon Ross
336a90cf9f2SGordon Ross if (STYPE_ISIPC(sr->tid_tree->t_res_type))
337a90cf9f2SGordon Ross return (NT_STATUS_INVALID_PARAMETER);
338a90cf9f2SGordon Ross
339a90cf9f2SGordon Ross smbsr_lookup_file(sr);
340a90cf9f2SGordon Ross if (sr->fid_ofile == NULL)
341a90cf9f2SGordon Ross return (NT_STATUS_INVALID_HANDLE);
342a90cf9f2SGordon Ross
343a90cf9f2SGordon Ross if (!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) {
344a90cf9f2SGordon Ross smbsr_release_file(sr);
345a90cf9f2SGordon Ross return (NT_STATUS_INVALID_PARAMETER);
346a90cf9f2SGordon Ross }
347a90cf9f2SGordon Ross
348a90cf9f2SGordon Ross fsctl.CtlCode = FSCTL_SRV_ENUMERATE_SNAPSHOTS;
349a90cf9f2SGordon Ross fsctl.InputCount = xa->smb_tpscnt;
350a90cf9f2SGordon Ross fsctl.OutputCount = 0;
351a90cf9f2SGordon Ross fsctl.MaxOutputResp = xa->smb_mdrcnt;
352a90cf9f2SGordon Ross fsctl.in_mbc = &xa->req_param_mb;
353a90cf9f2SGordon Ross fsctl.out_mbc = &xa->rep_data_mb;
354a90cf9f2SGordon Ross
355a90cf9f2SGordon Ross status = smb_vss_enum_snapshots(sr, &fsctl);
356a90cf9f2SGordon Ross
357a90cf9f2SGordon Ross smbsr_release_file(sr);
358a90cf9f2SGordon Ross return (status);
359a90cf9f2SGordon Ross }
360