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 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_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; 235 236 if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) 237 conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL; 238 } 239 240 /** 241 * init_smb3_02_server() - initialize a smb server connection with smb3.02 242 * command dispatcher 243 * @conn: connection instance 244 */ 245 void init_smb3_02_server(struct ksmbd_conn *conn) 246 { 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; 252 253 if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) 254 conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING | 255 SMB2_GLOBAL_CAP_DIRECTORY_LEASING; 256 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; 261 262 if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) 263 conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL; 264 265 if (server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE) 266 conn->vals->capabilities |= SMB2_GLOBAL_CAP_PERSISTENT_HANDLES; 267 } 268 269 /** 270 * init_smb3_11_server() - initialize a smb server connection with smb3.11 271 * command dispatcher 272 * @conn: connection instance 273 */ 274 int init_smb3_11_server(struct ksmbd_conn *conn) 275 { 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; 281 282 if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) 283 conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING | 284 SMB2_GLOBAL_CAP_DIRECTORY_LEASING; 285 286 if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) 287 conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL; 288 289 if (server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE) 290 conn->vals->capabilities |= SMB2_GLOBAL_CAP_PERSISTENT_HANDLES; 291 292 INIT_LIST_HEAD(&conn->preauth_sess_table); 293 return 0; 294 } 295 296 void init_smb2_max_read_size(unsigned int sz) 297 { 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; 303 } 304 305 void init_smb2_max_write_size(unsigned int sz) 306 { 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; 312 } 313 314 void init_smb2_max_trans_size(unsigned int sz) 315 { 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; 321 } 322 323 void init_smb2_max_credits(unsigned int sz) 324 { 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; 329 } 330
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.