Linux Audio

Check our new training course

Embedded Linux training

Mar 31-Apr 8, 2025
Register
Loading...
Note: File does not exist in v4.17.
  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
 15static 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
 41static 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
 68static 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
 95static 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
122static 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
135static 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
153static 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
171static 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 */
198void 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 */
215void 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			SMB2_GLOBAL_CAP_DIRECTORY_LEASING;
226
227	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION &&
228	    conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION)
229		conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
230
231	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
232		conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
233}
234
235/**
236 * init_smb3_02_server() - initialize a smb server connection with smb3.02
237 *			command dispatcher
238 * @conn:	connection instance
239 */
240void init_smb3_02_server(struct ksmbd_conn *conn)
241{
242	conn->vals = &smb302_server_values;
243	conn->ops = &smb3_0_server_ops;
244	conn->cmds = smb2_0_server_cmds;
245	conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds);
246	conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
247
248	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
249		conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING |
250			SMB2_GLOBAL_CAP_DIRECTORY_LEASING;
251
252	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION ||
253	    (!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF) &&
254	     conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION))
255		conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
256
257	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
258		conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
259}
260
261/**
262 * init_smb3_11_server() - initialize a smb server connection with smb3.11
263 *			command dispatcher
264 * @conn:	connection instance
265 */
266int init_smb3_11_server(struct ksmbd_conn *conn)
267{
268	conn->vals = &smb311_server_values;
269	conn->ops = &smb3_11_server_ops;
270	conn->cmds = smb2_0_server_cmds;
271	conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds);
272	conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
273
274	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
275		conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING |
276			SMB2_GLOBAL_CAP_DIRECTORY_LEASING;
277
278	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION ||
279	    (!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF) &&
280	     conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION))
281		conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
282
283	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
284		conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
285
286	INIT_LIST_HEAD(&conn->preauth_sess_table);
287	return 0;
288}
289
290void init_smb2_max_read_size(unsigned int sz)
291{
292	sz = clamp_val(sz, SMB3_MIN_IOSIZE, SMB3_MAX_IOSIZE);
293	smb21_server_values.max_read_size = sz;
294	smb30_server_values.max_read_size = sz;
295	smb302_server_values.max_read_size = sz;
296	smb311_server_values.max_read_size = sz;
297}
298
299void init_smb2_max_write_size(unsigned int sz)
300{
301	sz = clamp_val(sz, SMB3_MIN_IOSIZE, SMB3_MAX_IOSIZE);
302	smb21_server_values.max_write_size = sz;
303	smb30_server_values.max_write_size = sz;
304	smb302_server_values.max_write_size = sz;
305	smb311_server_values.max_write_size = sz;
306}
307
308void init_smb2_max_trans_size(unsigned int sz)
309{
310	sz = clamp_val(sz, SMB3_MIN_IOSIZE, SMB3_MAX_IOSIZE);
311	smb21_server_values.max_trans_size = sz;
312	smb30_server_values.max_trans_size = sz;
313	smb302_server_values.max_trans_size = sz;
314	smb311_server_values.max_trans_size = sz;
315}
316
317void init_smb2_max_credits(unsigned int sz)
318{
319	smb21_server_values.max_credits = sz;
320	smb30_server_values.max_credits = sz;
321	smb302_server_values.max_credits = sz;
322	smb311_server_values.max_credits = sz;
323}