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