]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - fs/ksmbd/server.c
btrfs: zoned: fix missing endianness conversion in sb_write_pointer
[mirror_ubuntu-jammy-kernel.git] / fs / ksmbd / server.c
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 "glob.h"
8 #include "oplock.h"
9 #include "misc.h"
10 #include <linux/sched/signal.h>
11 #include <linux/workqueue.h>
12 #include <linux/sysfs.h>
13 #include <linux/module.h>
14 #include <linux/moduleparam.h>
15
16 #include "server.h"
17 #include "smb_common.h"
18 #include "smbstatus.h"
19 #include "connection.h"
20 #include "transport_ipc.h"
21 #include "mgmt/user_session.h"
22 #include "crypto_ctx.h"
23 #include "auth.h"
24
25 int ksmbd_debug_types;
26
27 struct ksmbd_server_config server_conf;
28
29 enum SERVER_CTRL_TYPE {
30 SERVER_CTRL_TYPE_INIT,
31 SERVER_CTRL_TYPE_RESET,
32 };
33
34 struct server_ctrl_struct {
35 int type;
36 struct work_struct ctrl_work;
37 };
38
39 static DEFINE_MUTEX(ctrl_lock);
40
41 static int ___server_conf_set(int idx, char *val)
42 {
43 if (idx >= ARRAY_SIZE(server_conf.conf))
44 return -EINVAL;
45
46 if (!val || val[0] == 0x00)
47 return -EINVAL;
48
49 kfree(server_conf.conf[idx]);
50 server_conf.conf[idx] = kstrdup(val, GFP_KERNEL);
51 if (!server_conf.conf[idx])
52 return -ENOMEM;
53 return 0;
54 }
55
56 int ksmbd_set_netbios_name(char *v)
57 {
58 return ___server_conf_set(SERVER_CONF_NETBIOS_NAME, v);
59 }
60
61 int ksmbd_set_server_string(char *v)
62 {
63 return ___server_conf_set(SERVER_CONF_SERVER_STRING, v);
64 }
65
66 int ksmbd_set_work_group(char *v)
67 {
68 return ___server_conf_set(SERVER_CONF_WORK_GROUP, v);
69 }
70
71 char *ksmbd_netbios_name(void)
72 {
73 return server_conf.conf[SERVER_CONF_NETBIOS_NAME];
74 }
75
76 char *ksmbd_server_string(void)
77 {
78 return server_conf.conf[SERVER_CONF_SERVER_STRING];
79 }
80
81 char *ksmbd_work_group(void)
82 {
83 return server_conf.conf[SERVER_CONF_WORK_GROUP];
84 }
85
86 /**
87 * check_conn_state() - check state of server thread connection
88 * @work: smb work containing server thread information
89 *
90 * Return: 0 on valid connection, otherwise 1 to reconnect
91 */
92 static inline int check_conn_state(struct ksmbd_work *work)
93 {
94 struct smb_hdr *rsp_hdr;
95
96 if (ksmbd_conn_exiting(work) || ksmbd_conn_need_reconnect(work)) {
97 rsp_hdr = work->response_buf;
98 rsp_hdr->Status.CifsError = STATUS_CONNECTION_DISCONNECTED;
99 return 1;
100 }
101 return 0;
102 }
103
104 #define SERVER_HANDLER_CONTINUE 0
105 #define SERVER_HANDLER_ABORT 1
106
107 static int __process_request(struct ksmbd_work *work, struct ksmbd_conn *conn,
108 u16 *cmd)
109 {
110 struct smb_version_cmds *cmds;
111 u16 command;
112 int ret;
113
114 if (check_conn_state(work))
115 return SERVER_HANDLER_CONTINUE;
116
117 if (ksmbd_verify_smb_message(work))
118 return SERVER_HANDLER_ABORT;
119
120 command = conn->ops->get_cmd_val(work);
121 *cmd = command;
122
123 andx_again:
124 if (command >= conn->max_cmds) {
125 conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER);
126 return SERVER_HANDLER_CONTINUE;
127 }
128
129 cmds = &conn->cmds[command];
130 if (!cmds->proc) {
131 ksmbd_debug(SMB, "*** not implemented yet cmd = %x\n", command);
132 conn->ops->set_rsp_status(work, STATUS_NOT_IMPLEMENTED);
133 return SERVER_HANDLER_CONTINUE;
134 }
135
136 if (work->sess && conn->ops->is_sign_req(work, command)) {
137 ret = conn->ops->check_sign_req(work);
138 if (!ret) {
139 conn->ops->set_rsp_status(work, STATUS_ACCESS_DENIED);
140 return SERVER_HANDLER_CONTINUE;
141 }
142 }
143
144 ret = cmds->proc(work);
145
146 if (ret < 0)
147 ksmbd_debug(CONN, "Failed to process %u [%d]\n", command, ret);
148 /* AndX commands - chained request can return positive values */
149 else if (ret > 0) {
150 command = ret;
151 *cmd = command;
152 goto andx_again;
153 }
154
155 if (work->send_no_response)
156 return SERVER_HANDLER_ABORT;
157 return SERVER_HANDLER_CONTINUE;
158 }
159
160 static void __handle_ksmbd_work(struct ksmbd_work *work,
161 struct ksmbd_conn *conn)
162 {
163 u16 command = 0;
164 int rc;
165
166 if (conn->ops->allocate_rsp_buf(work))
167 return;
168
169 if (conn->ops->is_transform_hdr &&
170 conn->ops->is_transform_hdr(work->request_buf)) {
171 rc = conn->ops->decrypt_req(work);
172 if (rc < 0) {
173 conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
174 goto send;
175 }
176
177 work->encrypted = true;
178 }
179
180 rc = conn->ops->init_rsp_hdr(work);
181 if (rc) {
182 /* either uid or tid is not correct */
183 conn->ops->set_rsp_status(work, STATUS_INVALID_HANDLE);
184 goto send;
185 }
186
187 if (conn->ops->check_user_session) {
188 rc = conn->ops->check_user_session(work);
189 if (rc < 0) {
190 command = conn->ops->get_cmd_val(work);
191 conn->ops->set_rsp_status(work,
192 STATUS_USER_SESSION_DELETED);
193 goto send;
194 } else if (rc > 0) {
195 rc = conn->ops->get_ksmbd_tcon(work);
196 if (rc < 0) {
197 conn->ops->set_rsp_status(work,
198 STATUS_NETWORK_NAME_DELETED);
199 goto send;
200 }
201 }
202 }
203
204 do {
205 rc = __process_request(work, conn, &command);
206 if (rc == SERVER_HANDLER_ABORT)
207 break;
208
209 /*
210 * Call smb2_set_rsp_credits() function to set number of credits
211 * granted in hdr of smb2 response.
212 */
213 if (conn->ops->set_rsp_credits) {
214 spin_lock(&conn->credits_lock);
215 rc = conn->ops->set_rsp_credits(work);
216 spin_unlock(&conn->credits_lock);
217 if (rc < 0) {
218 conn->ops->set_rsp_status(work,
219 STATUS_INVALID_PARAMETER);
220 goto send;
221 }
222 }
223
224 if (work->sess &&
225 (work->sess->sign || smb3_11_final_sess_setup_resp(work) ||
226 conn->ops->is_sign_req(work, command)))
227 conn->ops->set_sign_rsp(work);
228 } while (is_chained_smb2_message(work));
229
230 if (work->send_no_response)
231 return;
232
233 send:
234 smb3_preauth_hash_rsp(work);
235 if (work->sess && work->sess->enc && work->encrypted &&
236 conn->ops->encrypt_resp) {
237 rc = conn->ops->encrypt_resp(work);
238 if (rc < 0)
239 conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
240 }
241
242 ksmbd_conn_write(work);
243 }
244
245 /**
246 * handle_ksmbd_work() - process pending smb work requests
247 * @wk: smb work containing request command buffer
248 *
249 * called by kworker threads to processing remaining smb work requests
250 */
251 static void handle_ksmbd_work(struct work_struct *wk)
252 {
253 struct ksmbd_work *work = container_of(wk, struct ksmbd_work, work);
254 struct ksmbd_conn *conn = work->conn;
255
256 atomic64_inc(&conn->stats.request_served);
257
258 __handle_ksmbd_work(work, conn);
259
260 ksmbd_conn_try_dequeue_request(work);
261 ksmbd_free_work_struct(work);
262 atomic_dec(&conn->r_count);
263 }
264
265 /**
266 * queue_ksmbd_work() - queue a smb request to worker thread queue
267 * for proccessing smb command and sending response
268 * @conn: connection instance
269 *
270 * read remaining data from socket create and submit work.
271 */
272 static int queue_ksmbd_work(struct ksmbd_conn *conn)
273 {
274 struct ksmbd_work *work;
275
276 work = ksmbd_alloc_work_struct();
277 if (!work) {
278 pr_err("allocation for work failed\n");
279 return -ENOMEM;
280 }
281
282 work->conn = conn;
283 work->request_buf = conn->request_buf;
284 conn->request_buf = NULL;
285
286 if (ksmbd_init_smb_server(work)) {
287 ksmbd_free_work_struct(work);
288 return -EINVAL;
289 }
290
291 ksmbd_conn_enqueue_request(work);
292 atomic_inc(&conn->r_count);
293 /* update activity on connection */
294 conn->last_active = jiffies;
295 INIT_WORK(&work->work, handle_ksmbd_work);
296 ksmbd_queue_work(work);
297 return 0;
298 }
299
300 static int ksmbd_server_process_request(struct ksmbd_conn *conn)
301 {
302 return queue_ksmbd_work(conn);
303 }
304
305 static int ksmbd_server_terminate_conn(struct ksmbd_conn *conn)
306 {
307 ksmbd_sessions_deregister(conn);
308 destroy_lease_table(conn);
309 return 0;
310 }
311
312 static void ksmbd_server_tcp_callbacks_init(void)
313 {
314 struct ksmbd_conn_ops ops;
315
316 ops.process_fn = ksmbd_server_process_request;
317 ops.terminate_fn = ksmbd_server_terminate_conn;
318
319 ksmbd_conn_init_server_callbacks(&ops);
320 }
321
322 static void server_conf_free(void)
323 {
324 int i;
325
326 for (i = 0; i < ARRAY_SIZE(server_conf.conf); i++) {
327 kfree(server_conf.conf[i]);
328 server_conf.conf[i] = NULL;
329 }
330 }
331
332 static int server_conf_init(void)
333 {
334 WRITE_ONCE(server_conf.state, SERVER_STATE_STARTING_UP);
335 server_conf.enforced_signing = 0;
336 server_conf.min_protocol = ksmbd_min_protocol();
337 server_conf.max_protocol = ksmbd_max_protocol();
338 server_conf.auth_mechs = KSMBD_AUTH_NTLMSSP;
339 #ifdef CONFIG_SMB_SERVER_KERBEROS5
340 server_conf.auth_mechs |= KSMBD_AUTH_KRB5 |
341 KSMBD_AUTH_MSKRB5;
342 #endif
343 return 0;
344 }
345
346 static void server_ctrl_handle_init(struct server_ctrl_struct *ctrl)
347 {
348 int ret;
349
350 ret = ksmbd_conn_transport_init();
351 if (ret) {
352 server_queue_ctrl_reset_work();
353 return;
354 }
355
356 WRITE_ONCE(server_conf.state, SERVER_STATE_RUNNING);
357 }
358
359 static void server_ctrl_handle_reset(struct server_ctrl_struct *ctrl)
360 {
361 ksmbd_ipc_soft_reset();
362 ksmbd_conn_transport_destroy();
363 server_conf_free();
364 server_conf_init();
365 WRITE_ONCE(server_conf.state, SERVER_STATE_STARTING_UP);
366 }
367
368 static void server_ctrl_handle_work(struct work_struct *work)
369 {
370 struct server_ctrl_struct *ctrl;
371
372 ctrl = container_of(work, struct server_ctrl_struct, ctrl_work);
373
374 mutex_lock(&ctrl_lock);
375 switch (ctrl->type) {
376 case SERVER_CTRL_TYPE_INIT:
377 server_ctrl_handle_init(ctrl);
378 break;
379 case SERVER_CTRL_TYPE_RESET:
380 server_ctrl_handle_reset(ctrl);
381 break;
382 default:
383 pr_err("Unknown server work type: %d\n", ctrl->type);
384 }
385 mutex_unlock(&ctrl_lock);
386 kfree(ctrl);
387 module_put(THIS_MODULE);
388 }
389
390 static int __queue_ctrl_work(int type)
391 {
392 struct server_ctrl_struct *ctrl;
393
394 ctrl = kmalloc(sizeof(struct server_ctrl_struct), GFP_KERNEL);
395 if (!ctrl)
396 return -ENOMEM;
397
398 __module_get(THIS_MODULE);
399 ctrl->type = type;
400 INIT_WORK(&ctrl->ctrl_work, server_ctrl_handle_work);
401 queue_work(system_long_wq, &ctrl->ctrl_work);
402 return 0;
403 }
404
405 int server_queue_ctrl_init_work(void)
406 {
407 return __queue_ctrl_work(SERVER_CTRL_TYPE_INIT);
408 }
409
410 int server_queue_ctrl_reset_work(void)
411 {
412 return __queue_ctrl_work(SERVER_CTRL_TYPE_RESET);
413 }
414
415 static ssize_t stats_show(struct class *class, struct class_attribute *attr,
416 char *buf)
417 {
418 /*
419 * Inc this each time you change stats output format,
420 * so user space will know what to do.
421 */
422 static int stats_version = 2;
423 static const char * const state[] = {
424 "startup",
425 "running",
426 "reset",
427 "shutdown"
428 };
429
430 ssize_t sz = scnprintf(buf, PAGE_SIZE, "%d %s %d %lu\n", stats_version,
431 state[server_conf.state], server_conf.tcp_port,
432 server_conf.ipc_last_active / HZ);
433 return sz;
434 }
435
436 static ssize_t kill_server_store(struct class *class,
437 struct class_attribute *attr, const char *buf,
438 size_t len)
439 {
440 if (!sysfs_streq(buf, "hard"))
441 return len;
442
443 pr_info("kill command received\n");
444 mutex_lock(&ctrl_lock);
445 WRITE_ONCE(server_conf.state, SERVER_STATE_RESETTING);
446 __module_get(THIS_MODULE);
447 server_ctrl_handle_reset(NULL);
448 module_put(THIS_MODULE);
449 mutex_unlock(&ctrl_lock);
450 return len;
451 }
452
453 static const char * const debug_type_strings[] = {"smb", "auth", "vfs",
454 "oplock", "ipc", "conn",
455 "rdma"};
456
457 static ssize_t debug_show(struct class *class, struct class_attribute *attr,
458 char *buf)
459 {
460 ssize_t sz = 0;
461 int i, pos = 0;
462
463 for (i = 0; i < ARRAY_SIZE(debug_type_strings); i++) {
464 if ((ksmbd_debug_types >> i) & 1) {
465 pos = scnprintf(buf + sz,
466 PAGE_SIZE - sz,
467 "[%s] ",
468 debug_type_strings[i]);
469 } else {
470 pos = scnprintf(buf + sz,
471 PAGE_SIZE - sz,
472 "%s ",
473 debug_type_strings[i]);
474 }
475 sz += pos;
476 }
477 sz += scnprintf(buf + sz, PAGE_SIZE - sz, "\n");
478 return sz;
479 }
480
481 static ssize_t debug_store(struct class *class, struct class_attribute *attr,
482 const char *buf, size_t len)
483 {
484 int i;
485
486 for (i = 0; i < ARRAY_SIZE(debug_type_strings); i++) {
487 if (sysfs_streq(buf, "all")) {
488 if (ksmbd_debug_types == KSMBD_DEBUG_ALL)
489 ksmbd_debug_types = 0;
490 else
491 ksmbd_debug_types = KSMBD_DEBUG_ALL;
492 break;
493 }
494
495 if (sysfs_streq(buf, debug_type_strings[i])) {
496 if (ksmbd_debug_types & (1 << i))
497 ksmbd_debug_types &= ~(1 << i);
498 else
499 ksmbd_debug_types |= (1 << i);
500 break;
501 }
502 }
503
504 return len;
505 }
506
507 static CLASS_ATTR_RO(stats);
508 static CLASS_ATTR_WO(kill_server);
509 static CLASS_ATTR_RW(debug);
510
511 static struct attribute *ksmbd_control_class_attrs[] = {
512 &class_attr_stats.attr,
513 &class_attr_kill_server.attr,
514 &class_attr_debug.attr,
515 NULL,
516 };
517 ATTRIBUTE_GROUPS(ksmbd_control_class);
518
519 static struct class ksmbd_control_class = {
520 .name = "ksmbd-control",
521 .owner = THIS_MODULE,
522 .class_groups = ksmbd_control_class_groups,
523 };
524
525 static int ksmbd_server_shutdown(void)
526 {
527 WRITE_ONCE(server_conf.state, SERVER_STATE_SHUTTING_DOWN);
528
529 class_unregister(&ksmbd_control_class);
530 ksmbd_workqueue_destroy();
531 ksmbd_ipc_release();
532 ksmbd_conn_transport_destroy();
533 ksmbd_crypto_destroy();
534 ksmbd_free_global_file_table();
535 destroy_lease_table(NULL);
536 ksmbd_work_pool_destroy();
537 ksmbd_exit_file_cache();
538 server_conf_free();
539 return 0;
540 }
541
542 static int __init ksmbd_server_init(void)
543 {
544 int ret;
545
546 ret = class_register(&ksmbd_control_class);
547 if (ret) {
548 pr_err("Unable to register ksmbd-control class\n");
549 return ret;
550 }
551
552 ksmbd_server_tcp_callbacks_init();
553
554 ret = server_conf_init();
555 if (ret)
556 goto err_unregister;
557
558 ret = ksmbd_work_pool_init();
559 if (ret)
560 goto err_unregister;
561
562 ret = ksmbd_init_file_cache();
563 if (ret)
564 goto err_destroy_work_pools;
565
566 ret = ksmbd_ipc_init();
567 if (ret)
568 goto err_exit_file_cache;
569
570 ret = ksmbd_init_global_file_table();
571 if (ret)
572 goto err_ipc_release;
573
574 ret = ksmbd_inode_hash_init();
575 if (ret)
576 goto err_destroy_file_table;
577
578 ret = ksmbd_crypto_create();
579 if (ret)
580 goto err_release_inode_hash;
581
582 ret = ksmbd_workqueue_init();
583 if (ret)
584 goto err_crypto_destroy;
585
586 pr_warn_once("The ksmbd server is experimental, use at your own risk.\n");
587
588 return 0;
589
590 err_crypto_destroy:
591 ksmbd_crypto_destroy();
592 err_release_inode_hash:
593 ksmbd_release_inode_hash();
594 err_destroy_file_table:
595 ksmbd_free_global_file_table();
596 err_ipc_release:
597 ksmbd_ipc_release();
598 err_exit_file_cache:
599 ksmbd_exit_file_cache();
600 err_destroy_work_pools:
601 ksmbd_work_pool_destroy();
602 err_unregister:
603 class_unregister(&ksmbd_control_class);
604
605 return ret;
606 }
607
608 /**
609 * ksmbd_server_exit() - shutdown forker thread and free memory at module exit
610 */
611 static void __exit ksmbd_server_exit(void)
612 {
613 ksmbd_server_shutdown();
614 ksmbd_release_inode_hash();
615 }
616
617 MODULE_AUTHOR("Namjae Jeon <linkinjeon@kernel.org>");
618 MODULE_VERSION(KSMBD_VERSION);
619 MODULE_DESCRIPTION("Linux kernel CIFS/SMB SERVER");
620 MODULE_LICENSE("GPL");
621 MODULE_SOFTDEP("pre: ecb");
622 MODULE_SOFTDEP("pre: hmac");
623 MODULE_SOFTDEP("pre: md4");
624 MODULE_SOFTDEP("pre: md5");
625 MODULE_SOFTDEP("pre: nls");
626 MODULE_SOFTDEP("pre: aes");
627 MODULE_SOFTDEP("pre: cmac");
628 MODULE_SOFTDEP("pre: sha256");
629 MODULE_SOFTDEP("pre: sha512");
630 MODULE_SOFTDEP("pre: aead2");
631 MODULE_SOFTDEP("pre: ccm");
632 MODULE_SOFTDEP("pre: gcm");
633 MODULE_SOFTDEP("pre: crc32");
634 module_init(ksmbd_server_init)
635 module_exit(ksmbd_server_exit)