0001
0002
0003
0004
0005
0006
0007 #include "glob.h"
0008 #include "oplock.h"
0009 #include "misc.h"
0010 #include <linux/sched/signal.h>
0011 #include <linux/workqueue.h>
0012 #include <linux/sysfs.h>
0013 #include <linux/module.h>
0014 #include <linux/moduleparam.h>
0015
0016 #include "server.h"
0017 #include "smb_common.h"
0018 #include "smbstatus.h"
0019 #include "connection.h"
0020 #include "transport_ipc.h"
0021 #include "mgmt/user_session.h"
0022 #include "crypto_ctx.h"
0023 #include "auth.h"
0024
0025 int ksmbd_debug_types;
0026
0027 struct ksmbd_server_config server_conf;
0028
0029 enum SERVER_CTRL_TYPE {
0030 SERVER_CTRL_TYPE_INIT,
0031 SERVER_CTRL_TYPE_RESET,
0032 };
0033
0034 struct server_ctrl_struct {
0035 int type;
0036 struct work_struct ctrl_work;
0037 };
0038
0039 static DEFINE_MUTEX(ctrl_lock);
0040
0041 static int ___server_conf_set(int idx, char *val)
0042 {
0043 if (idx >= ARRAY_SIZE(server_conf.conf))
0044 return -EINVAL;
0045
0046 if (!val || val[0] == 0x00)
0047 return -EINVAL;
0048
0049 kfree(server_conf.conf[idx]);
0050 server_conf.conf[idx] = kstrdup(val, GFP_KERNEL);
0051 if (!server_conf.conf[idx])
0052 return -ENOMEM;
0053 return 0;
0054 }
0055
0056 int ksmbd_set_netbios_name(char *v)
0057 {
0058 return ___server_conf_set(SERVER_CONF_NETBIOS_NAME, v);
0059 }
0060
0061 int ksmbd_set_server_string(char *v)
0062 {
0063 return ___server_conf_set(SERVER_CONF_SERVER_STRING, v);
0064 }
0065
0066 int ksmbd_set_work_group(char *v)
0067 {
0068 return ___server_conf_set(SERVER_CONF_WORK_GROUP, v);
0069 }
0070
0071 char *ksmbd_netbios_name(void)
0072 {
0073 return server_conf.conf[SERVER_CONF_NETBIOS_NAME];
0074 }
0075
0076 char *ksmbd_server_string(void)
0077 {
0078 return server_conf.conf[SERVER_CONF_SERVER_STRING];
0079 }
0080
0081 char *ksmbd_work_group(void)
0082 {
0083 return server_conf.conf[SERVER_CONF_WORK_GROUP];
0084 }
0085
0086
0087
0088
0089
0090
0091
0092 static inline int check_conn_state(struct ksmbd_work *work)
0093 {
0094 struct smb_hdr *rsp_hdr;
0095
0096 if (ksmbd_conn_exiting(work) || ksmbd_conn_need_reconnect(work)) {
0097 rsp_hdr = work->response_buf;
0098 rsp_hdr->Status.CifsError = STATUS_CONNECTION_DISCONNECTED;
0099 return 1;
0100 }
0101 return 0;
0102 }
0103
0104 #define SERVER_HANDLER_CONTINUE 0
0105 #define SERVER_HANDLER_ABORT 1
0106
0107 static int __process_request(struct ksmbd_work *work, struct ksmbd_conn *conn,
0108 u16 *cmd)
0109 {
0110 struct smb_version_cmds *cmds;
0111 u16 command;
0112 int ret;
0113
0114 if (check_conn_state(work))
0115 return SERVER_HANDLER_CONTINUE;
0116
0117 if (ksmbd_verify_smb_message(work))
0118 return SERVER_HANDLER_ABORT;
0119
0120 command = conn->ops->get_cmd_val(work);
0121 *cmd = command;
0122
0123 andx_again:
0124 if (command >= conn->max_cmds) {
0125 conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER);
0126 return SERVER_HANDLER_CONTINUE;
0127 }
0128
0129 cmds = &conn->cmds[command];
0130 if (!cmds->proc) {
0131 ksmbd_debug(SMB, "*** not implemented yet cmd = %x\n", command);
0132 conn->ops->set_rsp_status(work, STATUS_NOT_IMPLEMENTED);
0133 return SERVER_HANDLER_CONTINUE;
0134 }
0135
0136 if (work->sess && conn->ops->is_sign_req(work, command)) {
0137 ret = conn->ops->check_sign_req(work);
0138 if (!ret) {
0139 conn->ops->set_rsp_status(work, STATUS_ACCESS_DENIED);
0140 return SERVER_HANDLER_CONTINUE;
0141 }
0142 }
0143
0144 ret = cmds->proc(work);
0145
0146 if (ret < 0)
0147 ksmbd_debug(CONN, "Failed to process %u [%d]\n", command, ret);
0148
0149 else if (ret > 0) {
0150 command = ret;
0151 *cmd = command;
0152 goto andx_again;
0153 }
0154
0155 if (work->send_no_response)
0156 return SERVER_HANDLER_ABORT;
0157 return SERVER_HANDLER_CONTINUE;
0158 }
0159
0160 static void __handle_ksmbd_work(struct ksmbd_work *work,
0161 struct ksmbd_conn *conn)
0162 {
0163 u16 command = 0;
0164 int rc;
0165
0166 if (conn->ops->allocate_rsp_buf(work))
0167 return;
0168
0169 if (conn->ops->is_transform_hdr &&
0170 conn->ops->is_transform_hdr(work->request_buf)) {
0171 rc = conn->ops->decrypt_req(work);
0172 if (rc < 0) {
0173 conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
0174 goto send;
0175 }
0176
0177 work->encrypted = true;
0178 }
0179
0180 rc = conn->ops->init_rsp_hdr(work);
0181 if (rc) {
0182
0183 conn->ops->set_rsp_status(work, STATUS_INVALID_HANDLE);
0184 goto send;
0185 }
0186
0187 if (conn->ops->check_user_session) {
0188 rc = conn->ops->check_user_session(work);
0189 if (rc < 0) {
0190 command = conn->ops->get_cmd_val(work);
0191 conn->ops->set_rsp_status(work,
0192 STATUS_USER_SESSION_DELETED);
0193 goto send;
0194 } else if (rc > 0) {
0195 rc = conn->ops->get_ksmbd_tcon(work);
0196 if (rc < 0) {
0197 conn->ops->set_rsp_status(work,
0198 STATUS_NETWORK_NAME_DELETED);
0199 goto send;
0200 }
0201 }
0202 }
0203
0204 do {
0205 rc = __process_request(work, conn, &command);
0206 if (rc == SERVER_HANDLER_ABORT)
0207 break;
0208
0209
0210
0211
0212
0213 if (conn->ops->set_rsp_credits) {
0214 spin_lock(&conn->credits_lock);
0215 rc = conn->ops->set_rsp_credits(work);
0216 spin_unlock(&conn->credits_lock);
0217 if (rc < 0) {
0218 conn->ops->set_rsp_status(work,
0219 STATUS_INVALID_PARAMETER);
0220 goto send;
0221 }
0222 }
0223
0224 if (work->sess &&
0225 (work->sess->sign || smb3_11_final_sess_setup_resp(work) ||
0226 conn->ops->is_sign_req(work, command)))
0227 conn->ops->set_sign_rsp(work);
0228 } while (is_chained_smb2_message(work));
0229
0230 if (work->send_no_response)
0231 return;
0232
0233 send:
0234 smb3_preauth_hash_rsp(work);
0235 if (work->sess && work->sess->enc && work->encrypted &&
0236 conn->ops->encrypt_resp) {
0237 rc = conn->ops->encrypt_resp(work);
0238 if (rc < 0) {
0239 conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
0240 goto send;
0241 }
0242 }
0243
0244 ksmbd_conn_write(work);
0245 }
0246
0247
0248
0249
0250
0251
0252
0253 static void handle_ksmbd_work(struct work_struct *wk)
0254 {
0255 struct ksmbd_work *work = container_of(wk, struct ksmbd_work, work);
0256 struct ksmbd_conn *conn = work->conn;
0257
0258 atomic64_inc(&conn->stats.request_served);
0259
0260 __handle_ksmbd_work(work, conn);
0261
0262 ksmbd_conn_try_dequeue_request(work);
0263 ksmbd_free_work_struct(work);
0264
0265
0266
0267
0268
0269 if (!atomic_dec_return(&conn->r_count) && waitqueue_active(&conn->r_count_q))
0270 wake_up(&conn->r_count_q);
0271 }
0272
0273
0274
0275
0276
0277
0278
0279
0280 static int queue_ksmbd_work(struct ksmbd_conn *conn)
0281 {
0282 struct ksmbd_work *work;
0283
0284 work = ksmbd_alloc_work_struct();
0285 if (!work) {
0286 pr_err("allocation for work failed\n");
0287 return -ENOMEM;
0288 }
0289
0290 work->conn = conn;
0291 work->request_buf = conn->request_buf;
0292 conn->request_buf = NULL;
0293
0294 if (ksmbd_init_smb_server(work)) {
0295 ksmbd_free_work_struct(work);
0296 return -EINVAL;
0297 }
0298
0299 ksmbd_conn_enqueue_request(work);
0300 atomic_inc(&conn->r_count);
0301
0302 conn->last_active = jiffies;
0303 INIT_WORK(&work->work, handle_ksmbd_work);
0304 ksmbd_queue_work(work);
0305 return 0;
0306 }
0307
0308 static int ksmbd_server_process_request(struct ksmbd_conn *conn)
0309 {
0310 return queue_ksmbd_work(conn);
0311 }
0312
0313 static int ksmbd_server_terminate_conn(struct ksmbd_conn *conn)
0314 {
0315 ksmbd_sessions_deregister(conn);
0316 destroy_lease_table(conn);
0317 return 0;
0318 }
0319
0320 static void ksmbd_server_tcp_callbacks_init(void)
0321 {
0322 struct ksmbd_conn_ops ops;
0323
0324 ops.process_fn = ksmbd_server_process_request;
0325 ops.terminate_fn = ksmbd_server_terminate_conn;
0326
0327 ksmbd_conn_init_server_callbacks(&ops);
0328 }
0329
0330 static void server_conf_free(void)
0331 {
0332 int i;
0333
0334 for (i = 0; i < ARRAY_SIZE(server_conf.conf); i++) {
0335 kfree(server_conf.conf[i]);
0336 server_conf.conf[i] = NULL;
0337 }
0338 }
0339
0340 static int server_conf_init(void)
0341 {
0342 WRITE_ONCE(server_conf.state, SERVER_STATE_STARTING_UP);
0343 server_conf.enforced_signing = 0;
0344 server_conf.min_protocol = ksmbd_min_protocol();
0345 server_conf.max_protocol = ksmbd_max_protocol();
0346 server_conf.auth_mechs = KSMBD_AUTH_NTLMSSP;
0347 #ifdef CONFIG_SMB_SERVER_KERBEROS5
0348 server_conf.auth_mechs |= KSMBD_AUTH_KRB5 |
0349 KSMBD_AUTH_MSKRB5;
0350 #endif
0351 return 0;
0352 }
0353
0354 static void server_ctrl_handle_init(struct server_ctrl_struct *ctrl)
0355 {
0356 int ret;
0357
0358 ret = ksmbd_conn_transport_init();
0359 if (ret) {
0360 server_queue_ctrl_reset_work();
0361 return;
0362 }
0363
0364 WRITE_ONCE(server_conf.state, SERVER_STATE_RUNNING);
0365 }
0366
0367 static void server_ctrl_handle_reset(struct server_ctrl_struct *ctrl)
0368 {
0369 ksmbd_ipc_soft_reset();
0370 ksmbd_conn_transport_destroy();
0371 server_conf_free();
0372 server_conf_init();
0373 WRITE_ONCE(server_conf.state, SERVER_STATE_STARTING_UP);
0374 }
0375
0376 static void server_ctrl_handle_work(struct work_struct *work)
0377 {
0378 struct server_ctrl_struct *ctrl;
0379
0380 ctrl = container_of(work, struct server_ctrl_struct, ctrl_work);
0381
0382 mutex_lock(&ctrl_lock);
0383 switch (ctrl->type) {
0384 case SERVER_CTRL_TYPE_INIT:
0385 server_ctrl_handle_init(ctrl);
0386 break;
0387 case SERVER_CTRL_TYPE_RESET:
0388 server_ctrl_handle_reset(ctrl);
0389 break;
0390 default:
0391 pr_err("Unknown server work type: %d\n", ctrl->type);
0392 }
0393 mutex_unlock(&ctrl_lock);
0394 kfree(ctrl);
0395 module_put(THIS_MODULE);
0396 }
0397
0398 static int __queue_ctrl_work(int type)
0399 {
0400 struct server_ctrl_struct *ctrl;
0401
0402 ctrl = kmalloc(sizeof(struct server_ctrl_struct), GFP_KERNEL);
0403 if (!ctrl)
0404 return -ENOMEM;
0405
0406 __module_get(THIS_MODULE);
0407 ctrl->type = type;
0408 INIT_WORK(&ctrl->ctrl_work, server_ctrl_handle_work);
0409 queue_work(system_long_wq, &ctrl->ctrl_work);
0410 return 0;
0411 }
0412
0413 int server_queue_ctrl_init_work(void)
0414 {
0415 return __queue_ctrl_work(SERVER_CTRL_TYPE_INIT);
0416 }
0417
0418 int server_queue_ctrl_reset_work(void)
0419 {
0420 return __queue_ctrl_work(SERVER_CTRL_TYPE_RESET);
0421 }
0422
0423 static ssize_t stats_show(struct class *class, struct class_attribute *attr,
0424 char *buf)
0425 {
0426
0427
0428
0429
0430 static int stats_version = 2;
0431 static const char * const state[] = {
0432 "startup",
0433 "running",
0434 "reset",
0435 "shutdown"
0436 };
0437
0438 ssize_t sz = scnprintf(buf, PAGE_SIZE, "%d %s %d %lu\n", stats_version,
0439 state[server_conf.state], server_conf.tcp_port,
0440 server_conf.ipc_last_active / HZ);
0441 return sz;
0442 }
0443
0444 static ssize_t kill_server_store(struct class *class,
0445 struct class_attribute *attr, const char *buf,
0446 size_t len)
0447 {
0448 if (!sysfs_streq(buf, "hard"))
0449 return len;
0450
0451 pr_info("kill command received\n");
0452 mutex_lock(&ctrl_lock);
0453 WRITE_ONCE(server_conf.state, SERVER_STATE_RESETTING);
0454 __module_get(THIS_MODULE);
0455 server_ctrl_handle_reset(NULL);
0456 module_put(THIS_MODULE);
0457 mutex_unlock(&ctrl_lock);
0458 return len;
0459 }
0460
0461 static const char * const debug_type_strings[] = {"smb", "auth", "vfs",
0462 "oplock", "ipc", "conn",
0463 "rdma"};
0464
0465 static ssize_t debug_show(struct class *class, struct class_attribute *attr,
0466 char *buf)
0467 {
0468 ssize_t sz = 0;
0469 int i, pos = 0;
0470
0471 for (i = 0; i < ARRAY_SIZE(debug_type_strings); i++) {
0472 if ((ksmbd_debug_types >> i) & 1) {
0473 pos = scnprintf(buf + sz,
0474 PAGE_SIZE - sz,
0475 "[%s] ",
0476 debug_type_strings[i]);
0477 } else {
0478 pos = scnprintf(buf + sz,
0479 PAGE_SIZE - sz,
0480 "%s ",
0481 debug_type_strings[i]);
0482 }
0483 sz += pos;
0484 }
0485 sz += scnprintf(buf + sz, PAGE_SIZE - sz, "\n");
0486 return sz;
0487 }
0488
0489 static ssize_t debug_store(struct class *class, struct class_attribute *attr,
0490 const char *buf, size_t len)
0491 {
0492 int i;
0493
0494 for (i = 0; i < ARRAY_SIZE(debug_type_strings); i++) {
0495 if (sysfs_streq(buf, "all")) {
0496 if (ksmbd_debug_types == KSMBD_DEBUG_ALL)
0497 ksmbd_debug_types = 0;
0498 else
0499 ksmbd_debug_types = KSMBD_DEBUG_ALL;
0500 break;
0501 }
0502
0503 if (sysfs_streq(buf, debug_type_strings[i])) {
0504 if (ksmbd_debug_types & (1 << i))
0505 ksmbd_debug_types &= ~(1 << i);
0506 else
0507 ksmbd_debug_types |= (1 << i);
0508 break;
0509 }
0510 }
0511
0512 return len;
0513 }
0514
0515 static CLASS_ATTR_RO(stats);
0516 static CLASS_ATTR_WO(kill_server);
0517 static CLASS_ATTR_RW(debug);
0518
0519 static struct attribute *ksmbd_control_class_attrs[] = {
0520 &class_attr_stats.attr,
0521 &class_attr_kill_server.attr,
0522 &class_attr_debug.attr,
0523 NULL,
0524 };
0525 ATTRIBUTE_GROUPS(ksmbd_control_class);
0526
0527 static struct class ksmbd_control_class = {
0528 .name = "ksmbd-control",
0529 .owner = THIS_MODULE,
0530 .class_groups = ksmbd_control_class_groups,
0531 };
0532
0533 static int ksmbd_server_shutdown(void)
0534 {
0535 WRITE_ONCE(server_conf.state, SERVER_STATE_SHUTTING_DOWN);
0536
0537 class_unregister(&ksmbd_control_class);
0538 ksmbd_workqueue_destroy();
0539 ksmbd_ipc_release();
0540 ksmbd_conn_transport_destroy();
0541 ksmbd_crypto_destroy();
0542 ksmbd_free_global_file_table();
0543 destroy_lease_table(NULL);
0544 ksmbd_work_pool_destroy();
0545 ksmbd_exit_file_cache();
0546 server_conf_free();
0547 return 0;
0548 }
0549
0550 static int __init ksmbd_server_init(void)
0551 {
0552 int ret;
0553
0554 ret = class_register(&ksmbd_control_class);
0555 if (ret) {
0556 pr_err("Unable to register ksmbd-control class\n");
0557 return ret;
0558 }
0559
0560 ksmbd_server_tcp_callbacks_init();
0561
0562 ret = server_conf_init();
0563 if (ret)
0564 goto err_unregister;
0565
0566 ret = ksmbd_work_pool_init();
0567 if (ret)
0568 goto err_unregister;
0569
0570 ret = ksmbd_init_file_cache();
0571 if (ret)
0572 goto err_destroy_work_pools;
0573
0574 ret = ksmbd_ipc_init();
0575 if (ret)
0576 goto err_exit_file_cache;
0577
0578 ret = ksmbd_init_global_file_table();
0579 if (ret)
0580 goto err_ipc_release;
0581
0582 ret = ksmbd_inode_hash_init();
0583 if (ret)
0584 goto err_destroy_file_table;
0585
0586 ret = ksmbd_crypto_create();
0587 if (ret)
0588 goto err_release_inode_hash;
0589
0590 ret = ksmbd_workqueue_init();
0591 if (ret)
0592 goto err_crypto_destroy;
0593
0594 pr_warn_once("The ksmbd server is experimental\n");
0595
0596 return 0;
0597
0598 err_crypto_destroy:
0599 ksmbd_crypto_destroy();
0600 err_release_inode_hash:
0601 ksmbd_release_inode_hash();
0602 err_destroy_file_table:
0603 ksmbd_free_global_file_table();
0604 err_ipc_release:
0605 ksmbd_ipc_release();
0606 err_exit_file_cache:
0607 ksmbd_exit_file_cache();
0608 err_destroy_work_pools:
0609 ksmbd_work_pool_destroy();
0610 err_unregister:
0611 class_unregister(&ksmbd_control_class);
0612
0613 return ret;
0614 }
0615
0616
0617
0618
0619 static void __exit ksmbd_server_exit(void)
0620 {
0621 ksmbd_server_shutdown();
0622 ksmbd_release_inode_hash();
0623 }
0624
0625 MODULE_AUTHOR("Namjae Jeon <linkinjeon@kernel.org>");
0626 MODULE_VERSION(KSMBD_VERSION);
0627 MODULE_DESCRIPTION("Linux kernel CIFS/SMB SERVER");
0628 MODULE_LICENSE("GPL");
0629 MODULE_SOFTDEP("pre: ecb");
0630 MODULE_SOFTDEP("pre: hmac");
0631 MODULE_SOFTDEP("pre: md5");
0632 MODULE_SOFTDEP("pre: nls");
0633 MODULE_SOFTDEP("pre: aes");
0634 MODULE_SOFTDEP("pre: cmac");
0635 MODULE_SOFTDEP("pre: sha256");
0636 MODULE_SOFTDEP("pre: sha512");
0637 MODULE_SOFTDEP("pre: aead2");
0638 MODULE_SOFTDEP("pre: ccm");
0639 MODULE_SOFTDEP("pre: gcm");
0640 MODULE_SOFTDEP("pre: crc32");
0641 module_init(ksmbd_server_init)
0642 module_exit(ksmbd_server_exit)