xref: /onnv-gate/usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c (revision 12890:16985853e3aa)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23  */
24 
25 #include <smbsrv/smb_kproto.h>
26 #include <smbsrv/winioctl.h>
27 
28 
29 static uint32_t smb_nt_trans_ioctl_noop(smb_request_t *, smb_xa_t *);
30 static uint32_t smb_nt_trans_ioctl_invalid_parm(smb_request_t *,
31     smb_xa_t *);
32 
33 /*
34  * This table defines the list of FSCTL values for which we'll
35  * call a funtion to perform specific processing.
36  *
37  * Note: If support is added for FSCTL_SET_ZERO_DATA, it must break
38  * any oplocks on the file to none:
39  *   smb_oplock_break(sr, node, SMB_OPLOCK_BREAK_TO_NONE);
40  */
41 static struct {
42 	uint32_t fcode;
43 	uint32_t (*ioctl_func)(smb_request_t *sr, smb_xa_t *xa);
44 } ioctl_ret_tbl[] = {
45 	{ FSCTL_GET_OBJECT_ID, smb_nt_trans_ioctl_invalid_parm },
46 	{ FSCTL_QUERY_ALLOCATED_RANGES, smb_nt_trans_ioctl_invalid_parm },
47 	{ FSCTL_SRV_ENUMERATE_SNAPSHOTS, smb_vss_ioctl_enumerate_snaps },
48 	{ FSCTL_SET_SPARSE, smb_nt_trans_ioctl_noop },
49 	{ FSCTL_FIND_FILES_BY_SID, smb_nt_trans_ioctl_noop }
50 };
51 
52 /*
53  * smb_nt_transact_ioctl
54  *
55  * This command allows device and file system control functions to be
56  * transferred transparently from client to server.
57  *
58  * Setup Words Encoding        Description
59  * =========================== =========================================
60  * ULONG FunctionCode;         NT device or file system control code
61  * USHORT Fid;                 Handle for io or fs control. Unless BIT0
62  *                             of ISFLAGS is set.
63  * BOOLEAN IsFsctl;            Indicates whether the command is a device
64  *                             control (FALSE) or a file system control
65  *                             (TRUE).
66  * UCHAR   IsFlags;            BIT0 - command is to be applied to share
67  *                             root handle. Share must be a DFS share.
68  *
69  * Data Block Encoding         Description
70  * =========================== =========================================
71  * Data[ TotalDataCount ]      Passed to the Fsctl or Ioctl
72  *
73  * Server Response             Description
74  * =========================== ==================================
75  * SetupCount                  1
76  * Setup[0]                    Length of information returned by
77  *                             io or fs control.
78  * DataCount                   Length of information returned by
79  *                             io or fs control.
80  * Data[ DataCount ]           The results of the io or fs control.
81  */
82 smb_sdrc_t
83 smb_nt_transact_ioctl(smb_request_t *sr, smb_xa_t *xa)
84 {
85 	uint32_t status = NT_STATUS_NOT_SUPPORTED;
86 	uint32_t fcode;
87 	unsigned short fid;
88 	unsigned char is_fsctl;
89 	unsigned char is_flags;
90 	int i;
91 
92 	if (smb_mbc_decodef(&xa->req_setup_mb, "lwbb",
93 	    &fcode, &fid, &is_fsctl, &is_flags) != 0) {
94 		smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
95 		return (SDRC_ERROR);
96 	}
97 
98 	/*
99 	 * Invoke handler if specified, otherwise the default
100 	 * behavior is to return NT_STATUS_NOT_SUPPORTED
101 	 */
102 	for (i = 0; i < sizeof (ioctl_ret_tbl) / sizeof (ioctl_ret_tbl[0]);
103 	    i++) {
104 		if (ioctl_ret_tbl[i].fcode == fcode) {
105 			status = ioctl_ret_tbl[i].ioctl_func(sr, xa);
106 			break;
107 		}
108 	}
109 
110 	if (status != NT_STATUS_SUCCESS) {
111 		smbsr_error(sr, status, 0, 0);
112 		return (SDRC_ERROR);
113 	}
114 
115 	(void) smb_mbc_encodef(&xa->rep_param_mb, "l", 0);
116 	return (SDRC_SUCCESS);
117 }
118 
119 /* ARGSUSED */
120 static uint32_t
121 smb_nt_trans_ioctl_noop(smb_request_t *sr, smb_xa_t *xa)
122 {
123 	return (NT_STATUS_SUCCESS);
124 }
125 
126 /* ARGSUSED */
127 static uint32_t
128 smb_nt_trans_ioctl_invalid_parm(smb_request_t *sr, smb_xa_t *xa)
129 {
130 	return (NT_STATUS_INVALID_PARAMETER);
131 }
132