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