xref: /openbmc/linux/fs/smb/server/smb2ops.c (revision 6db6b729)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *   Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org>
4  *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
5  */
6 
7 #include <linux/slab.h>
8 #include "glob.h"
9 
10 #include "auth.h"
11 #include "connection.h"
12 #include "smb_common.h"
13 #include "server.h"
14 
15 static struct smb_version_values smb21_server_values = {
16 	.version_string = SMB21_VERSION_STRING,
17 	.protocol_id = SMB21_PROT_ID,
18 	.capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
19 	.max_read_size = SMB21_DEFAULT_IOSIZE,
20 	.max_write_size = SMB21_DEFAULT_IOSIZE,
21 	.max_trans_size = SMB21_DEFAULT_IOSIZE,
22 	.max_credits = SMB2_MAX_CREDITS,
23 	.large_lock_type = 0,
24 	.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE,
25 	.shared_lock_type = SMB2_LOCKFLAG_SHARED,
26 	.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
27 	.header_size = sizeof(struct smb2_hdr),
28 	.max_header_size = MAX_SMB2_HDR_SIZE,
29 	.read_rsp_size = sizeof(struct smb2_read_rsp),
30 	.lock_cmd = SMB2_LOCK,
31 	.cap_unix = 0,
32 	.cap_nt_find = SMB2_NT_FIND,
33 	.cap_large_files = SMB2_LARGE_FILES,
34 	.create_lease_size = sizeof(struct create_lease),
35 	.create_durable_size = sizeof(struct create_durable_rsp),
36 	.create_mxac_size = sizeof(struct create_mxac_rsp),
37 	.create_disk_id_size = sizeof(struct create_disk_id_rsp),
38 	.create_posix_size = sizeof(struct create_posix_rsp),
39 };
40 
41 static struct smb_version_values smb30_server_values = {
42 	.version_string = SMB30_VERSION_STRING,
43 	.protocol_id = SMB30_PROT_ID,
44 	.capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
45 	.max_read_size = SMB3_DEFAULT_IOSIZE,
46 	.max_write_size = SMB3_DEFAULT_IOSIZE,
47 	.max_trans_size = SMB3_DEFAULT_TRANS_SIZE,
48 	.max_credits = SMB2_MAX_CREDITS,
49 	.large_lock_type = 0,
50 	.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE,
51 	.shared_lock_type = SMB2_LOCKFLAG_SHARED,
52 	.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
53 	.header_size = sizeof(struct smb2_hdr),
54 	.max_header_size = MAX_SMB2_HDR_SIZE,
55 	.read_rsp_size = sizeof(struct smb2_read_rsp),
56 	.lock_cmd = SMB2_LOCK,
57 	.cap_unix = 0,
58 	.cap_nt_find = SMB2_NT_FIND,
59 	.cap_large_files = SMB2_LARGE_FILES,
60 	.create_lease_size = sizeof(struct create_lease_v2),
61 	.create_durable_size = sizeof(struct create_durable_rsp),
62 	.create_durable_v2_size = sizeof(struct create_durable_v2_rsp),
63 	.create_mxac_size = sizeof(struct create_mxac_rsp),
64 	.create_disk_id_size = sizeof(struct create_disk_id_rsp),
65 	.create_posix_size = sizeof(struct create_posix_rsp),
66 };
67 
68 static struct smb_version_values smb302_server_values = {
69 	.version_string = SMB302_VERSION_STRING,
70 	.protocol_id = SMB302_PROT_ID,
71 	.capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
72 	.max_read_size = SMB3_DEFAULT_IOSIZE,
73 	.max_write_size = SMB3_DEFAULT_IOSIZE,
74 	.max_trans_size = SMB3_DEFAULT_TRANS_SIZE,
75 	.max_credits = SMB2_MAX_CREDITS,
76 	.large_lock_type = 0,
77 	.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE,
78 	.shared_lock_type = SMB2_LOCKFLAG_SHARED,
79 	.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
80 	.header_size = sizeof(struct smb2_hdr),
81 	.max_header_size = MAX_SMB2_HDR_SIZE,
82 	.read_rsp_size = sizeof(struct smb2_read_rsp),
83 	.lock_cmd = SMB2_LOCK,
84 	.cap_unix = 0,
85 	.cap_nt_find = SMB2_NT_FIND,
86 	.cap_large_files = SMB2_LARGE_FILES,
87 	.create_lease_size = sizeof(struct create_lease_v2),
88 	.create_durable_size = sizeof(struct create_durable_rsp),
89 	.create_durable_v2_size = sizeof(struct create_durable_v2_rsp),
90 	.create_mxac_size = sizeof(struct create_mxac_rsp),
91 	.create_disk_id_size = sizeof(struct create_disk_id_rsp),
92 	.create_posix_size = sizeof(struct create_posix_rsp),
93 };
94 
95 static struct smb_version_values smb311_server_values = {
96 	.version_string = SMB311_VERSION_STRING,
97 	.protocol_id = SMB311_PROT_ID,
98 	.capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
99 	.max_read_size = SMB3_DEFAULT_IOSIZE,
100 	.max_write_size = SMB3_DEFAULT_IOSIZE,
101 	.max_trans_size = SMB3_DEFAULT_TRANS_SIZE,
102 	.max_credits = SMB2_MAX_CREDITS,
103 	.large_lock_type = 0,
104 	.exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE,
105 	.shared_lock_type = SMB2_LOCKFLAG_SHARED,
106 	.unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
107 	.header_size = sizeof(struct smb2_hdr),
108 	.max_header_size = MAX_SMB2_HDR_SIZE,
109 	.read_rsp_size = sizeof(struct smb2_read_rsp),
110 	.lock_cmd = SMB2_LOCK,
111 	.cap_unix = 0,
112 	.cap_nt_find = SMB2_NT_FIND,
113 	.cap_large_files = SMB2_LARGE_FILES,
114 	.create_lease_size = sizeof(struct create_lease_v2),
115 	.create_durable_size = sizeof(struct create_durable_rsp),
116 	.create_durable_v2_size = sizeof(struct create_durable_v2_rsp),
117 	.create_mxac_size = sizeof(struct create_mxac_rsp),
118 	.create_disk_id_size = sizeof(struct create_disk_id_rsp),
119 	.create_posix_size = sizeof(struct create_posix_rsp),
120 };
121 
122 static struct smb_version_ops smb2_0_server_ops = {
123 	.get_cmd_val		=	get_smb2_cmd_val,
124 	.init_rsp_hdr		=	init_smb2_rsp_hdr,
125 	.set_rsp_status		=	set_smb2_rsp_status,
126 	.allocate_rsp_buf       =       smb2_allocate_rsp_buf,
127 	.set_rsp_credits	=	smb2_set_rsp_credits,
128 	.check_user_session	=	smb2_check_user_session,
129 	.get_ksmbd_tcon		=	smb2_get_ksmbd_tcon,
130 	.is_sign_req		=	smb2_is_sign_req,
131 	.check_sign_req		=	smb2_check_sign_req,
132 	.set_sign_rsp		=	smb2_set_sign_rsp
133 };
134 
135 static struct smb_version_ops smb3_0_server_ops = {
136 	.get_cmd_val		=	get_smb2_cmd_val,
137 	.init_rsp_hdr		=	init_smb2_rsp_hdr,
138 	.set_rsp_status		=	set_smb2_rsp_status,
139 	.allocate_rsp_buf       =       smb2_allocate_rsp_buf,
140 	.set_rsp_credits	=	smb2_set_rsp_credits,
141 	.check_user_session	=	smb2_check_user_session,
142 	.get_ksmbd_tcon		=	smb2_get_ksmbd_tcon,
143 	.is_sign_req		=	smb2_is_sign_req,
144 	.check_sign_req		=	smb3_check_sign_req,
145 	.set_sign_rsp		=	smb3_set_sign_rsp,
146 	.generate_signingkey	=	ksmbd_gen_smb30_signingkey,
147 	.generate_encryptionkey	=	ksmbd_gen_smb30_encryptionkey,
148 	.is_transform_hdr	=	smb3_is_transform_hdr,
149 	.decrypt_req		=	smb3_decrypt_req,
150 	.encrypt_resp		=	smb3_encrypt_resp
151 };
152 
153 static struct smb_version_ops smb3_11_server_ops = {
154 	.get_cmd_val		=	get_smb2_cmd_val,
155 	.init_rsp_hdr		=	init_smb2_rsp_hdr,
156 	.set_rsp_status		=	set_smb2_rsp_status,
157 	.allocate_rsp_buf       =       smb2_allocate_rsp_buf,
158 	.set_rsp_credits	=	smb2_set_rsp_credits,
159 	.check_user_session	=	smb2_check_user_session,
160 	.get_ksmbd_tcon		=	smb2_get_ksmbd_tcon,
161 	.is_sign_req		=	smb2_is_sign_req,
162 	.check_sign_req		=	smb3_check_sign_req,
163 	.set_sign_rsp		=	smb3_set_sign_rsp,
164 	.generate_signingkey	=	ksmbd_gen_smb311_signingkey,
165 	.generate_encryptionkey	=	ksmbd_gen_smb311_encryptionkey,
166 	.is_transform_hdr	=	smb3_is_transform_hdr,
167 	.decrypt_req		=	smb3_decrypt_req,
168 	.encrypt_resp		=	smb3_encrypt_resp
169 };
170 
171 static struct smb_version_cmds smb2_0_server_cmds[NUMBER_OF_SMB2_COMMANDS] = {
172 	[SMB2_NEGOTIATE_HE]	=	{ .proc = smb2_negotiate_request, },
173 	[SMB2_SESSION_SETUP_HE] =	{ .proc = smb2_sess_setup, },
174 	[SMB2_TREE_CONNECT_HE]  =	{ .proc = smb2_tree_connect,},
175 	[SMB2_TREE_DISCONNECT_HE]  =	{ .proc = smb2_tree_disconnect,},
176 	[SMB2_LOGOFF_HE]	=	{ .proc = smb2_session_logoff,},
177 	[SMB2_CREATE_HE]	=	{ .proc = smb2_open},
178 	[SMB2_QUERY_INFO_HE]	=	{ .proc = smb2_query_info},
179 	[SMB2_QUERY_DIRECTORY_HE] =	{ .proc = smb2_query_dir},
180 	[SMB2_CLOSE_HE]		=	{ .proc = smb2_close},
181 	[SMB2_ECHO_HE]		=	{ .proc = smb2_echo},
182 	[SMB2_SET_INFO_HE]      =       { .proc = smb2_set_info},
183 	[SMB2_READ_HE]		=	{ .proc = smb2_read},
184 	[SMB2_WRITE_HE]		=	{ .proc = smb2_write},
185 	[SMB2_FLUSH_HE]		=	{ .proc = smb2_flush},
186 	[SMB2_CANCEL_HE]	=	{ .proc = smb2_cancel},
187 	[SMB2_LOCK_HE]		=	{ .proc = smb2_lock},
188 	[SMB2_IOCTL_HE]		=	{ .proc = smb2_ioctl},
189 	[SMB2_OPLOCK_BREAK_HE]	=	{ .proc = smb2_oplock_break},
190 	[SMB2_CHANGE_NOTIFY_HE]	=	{ .proc = smb2_notify},
191 };
192 
193 /**
194  * init_smb2_1_server() - initialize a smb server connection with smb2.1
195  *			command dispatcher
196  * @conn:	connection instance
197  */
198 void init_smb2_1_server(struct ksmbd_conn *conn)
199 {
200 	conn->vals = &smb21_server_values;
201 	conn->ops = &smb2_0_server_ops;
202 	conn->cmds = smb2_0_server_cmds;
203 	conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds);
204 	conn->signing_algorithm = SIGNING_ALG_HMAC_SHA256_LE;
205 
206 	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
207 		conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING;
208 }
209 
210 /**
211  * init_smb3_0_server() - initialize a smb server connection with smb3.0
212  *			command dispatcher
213  * @conn:	connection instance
214  */
215 void init_smb3_0_server(struct ksmbd_conn *conn)
216 {
217 	conn->vals = &smb30_server_values;
218 	conn->ops = &smb3_0_server_ops;
219 	conn->cmds = smb2_0_server_cmds;
220 	conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds);
221 	conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
222 
223 	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
224 		conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING;
225 
226 	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION &&
227 	    conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION)
228 		conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
229 
230 	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
231 		conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
232 }
233 
234 /**
235  * init_smb3_02_server() - initialize a smb server connection with smb3.02
236  *			command dispatcher
237  * @conn:	connection instance
238  */
239 void init_smb3_02_server(struct ksmbd_conn *conn)
240 {
241 	conn->vals = &smb302_server_values;
242 	conn->ops = &smb3_0_server_ops;
243 	conn->cmds = smb2_0_server_cmds;
244 	conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds);
245 	conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
246 
247 	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
248 		conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING;
249 
250 	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION ||
251 	    (!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF) &&
252 	     conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION))
253 		conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
254 
255 	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
256 		conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
257 }
258 
259 /**
260  * init_smb3_11_server() - initialize a smb server connection with smb3.11
261  *			command dispatcher
262  * @conn:	connection instance
263  */
264 int init_smb3_11_server(struct ksmbd_conn *conn)
265 {
266 	conn->vals = &smb311_server_values;
267 	conn->ops = &smb3_11_server_ops;
268 	conn->cmds = smb2_0_server_cmds;
269 	conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds);
270 	conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
271 
272 	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
273 		conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING;
274 
275 	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION ||
276 	    (!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF) &&
277 	     conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION))
278 		conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
279 
280 	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
281 		conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
282 
283 	INIT_LIST_HEAD(&conn->preauth_sess_table);
284 	return 0;
285 }
286 
287 void init_smb2_max_read_size(unsigned int sz)
288 {
289 	sz = clamp_val(sz, SMB3_MIN_IOSIZE, SMB3_MAX_IOSIZE);
290 	smb21_server_values.max_read_size = sz;
291 	smb30_server_values.max_read_size = sz;
292 	smb302_server_values.max_read_size = sz;
293 	smb311_server_values.max_read_size = sz;
294 }
295 
296 void init_smb2_max_write_size(unsigned int sz)
297 {
298 	sz = clamp_val(sz, SMB3_MIN_IOSIZE, SMB3_MAX_IOSIZE);
299 	smb21_server_values.max_write_size = sz;
300 	smb30_server_values.max_write_size = sz;
301 	smb302_server_values.max_write_size = sz;
302 	smb311_server_values.max_write_size = sz;
303 }
304 
305 void init_smb2_max_trans_size(unsigned int sz)
306 {
307 	sz = clamp_val(sz, SMB3_MIN_IOSIZE, SMB3_MAX_IOSIZE);
308 	smb21_server_values.max_trans_size = sz;
309 	smb30_server_values.max_trans_size = sz;
310 	smb302_server_values.max_trans_size = sz;
311 	smb311_server_values.max_trans_size = sz;
312 }
313 
314 void init_smb2_max_credits(unsigned int sz)
315 {
316 	smb21_server_values.max_credits = sz;
317 	smb30_server_values.max_credits = sz;
318 	smb302_server_values.max_credits = sz;
319 	smb311_server_values.max_credits = sz;
320 }
321