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