1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org>
4 * Copyright (C) 2018 Samsung Electronics Co., Ltd.
7 #include <linux/slab.h>
11 #include "connection.h"
12 #include "smb_common.h"
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
,
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
,
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
),
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
,
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
,
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
),
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
,
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
,
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
),
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
,
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
),
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
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
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
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
},
194 * init_smb2_1_server() - initialize a smb server connection with smb2.1
196 * @conn: connection instance
198 void init_smb2_1_server(struct ksmbd_conn
*conn
)
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
;
206 if (server_conf
.flags
& KSMBD_GLOBAL_FLAG_SMB2_LEASES
)
207 conn
->vals
->capabilities
|= SMB2_GLOBAL_CAP_LEASING
;
211 * init_smb3_0_server() - initialize a smb server connection with smb3.0
213 * @conn: connection instance
215 void init_smb3_0_server(struct ksmbd_conn
*conn
)
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
;
223 if (server_conf
.flags
& KSMBD_GLOBAL_FLAG_SMB2_LEASES
)
224 conn
->vals
->capabilities
|= SMB2_GLOBAL_CAP_LEASING
|
225 SMB2_GLOBAL_CAP_DIRECTORY_LEASING
;
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
;
231 if (server_conf
.flags
& KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION
||
232 (!(server_conf
.flags
& KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF
) &&
233 conn
->cli_cap
& SMB2_GLOBAL_CAP_ENCRYPTION
))
234 conn
->vals
->capabilities
|= SMB2_GLOBAL_CAP_ENCRYPTION
;
236 if (server_conf
.flags
& KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL
)
237 conn
->vals
->capabilities
|= SMB2_GLOBAL_CAP_MULTI_CHANNEL
;
241 * init_smb3_02_server() - initialize a smb server connection with smb3.02
243 * @conn: connection instance
245 void init_smb3_02_server(struct ksmbd_conn
*conn
)
247 conn
->vals
= &smb302_server_values
;
248 conn
->ops
= &smb3_0_server_ops
;
249 conn
->cmds
= smb2_0_server_cmds
;
250 conn
->max_cmds
= ARRAY_SIZE(smb2_0_server_cmds
);
251 conn
->signing_algorithm
= SIGNING_ALG_AES_CMAC_LE
;
253 if (server_conf
.flags
& KSMBD_GLOBAL_FLAG_SMB2_LEASES
)
254 conn
->vals
->capabilities
|= SMB2_GLOBAL_CAP_LEASING
|
255 SMB2_GLOBAL_CAP_DIRECTORY_LEASING
;
257 if (server_conf
.flags
& KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION
||
258 (!(server_conf
.flags
& KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF
) &&
259 conn
->cli_cap
& SMB2_GLOBAL_CAP_ENCRYPTION
))
260 conn
->vals
->capabilities
|= SMB2_GLOBAL_CAP_ENCRYPTION
;
262 if (server_conf
.flags
& KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL
)
263 conn
->vals
->capabilities
|= SMB2_GLOBAL_CAP_MULTI_CHANNEL
;
265 if (server_conf
.flags
& KSMBD_GLOBAL_FLAG_DURABLE_HANDLE
)
266 conn
->vals
->capabilities
|= SMB2_GLOBAL_CAP_PERSISTENT_HANDLES
;
270 * init_smb3_11_server() - initialize a smb server connection with smb3.11
272 * @conn: connection instance
274 int init_smb3_11_server(struct ksmbd_conn
*conn
)
276 conn
->vals
= &smb311_server_values
;
277 conn
->ops
= &smb3_11_server_ops
;
278 conn
->cmds
= smb2_0_server_cmds
;
279 conn
->max_cmds
= ARRAY_SIZE(smb2_0_server_cmds
);
280 conn
->signing_algorithm
= SIGNING_ALG_AES_CMAC_LE
;
282 if (server_conf
.flags
& KSMBD_GLOBAL_FLAG_SMB2_LEASES
)
283 conn
->vals
->capabilities
|= SMB2_GLOBAL_CAP_LEASING
|
284 SMB2_GLOBAL_CAP_DIRECTORY_LEASING
;
286 if (server_conf
.flags
& KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL
)
287 conn
->vals
->capabilities
|= SMB2_GLOBAL_CAP_MULTI_CHANNEL
;
289 if (server_conf
.flags
& KSMBD_GLOBAL_FLAG_DURABLE_HANDLE
)
290 conn
->vals
->capabilities
|= SMB2_GLOBAL_CAP_PERSISTENT_HANDLES
;
292 INIT_LIST_HEAD(&conn
->preauth_sess_table
);
296 void init_smb2_max_read_size(unsigned int sz
)
298 sz
= clamp_val(sz
, SMB3_MIN_IOSIZE
, SMB3_MAX_IOSIZE
);
299 smb21_server_values
.max_read_size
= sz
;
300 smb30_server_values
.max_read_size
= sz
;
301 smb302_server_values
.max_read_size
= sz
;
302 smb311_server_values
.max_read_size
= sz
;
305 void init_smb2_max_write_size(unsigned int sz
)
307 sz
= clamp_val(sz
, SMB3_MIN_IOSIZE
, SMB3_MAX_IOSIZE
);
308 smb21_server_values
.max_write_size
= sz
;
309 smb30_server_values
.max_write_size
= sz
;
310 smb302_server_values
.max_write_size
= sz
;
311 smb311_server_values
.max_write_size
= sz
;
314 void init_smb2_max_trans_size(unsigned int sz
)
316 sz
= clamp_val(sz
, SMB3_MIN_IOSIZE
, SMB3_MAX_IOSIZE
);
317 smb21_server_values
.max_trans_size
= sz
;
318 smb30_server_values
.max_trans_size
= sz
;
319 smb302_server_values
.max_trans_size
= sz
;
320 smb311_server_values
.max_trans_size
= sz
;
323 void init_smb2_max_credits(unsigned int sz
)
325 smb21_server_values
.max_credits
= sz
;
326 smb30_server_values
.max_credits
= sz
;
327 smb302_server_values
.max_credits
= sz
;
328 smb311_server_values
.max_credits
= sz
;