| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- // SPDX-License-Identifier: GPL-2.0-or-later
- /*
- * Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org>
- * Copyright (C) 2018 Samsung Electronics Co., Ltd.
- */
- #include <linux/slab.h>
- #include "glob.h"
- #include "auth.h"
- #include "connection.h"
- #include "smb_common.h"
- #include "server.h"
- static struct smb_version_values smb21_server_values = {
- .version_string = SMB21_VERSION_STRING,
- .protocol_id = SMB21_PROT_ID,
- .capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
- .max_read_size = SMB21_DEFAULT_IOSIZE,
- .max_write_size = SMB21_DEFAULT_IOSIZE,
- .max_trans_size = SMB21_DEFAULT_IOSIZE,
- .max_credits = SMB2_MAX_CREDITS,
- .large_lock_type = 0,
- .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE,
- .shared_lock_type = SMB2_LOCKFLAG_SHARED,
- .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
- .header_size = sizeof(struct smb2_hdr),
- .max_header_size = MAX_SMB2_HDR_SIZE,
- .read_rsp_size = sizeof(struct smb2_read_rsp),
- .lock_cmd = SMB2_LOCK,
- .cap_unix = 0,
- .cap_nt_find = SMB2_NT_FIND,
- .cap_large_files = SMB2_LARGE_FILES,
- .create_lease_size = sizeof(struct create_lease),
- .create_durable_size = sizeof(struct create_durable_rsp),
- .create_mxac_size = sizeof(struct create_mxac_rsp),
- .create_disk_id_size = sizeof(struct create_disk_id_rsp),
- .create_posix_size = sizeof(struct create_posix_rsp),
- };
- static struct smb_version_values smb30_server_values = {
- .version_string = SMB30_VERSION_STRING,
- .protocol_id = SMB30_PROT_ID,
- .capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
- .max_read_size = SMB3_DEFAULT_IOSIZE,
- .max_write_size = SMB3_DEFAULT_IOSIZE,
- .max_trans_size = SMB3_DEFAULT_TRANS_SIZE,
- .max_credits = SMB2_MAX_CREDITS,
- .large_lock_type = 0,
- .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE,
- .shared_lock_type = SMB2_LOCKFLAG_SHARED,
- .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
- .header_size = sizeof(struct smb2_hdr),
- .max_header_size = MAX_SMB2_HDR_SIZE,
- .read_rsp_size = sizeof(struct smb2_read_rsp),
- .lock_cmd = SMB2_LOCK,
- .cap_unix = 0,
- .cap_nt_find = SMB2_NT_FIND,
- .cap_large_files = SMB2_LARGE_FILES,
- .create_lease_size = sizeof(struct create_lease_v2),
- .create_durable_size = sizeof(struct create_durable_rsp),
- .create_durable_v2_size = sizeof(struct create_durable_v2_rsp),
- .create_mxac_size = sizeof(struct create_mxac_rsp),
- .create_disk_id_size = sizeof(struct create_disk_id_rsp),
- .create_posix_size = sizeof(struct create_posix_rsp),
- };
- static struct smb_version_values smb302_server_values = {
- .version_string = SMB302_VERSION_STRING,
- .protocol_id = SMB302_PROT_ID,
- .capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
- .max_read_size = SMB3_DEFAULT_IOSIZE,
- .max_write_size = SMB3_DEFAULT_IOSIZE,
- .max_trans_size = SMB3_DEFAULT_TRANS_SIZE,
- .max_credits = SMB2_MAX_CREDITS,
- .large_lock_type = 0,
- .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE,
- .shared_lock_type = SMB2_LOCKFLAG_SHARED,
- .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
- .header_size = sizeof(struct smb2_hdr),
- .max_header_size = MAX_SMB2_HDR_SIZE,
- .read_rsp_size = sizeof(struct smb2_read_rsp),
- .lock_cmd = SMB2_LOCK,
- .cap_unix = 0,
- .cap_nt_find = SMB2_NT_FIND,
- .cap_large_files = SMB2_LARGE_FILES,
- .create_lease_size = sizeof(struct create_lease_v2),
- .create_durable_size = sizeof(struct create_durable_rsp),
- .create_durable_v2_size = sizeof(struct create_durable_v2_rsp),
- .create_mxac_size = sizeof(struct create_mxac_rsp),
- .create_disk_id_size = sizeof(struct create_disk_id_rsp),
- .create_posix_size = sizeof(struct create_posix_rsp),
- };
- static struct smb_version_values smb311_server_values = {
- .version_string = SMB311_VERSION_STRING,
- .protocol_id = SMB311_PROT_ID,
- .capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
- .max_read_size = SMB3_DEFAULT_IOSIZE,
- .max_write_size = SMB3_DEFAULT_IOSIZE,
- .max_trans_size = SMB3_DEFAULT_TRANS_SIZE,
- .max_credits = SMB2_MAX_CREDITS,
- .large_lock_type = 0,
- .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE,
- .shared_lock_type = SMB2_LOCKFLAG_SHARED,
- .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
- .header_size = sizeof(struct smb2_hdr),
- .max_header_size = MAX_SMB2_HDR_SIZE,
- .read_rsp_size = sizeof(struct smb2_read_rsp),
- .lock_cmd = SMB2_LOCK,
- .cap_unix = 0,
- .cap_nt_find = SMB2_NT_FIND,
- .cap_large_files = SMB2_LARGE_FILES,
- .create_lease_size = sizeof(struct create_lease_v2),
- .create_durable_size = sizeof(struct create_durable_rsp),
- .create_durable_v2_size = sizeof(struct create_durable_v2_rsp),
- .create_mxac_size = sizeof(struct create_mxac_rsp),
- .create_disk_id_size = sizeof(struct create_disk_id_rsp),
- .create_posix_size = sizeof(struct create_posix_rsp),
- };
- static struct smb_version_ops smb2_0_server_ops = {
- .get_cmd_val = get_smb2_cmd_val,
- .init_rsp_hdr = init_smb2_rsp_hdr,
- .set_rsp_status = set_smb2_rsp_status,
- .allocate_rsp_buf = smb2_allocate_rsp_buf,
- .set_rsp_credits = smb2_set_rsp_credits,
- .check_user_session = smb2_check_user_session,
- .get_ksmbd_tcon = smb2_get_ksmbd_tcon,
- .is_sign_req = smb2_is_sign_req,
- .check_sign_req = smb2_check_sign_req,
- .set_sign_rsp = smb2_set_sign_rsp
- };
- static struct smb_version_ops smb3_0_server_ops = {
- .get_cmd_val = get_smb2_cmd_val,
- .init_rsp_hdr = init_smb2_rsp_hdr,
- .set_rsp_status = set_smb2_rsp_status,
- .allocate_rsp_buf = smb2_allocate_rsp_buf,
- .set_rsp_credits = smb2_set_rsp_credits,
- .check_user_session = smb2_check_user_session,
- .get_ksmbd_tcon = smb2_get_ksmbd_tcon,
- .is_sign_req = smb2_is_sign_req,
- .check_sign_req = smb3_check_sign_req,
- .set_sign_rsp = smb3_set_sign_rsp,
- .generate_signingkey = ksmbd_gen_smb30_signingkey,
- .generate_encryptionkey = ksmbd_gen_smb30_encryptionkey,
- .is_transform_hdr = smb3_is_transform_hdr,
- .decrypt_req = smb3_decrypt_req,
- .encrypt_resp = smb3_encrypt_resp
- };
- static struct smb_version_ops smb3_11_server_ops = {
- .get_cmd_val = get_smb2_cmd_val,
- .init_rsp_hdr = init_smb2_rsp_hdr,
- .set_rsp_status = set_smb2_rsp_status,
- .allocate_rsp_buf = smb2_allocate_rsp_buf,
- .set_rsp_credits = smb2_set_rsp_credits,
- .check_user_session = smb2_check_user_session,
- .get_ksmbd_tcon = smb2_get_ksmbd_tcon,
- .is_sign_req = smb2_is_sign_req,
- .check_sign_req = smb3_check_sign_req,
- .set_sign_rsp = smb3_set_sign_rsp,
- .generate_signingkey = ksmbd_gen_smb311_signingkey,
- .generate_encryptionkey = ksmbd_gen_smb311_encryptionkey,
- .is_transform_hdr = smb3_is_transform_hdr,
- .decrypt_req = smb3_decrypt_req,
- .encrypt_resp = smb3_encrypt_resp
- };
- static struct smb_version_cmds smb2_0_server_cmds[NUMBER_OF_SMB2_COMMANDS] = {
- [SMB2_NEGOTIATE_HE] = { .proc = smb2_negotiate_request, },
- [SMB2_SESSION_SETUP_HE] = { .proc = smb2_sess_setup, },
- [SMB2_TREE_CONNECT_HE] = { .proc = smb2_tree_connect,},
- [SMB2_TREE_DISCONNECT_HE] = { .proc = smb2_tree_disconnect,},
- [SMB2_LOGOFF_HE] = { .proc = smb2_session_logoff,},
- [SMB2_CREATE_HE] = { .proc = smb2_open},
- [SMB2_QUERY_INFO_HE] = { .proc = smb2_query_info},
- [SMB2_QUERY_DIRECTORY_HE] = { .proc = smb2_query_dir},
- [SMB2_CLOSE_HE] = { .proc = smb2_close},
- [SMB2_ECHO_HE] = { .proc = smb2_echo},
- [SMB2_SET_INFO_HE] = { .proc = smb2_set_info},
- [SMB2_READ_HE] = { .proc = smb2_read},
- [SMB2_WRITE_HE] = { .proc = smb2_write},
- [SMB2_FLUSH_HE] = { .proc = smb2_flush},
- [SMB2_CANCEL_HE] = { .proc = smb2_cancel},
- [SMB2_LOCK_HE] = { .proc = smb2_lock},
- [SMB2_IOCTL_HE] = { .proc = smb2_ioctl},
- [SMB2_OPLOCK_BREAK_HE] = { .proc = smb2_oplock_break},
- [SMB2_CHANGE_NOTIFY_HE] = { .proc = smb2_notify},
- };
- /**
- * init_smb2_1_server() - initialize a smb server connection with smb2.1
- * command dispatcher
- * @conn: connection instance
- */
- void init_smb2_1_server(struct ksmbd_conn *conn)
- {
- conn->vals = &smb21_server_values;
- conn->ops = &smb2_0_server_ops;
- conn->cmds = smb2_0_server_cmds;
- conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds);
- conn->signing_algorithm = SIGNING_ALG_HMAC_SHA256_LE;
- if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING;
- }
- /**
- * init_smb3_0_server() - initialize a smb server connection with smb3.0
- * command dispatcher
- * @conn: connection instance
- */
- void init_smb3_0_server(struct ksmbd_conn *conn)
- {
- conn->vals = &smb30_server_values;
- conn->ops = &smb3_0_server_ops;
- conn->cmds = smb2_0_server_cmds;
- conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds);
- conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
- if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING |
- SMB2_GLOBAL_CAP_DIRECTORY_LEASING;
- if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION &&
- conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
- if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION ||
- (!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF) &&
- conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION))
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
- if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
- }
- /**
- * init_smb3_02_server() - initialize a smb server connection with smb3.02
- * command dispatcher
- * @conn: connection instance
- */
- void init_smb3_02_server(struct ksmbd_conn *conn)
- {
- conn->vals = &smb302_server_values;
- conn->ops = &smb3_0_server_ops;
- conn->cmds = smb2_0_server_cmds;
- conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds);
- conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
- if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING |
- SMB2_GLOBAL_CAP_DIRECTORY_LEASING;
- if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION ||
- (!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF) &&
- conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION))
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
- if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
- if (server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_PERSISTENT_HANDLES;
- }
- /**
- * init_smb3_11_server() - initialize a smb server connection with smb3.11
- * command dispatcher
- * @conn: connection instance
- */
- int init_smb3_11_server(struct ksmbd_conn *conn)
- {
- conn->vals = &smb311_server_values;
- conn->ops = &smb3_11_server_ops;
- conn->cmds = smb2_0_server_cmds;
- conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds);
- conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
- if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING |
- SMB2_GLOBAL_CAP_DIRECTORY_LEASING;
- if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
- if (server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE)
- conn->vals->capabilities |= SMB2_GLOBAL_CAP_PERSISTENT_HANDLES;
- INIT_LIST_HEAD(&conn->preauth_sess_table);
- return 0;
- }
- void init_smb2_max_read_size(unsigned int sz)
- {
- sz = clamp_val(sz, SMB3_MIN_IOSIZE, SMB3_MAX_IOSIZE);
- smb21_server_values.max_read_size = sz;
- smb30_server_values.max_read_size = sz;
- smb302_server_values.max_read_size = sz;
- smb311_server_values.max_read_size = sz;
- }
- void init_smb2_max_write_size(unsigned int sz)
- {
- sz = clamp_val(sz, SMB3_MIN_IOSIZE, SMB3_MAX_IOSIZE);
- smb21_server_values.max_write_size = sz;
- smb30_server_values.max_write_size = sz;
- smb302_server_values.max_write_size = sz;
- smb311_server_values.max_write_size = sz;
- }
- void init_smb2_max_trans_size(unsigned int sz)
- {
- sz = clamp_val(sz, SMB3_MIN_IOSIZE, SMB3_MAX_IOSIZE);
- smb21_server_values.max_trans_size = sz;
- smb30_server_values.max_trans_size = sz;
- smb302_server_values.max_trans_size = sz;
- smb311_server_values.max_trans_size = sz;
- }
- void init_smb2_max_credits(unsigned int sz)
- {
- smb21_server_values.max_credits = sz;
- smb30_server_values.max_credits = sz;
- smb302_server_values.max_credits = sz;
- smb311_server_values.max_credits = sz;
- }
|