smb2ops.c (11266B)
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 15static 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) - 1, 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 41static 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) - 1, 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 68static 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) - 1, 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 95static 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) - 1, 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 122static 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 135static 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 153static 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 171static 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 */ 198void 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 */ 215void 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 */ 239void 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 conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION) 252 conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION; 253 254 if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) 255 conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL; 256} 257 258/** 259 * init_smb3_11_server() - initialize a smb server connection with smb3.11 260 * command dispatcher 261 * @conn: connection instance 262 */ 263int init_smb3_11_server(struct ksmbd_conn *conn) 264{ 265 conn->vals = &smb311_server_values; 266 conn->ops = &smb3_11_server_ops; 267 conn->cmds = smb2_0_server_cmds; 268 conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds); 269 conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE; 270 271 if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) 272 conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING; 273 274 if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) 275 conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL; 276 277 INIT_LIST_HEAD(&conn->preauth_sess_table); 278 return 0; 279} 280 281void init_smb2_max_read_size(unsigned int sz) 282{ 283 sz = clamp_val(sz, SMB3_MIN_IOSIZE, SMB3_MAX_IOSIZE); 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 290void init_smb2_max_write_size(unsigned int sz) 291{ 292 sz = clamp_val(sz, SMB3_MIN_IOSIZE, SMB3_MAX_IOSIZE); 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 299void init_smb2_max_trans_size(unsigned int sz) 300{ 301 sz = clamp_val(sz, SMB3_MIN_IOSIZE, SMB3_MAX_IOSIZE); 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} 307 308void init_smb2_max_credits(unsigned int sz) 309{ 310 smb21_server_values.max_credits = sz; 311 smb30_server_values.max_credits = sz; 312 smb302_server_values.max_credits = sz; 313 smb311_server_values.max_credits = sz; 314}