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