projects/linux·blob master · refs

760 lines · 17.8 KiB

1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (C) 2016 Namjae Jeon <[email protected]>
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 "smb2pdu.h"
19#include "../common/smb2status.h"
20#include "connection.h"
21#include "transport_ipc.h"
22#include "mgmt/user_session.h"
23#include "crypto_ctx.h"
24#include "auth.h"
25#include "stats.h"
26#include "compress.h"
27#include "mgmt/share_config.h"
28#include "mgmt/tree_connect.h"
29
30int ksmbd_debug_types;
31
32struct ksmbd_server_config server_conf;
33
34enum SERVER_CTRL_TYPE {
35 SERVER_CTRL_TYPE_INIT,
36 SERVER_CTRL_TYPE_RESET,
37};
38
39struct server_ctrl_struct {
40 int type;
41 struct work_struct ctrl_work;
42};
43
44static DEFINE_MUTEX(ctrl_lock);
45
46static int ___server_conf_set(int idx, char *val)
47{
48 if (idx >= ARRAY_SIZE(server_conf.conf))
49 return -EINVAL;
50
51 if (!val || val[0] == 0x00)
52 return -EINVAL;
53
54 kfree(server_conf.conf[idx]);
55 server_conf.conf[idx] = kstrdup(val, KSMBD_DEFAULT_GFP);
56 if (!server_conf.conf[idx])
57 return -ENOMEM;
58 return 0;
59}
60
61int ksmbd_set_netbios_name(char *v)
62{
63 return ___server_conf_set(SERVER_CONF_NETBIOS_NAME, v);
64}
65
66int ksmbd_set_server_string(char *v)
67{
68 return ___server_conf_set(SERVER_CONF_SERVER_STRING, v);
69}
70
71int ksmbd_set_work_group(char *v)
72{
73 return ___server_conf_set(SERVER_CONF_WORK_GROUP, v);
74}
75
76char *ksmbd_netbios_name(void)
77{
78 return server_conf.conf[SERVER_CONF_NETBIOS_NAME];
79}
80
81char *ksmbd_server_string(void)
82{
83 return server_conf.conf[SERVER_CONF_SERVER_STRING];
84}
85
86char *ksmbd_work_group(void)
87{
88 return server_conf.conf[SERVER_CONF_WORK_GROUP];
89}
90
91/**
92 * check_conn_state() - check state of server thread connection
93 * @work: smb work containing server thread information
94 *
95 * Return: 0 on valid connection, otherwise 1 to reconnect
96 */
97static inline int check_conn_state(struct ksmbd_work *work)
98{
99 struct smb_hdr *rsp_hdr;
100
101 if (ksmbd_conn_exiting(work->conn) ||
102 ksmbd_conn_need_reconnect(work->conn)) {
103 rsp_hdr = smb_get_msg(work->response_buf);
104 rsp_hdr->Status.CifsError = STATUS_CONNECTION_DISCONNECTED;
105 return 1;
106 }
107 return 0;
108}
109
110#define SERVER_HANDLER_CONTINUE 0
111#define SERVER_HANDLER_ABORT 1
112
113static int __process_request(struct ksmbd_work *work, struct ksmbd_conn *conn,
114 u16 *cmd)
115{
116 struct smb_version_cmds *cmds;
117 u16 command;
118 bool signed_req;
119 int ret;
120
121 if (check_conn_state(work))
122 return SERVER_HANDLER_CONTINUE;
123
124 if (ksmbd_verify_smb_message(work)) {
125 conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER);
126 return SERVER_HANDLER_ABORT;
127 }
128
129 command = conn->ops->get_cmd_val(work);
130 *cmd = command;
131
132andx_again:
133 if (command >= conn->max_cmds) {
134 conn->ops->set_rsp_status(work, STATUS_INVALID_PARAMETER);
135 return SERVER_HANDLER_ABORT;
136 }
137
138 cmds = &conn->cmds[command];
139 if (!cmds->proc) {
140 ksmbd_debug(SMB, "*** not implemented yet cmd = %x\n", command);
141 conn->ops->set_rsp_status(work, STATUS_NOT_IMPLEMENTED);
142 return SERVER_HANDLER_ABORT;
143 }
144
145 signed_req = conn->ops->is_sign_req && conn->ops->is_sign_req(work, command);
146 if (work->sess && work->sess->sign && !work->encrypted &&
147 !signed_req) {
148 conn->ops->set_rsp_status(work, STATUS_ACCESS_DENIED);
149 return SERVER_HANDLER_ABORT;
150 }
151
152 if (work->sess && signed_req) {
153 ret = conn->ops->check_sign_req(work);
154 if (!ret) {
155 conn->ops->set_rsp_status(work, STATUS_ACCESS_DENIED);
156 return SERVER_HANDLER_ABORT;
157 }
158 }
159
160 ret = cmds->proc(work);
161 if (conn->ops->inc_reqs) {
162 struct smb2_hdr *rsp = ksmbd_resp_buf_curr(work);
163
164 conn->ops->inc_reqs(command, rsp->Status);
165 }
166
167 if (ret < 0)
168 ksmbd_debug(CONN, "Failed to process %u [%d]\n", command, ret);
169 /* AndX commands - chained request can return positive values */
170 else if (ret > 0) {
171 command = ret;
172 *cmd = command;
173 goto andx_again;
174 }
175
176 if (work->send_no_response)
177 return SERVER_HANDLER_ABORT;
178 return SERVER_HANDLER_CONTINUE;
179}
180
181static void __handle_ksmbd_work(struct ksmbd_work *work,
182 struct ksmbd_conn *conn)
183{
184 u16 command = 0;
185 int rc;
186 bool is_chained = false;
187
188 if (conn->ops->is_transform_hdr &&
189 conn->ops->is_transform_hdr(work->request_buf)) {
190 rc = conn->ops->decrypt_req(work);
191 if (rc < 0) {
192 ksmbd_conn_abort(conn);
193 return;
194 }
195 work->encrypted = true;
196
197 /*
198 * SMB3 applies compression before encryption. The receive loop
199 * handles a plain compression transform before allocating work, but
200 * an encrypted request exposes that transform only after decryption.
201 */
202 if (((struct smb2_hdr *)smb_get_msg(work->request_buf))->ProtocolId ==
203 SMB2_COMPRESSION_TRANSFORM_ID) {
204 rc = ksmbd_decompress_work_request(work);
205 if (rc < 0) {
206 ksmbd_conn_abort(conn);
207 return;
208 }
209 }
210
211 /* The decrypted payload must now be a complete SMB2 request. */
212 if (((struct smb2_hdr *)smb_get_msg(work->request_buf))->ProtocolId !=
213 SMB2_PROTO_NUMBER ||
214 get_rfc1002_len(work->request_buf) < sizeof(struct smb2_pdu)) {
215 ksmbd_conn_abort(conn);
216 return;
217 }
218 }
219
220 if (conn->ops->allocate_rsp_buf(work))
221 return;
222
223 rc = conn->ops->init_rsp_hdr(work);
224 if (rc) {
225 /* either uid or tid is not correct */
226 conn->ops->set_rsp_status(work, STATUS_INVALID_HANDLE);
227 goto send;
228 }
229
230 do {
231 if (conn->ops->check_user_session) {
232 rc = conn->ops->check_user_session(work);
233 if (rc < 0) {
234 if (rc == -EINVAL)
235 conn->ops->set_rsp_status(work,
236 STATUS_INVALID_PARAMETER);
237 else if (rc == -EKEYEXPIRED)
238 conn->ops->set_rsp_status(work,
239 STATUS_NETWORK_SESSION_EXPIRED);
240 else
241 conn->ops->set_rsp_status(work,
242 STATUS_USER_SESSION_DELETED);
243 if (conn->ops->is_sign_req(work, conn->ops->get_cmd_val(work))) {
244 struct smb2_hdr *rsp_hdr;
245
246 rsp_hdr = ksmbd_resp_buf_curr(work);
247 if (rc == -EKEYEXPIRED && work->sess &&
248 conn->ops->set_sign_rsp)
249 conn->ops->set_sign_rsp(work);
250 else
251 rsp_hdr->Flags |= SMB2_FLAGS_SIGNED;
252 }
253 goto send;
254 } else if (rc > 0) {
255 rc = conn->ops->get_ksmbd_tcon(work);
256 if (rc < 0) {
257 if (rc == -EINVAL)
258 conn->ops->set_rsp_status(work,
259 STATUS_INVALID_PARAMETER);
260 else
261 conn->ops->set_rsp_status(work,
262 STATUS_NETWORK_NAME_DELETED);
263 goto send;
264 }
265
266 if (work->tcon &&
267 test_share_config_flag(work->tcon->share_conf,
268 KSMBD_SHARE_FLAG_ENCRYPT_DATA) &&
269 !work->encrypted) {
270 conn->ops->set_rsp_status(work,
271 STATUS_ACCESS_DENIED);
272 goto send;
273 }
274 }
275 }
276
277 rc = __process_request(work, conn, &command);
278 if (rc == SERVER_HANDLER_ABORT) {
279 smb2_complete_request_open(work);
280 break;
281 }
282
283 /*
284 * Call smb2_set_rsp_credits() function to set number of credits
285 * granted in hdr of smb2 response.
286 */
287 if (conn->ops->set_rsp_credits) {
288 spin_lock(&conn->credits_lock);
289 rc = conn->ops->set_rsp_credits(work);
290 spin_unlock(&conn->credits_lock);
291 if (rc < 0) {
292 conn->ops->set_rsp_status(work,
293 STATUS_INVALID_PARAMETER);
294 smb2_complete_request_open(work);
295 goto send;
296 }
297 }
298
299 smb2_complete_request_open(work);
300
301 is_chained = is_chained_smb2_message(work);
302
303 if (work->sess &&
304 (work->sess->sign || smb3_11_final_sess_setup_resp(work) ||
305 conn->ops->is_sign_req(work, command))) {
306 if (command == SMB2_SESSION_SETUP_HE &&
307 work->sess->dialect >= SMB30_PROT_ID &&
308 conn->dialect < SMB30_PROT_ID)
309 smb3_set_sign_rsp(work);
310 else
311 conn->ops->set_sign_rsp(work);
312 }
313 } while (is_chained == true);
314
315send:
316 smb2_complete_request_open(work);
317 /*
318 * Release any credit charge still outstanding for this request. On
319 * the normal path smb2_set_rsp_credits() already returned it, but the
320 * abort, error and send-no-response paths skip that call, so the
321 * charge would otherwise leak and eventually exhaust the connection's
322 * outstanding credit window.
323 */
324 if (work->credit_charge) {
325 spin_lock(&conn->credits_lock);
326 conn->outstanding_credits -= work->credit_charge;
327 work->credit_charge = 0;
328 spin_unlock(&conn->credits_lock);
329 }
330
331 if (work->tcon)
332 ksmbd_tree_connect_put(work->tcon);
333 smb3_preauth_hash_rsp(work);
334 /*
335 * Preauthentication hashes cover the original SMB2 response. Apply the
336 * transport compression wrapper only after updating the hash.
337 */
338 if (work->compress_response) {
339 rc = ksmbd_compress_response(work);
340 if (rc < 0)
341 ksmbd_debug(CONN, "Failed to compress response: %d\n", rc);
342 }
343 if (work->sess && work->sess->enc && work->encrypted &&
344 conn->ops->encrypt_resp) {
345 rc = conn->ops->encrypt_resp(work);
346 if (rc < 0)
347 conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
348 }
349 if (work->sess)
350 ksmbd_user_session_put(work->sess);
351
352 ksmbd_conn_write(work);
353}
354
355/**
356 * handle_ksmbd_work() - process pending smb work requests
357 * @wk: smb work containing request command buffer
358 *
359 * called by kworker threads to processing remaining smb work requests
360 */
361static void handle_ksmbd_work(struct work_struct *wk)
362{
363 struct ksmbd_work *work = container_of(wk, struct ksmbd_work, work);
364 struct ksmbd_conn *conn = work->conn;
365
366 atomic64_inc(&conn->stats.request_served);
367
368 __handle_ksmbd_work(work, conn);
369
370 ksmbd_conn_try_dequeue_request(work);
371 ksmbd_free_work_struct(work);
372 ksmbd_conn_r_count_dec(conn);
373}
374
375/**
376 * queue_ksmbd_work() - queue a smb request to worker thread queue
377 * for processing smb command and sending response
378 * @conn: connection instance
379 *
380 * read remaining data from socket create and submit work.
381 */
382static int queue_ksmbd_work(struct ksmbd_conn *conn)
383{
384 struct ksmbd_work *work;
385 int err;
386
387 err = ksmbd_init_smb_server(conn);
388 if (err)
389 return 0;
390
391 work = ksmbd_alloc_work_struct();
392 if (!work) {
393 pr_err("allocation for work failed\n");
394 return -ENOMEM;
395 }
396
397 work->conn = conn;
398 work->request_buf = conn->request_buf;
399 conn->request_buf = NULL;
400
401 ksmbd_conn_enqueue_request(work);
402 ksmbd_conn_r_count_inc(conn);
403 /* update activity on connection */
404 conn->last_active = jiffies;
405 INIT_WORK(&work->work, handle_ksmbd_work);
406 ksmbd_queue_work(work);
407 return 0;
408}
409
410static int ksmbd_server_process_request(struct ksmbd_conn *conn)
411{
412 return queue_ksmbd_work(conn);
413}
414
415static int ksmbd_server_terminate_conn(struct ksmbd_conn *conn)
416{
417 ksmbd_conn_sessions_cleanup(conn);
418 destroy_lease_table(conn);
419 return 0;
420}
421
422static void ksmbd_server_tcp_callbacks_init(void)
423{
424 struct ksmbd_conn_ops ops;
425
426 ops.process_fn = ksmbd_server_process_request;
427 ops.terminate_fn = ksmbd_server_terminate_conn;
428
429 ksmbd_conn_init_server_callbacks(&ops);
430}
431
432static void server_conf_free(void)
433{
434 int i;
435
436 for (i = 0; i < ARRAY_SIZE(server_conf.conf); i++) {
437 kfree(server_conf.conf[i]);
438 server_conf.conf[i] = NULL;
439 }
440}
441
442static int server_conf_init(void)
443{
444 WRITE_ONCE(server_conf.state, SERVER_STATE_STARTING_UP);
445 server_conf.enforced_signing = 0;
446 server_conf.min_protocol = ksmbd_min_protocol();
447 server_conf.max_protocol = ksmbd_max_protocol();
448 server_conf.auth_mechs = KSMBD_AUTH_NTLMSSP;
449#ifdef CONFIG_SMB_SERVER_KERBEROS5
450 server_conf.auth_mechs |= KSMBD_AUTH_KRB5 |
451 KSMBD_AUTH_MSKRB5;
452#endif
453 server_conf.max_inflight_req = SMB2_MAX_CREDITS;
454 return 0;
455}
456
457static void server_ctrl_handle_init(struct server_ctrl_struct *ctrl)
458{
459 int ret;
460
461 ksmbd_proc_reset();
462 ret = ksmbd_conn_transport_init();
463 if (ret) {
464 server_queue_ctrl_reset_work();
465 return;
466 }
467
468 pr_info("running\n");
469 WRITE_ONCE(server_conf.state, SERVER_STATE_RUNNING);
470}
471
472static void server_ctrl_handle_reset(struct server_ctrl_struct *ctrl)
473{
474 ksmbd_ipc_soft_reset();
475 ksmbd_conn_transport_destroy();
476 ksmbd_stop_durable_scavenger();
477 server_conf_free();
478 server_conf_init();
479 WRITE_ONCE(server_conf.state, SERVER_STATE_STARTING_UP);
480}
481
482static void server_ctrl_handle_work(struct work_struct *work)
483{
484 struct server_ctrl_struct *ctrl;
485
486 ctrl = container_of(work, struct server_ctrl_struct, ctrl_work);
487
488 mutex_lock(&ctrl_lock);
489 switch (ctrl->type) {
490 case SERVER_CTRL_TYPE_INIT:
491 server_ctrl_handle_init(ctrl);
492 break;
493 case SERVER_CTRL_TYPE_RESET:
494 server_ctrl_handle_reset(ctrl);
495 break;
496 default:
497 pr_err("Unknown server work type: %d\n", ctrl->type);
498 }
499 mutex_unlock(&ctrl_lock);
500 kfree(ctrl);
501 module_put(THIS_MODULE);
502}
503
504static int __queue_ctrl_work(int type)
505{
506 struct server_ctrl_struct *ctrl;
507
508 ctrl = kmalloc_obj(struct server_ctrl_struct, KSMBD_DEFAULT_GFP);
509 if (!ctrl)
510 return -ENOMEM;
511
512 __module_get(THIS_MODULE);
513 ctrl->type = type;
514 INIT_WORK(&ctrl->ctrl_work, server_ctrl_handle_work);
515 queue_work(system_long_wq, &ctrl->ctrl_work);
516 return 0;
517}
518
519int server_queue_ctrl_init_work(void)
520{
521 return __queue_ctrl_work(SERVER_CTRL_TYPE_INIT);
522}
523
524int server_queue_ctrl_reset_work(void)
525{
526 return __queue_ctrl_work(SERVER_CTRL_TYPE_RESET);
527}
528
529static ssize_t stats_show(const struct class *class, const struct class_attribute *attr,
530 char *buf)
531{
532 /*
533 * Inc this each time you change stats output format,
534 * so user space will know what to do.
535 */
536 static int stats_version = 2;
537 static const char * const state[] = {
538 "startup",
539 "running",
540 "reset",
541 "shutdown"
542 };
543 return sysfs_emit(buf, "%d %s %d %lu\n", stats_version,
544 state[server_conf.state], server_conf.tcp_port,
545 server_conf.ipc_last_active / HZ);
546}
547
548static ssize_t kill_server_store(const struct class *class,
549 const struct class_attribute *attr, const char *buf,
550 size_t len)
551{
552 if (!sysfs_streq(buf, "hard"))
553 return len;
554
555 pr_info("kill command received\n");
556 mutex_lock(&ctrl_lock);
557 WRITE_ONCE(server_conf.state, SERVER_STATE_RESETTING);
558 __module_get(THIS_MODULE);
559 server_ctrl_handle_reset(NULL);
560 module_put(THIS_MODULE);
561 mutex_unlock(&ctrl_lock);
562 return len;
563}
564
565static const char * const debug_type_strings[] = {"smb", "auth", "vfs",
566 "oplock", "ipc", "conn",
567 "rdma"};
568
569static ssize_t debug_show(const struct class *class, const struct class_attribute *attr,
570 char *buf)
571{
572 ssize_t sz = 0;
573 int i, pos = 0;
574
575 for (i = 0; i < ARRAY_SIZE(debug_type_strings); i++) {
576 if ((ksmbd_debug_types >> i) & 1) {
577 pos = sysfs_emit_at(buf, sz, "[%s] ", debug_type_strings[i]);
578 } else {
579 pos = sysfs_emit_at(buf, sz, "%s ", debug_type_strings[i]);
580 }
581 sz += pos;
582 }
583 sz += sysfs_emit_at(buf, sz, "\n");
584 return sz;
585}
586
587static ssize_t debug_store(const struct class *class, const struct class_attribute *attr,
588 const char *buf, size_t len)
589{
590 int i;
591
592 for (i = 0; i < ARRAY_SIZE(debug_type_strings); i++) {
593 if (sysfs_streq(buf, "all")) {
594 if (ksmbd_debug_types == KSMBD_DEBUG_ALL)
595 ksmbd_debug_types = 0;
596 else
597 ksmbd_debug_types = KSMBD_DEBUG_ALL;
598 break;
599 }
600
601 if (sysfs_streq(buf, debug_type_strings[i])) {
602 if (ksmbd_debug_types & (1 << i))
603 ksmbd_debug_types &= ~(1 << i);
604 else
605 ksmbd_debug_types |= (1 << i);
606 break;
607 }
608 }
609
610 return len;
611}
612
613static CLASS_ATTR_RO(stats);
614static CLASS_ATTR_WO(kill_server);
615static CLASS_ATTR_RW(debug);
616
617static struct attribute *ksmbd_control_class_attrs[] = {
618 &class_attr_stats.attr,
619 &class_attr_kill_server.attr,
620 &class_attr_debug.attr,
621 NULL,
622};
623ATTRIBUTE_GROUPS(ksmbd_control_class);
624
625static struct class ksmbd_control_class = {
626 .name = "ksmbd-control",
627 .class_groups = ksmbd_control_class_groups,
628};
629
630static int ksmbd_server_shutdown(void)
631{
632 WRITE_ONCE(server_conf.state, SERVER_STATE_SHUTTING_DOWN);
633
634 class_unregister(&ksmbd_control_class);
635 ksmbd_workqueue_destroy();
636 ksmbd_ipc_release();
637 ksmbd_conn_transport_destroy();
638 /*
639 * ksmbd_conn_transport_destroy() calls delete_proc_clients() and destroys
640 * sessions. ksmbd_session_destroy() removes each session's proc entry.
641 * Keep the procfs tree alive until these entries have been removed.
642 */
643 ksmbd_proc_cleanup();
644 ksmbd_crypto_destroy();
645 ksmbd_free_global_file_table();
646 destroy_lease_table(NULL);
647 ksmbd_work_pool_destroy();
648 ksmbd_exit_file_cache();
649 server_conf_free();
650 return 0;
651}
652
653static int __init ksmbd_server_init(void)
654{
655 int ret;
656
657 ret = class_register(&ksmbd_control_class);
658 if (ret) {
659 pr_err("Unable to register ksmbd-control class\n");
660 return ret;
661 }
662
663 ret = ksmbd_proc_init();
664 if (ret)
665 goto err_unregister;
666
667 if (create_proc_sessions())
668 pr_warn("Unable to create sessions procfs entry\n");
669
670 if (create_proc_shares())
671 pr_warn("Unable to create shares procfs entry\n");
672
673 ksmbd_server_tcp_callbacks_init();
674
675 ret = server_conf_init();
676 if (ret)
677 goto err_proc_cleanup;
678
679 ret = ksmbd_work_pool_init();
680 if (ret)
681 goto err_proc_cleanup;
682
683 ret = ksmbd_init_file_cache();
684 if (ret)
685 goto err_destroy_work_pools;
686
687 ret = ksmbd_ipc_init();
688 if (ret)
689 goto err_exit_file_cache;
690
691 ret = ksmbd_init_global_file_table();
692 if (ret)
693 goto err_ipc_release;
694
695 ret = ksmbd_inode_hash_init();
696 if (ret)
697 goto err_destroy_file_table;
698
699 ret = ksmbd_crypto_create();
700 if (ret)
701 goto err_release_inode_hash;
702
703 ret = ksmbd_workqueue_init();
704 if (ret)
705 goto err_crypto_destroy;
706
707 ret = ksmbd_conn_wq_init();
708 if (ret)
709 goto err_workqueue_destroy;
710
711 return 0;
712
713err_workqueue_destroy:
714 ksmbd_workqueue_destroy();
715err_crypto_destroy:
716 ksmbd_crypto_destroy();
717err_release_inode_hash:
718 ksmbd_release_inode_hash();
719err_destroy_file_table:
720 ksmbd_free_global_file_table();
721err_ipc_release:
722 ksmbd_ipc_release();
723err_exit_file_cache:
724 ksmbd_exit_file_cache();
725err_destroy_work_pools:
726 ksmbd_work_pool_destroy();
727err_proc_cleanup:
728 ksmbd_proc_cleanup();
729err_unregister:
730 class_unregister(&ksmbd_control_class);
731
732 return ret;
733}
734
735/**
736 * ksmbd_server_exit() - shutdown forker thread and free memory at module exit
737 */
738static void __exit ksmbd_server_exit(void)
739{
740 ksmbd_server_shutdown();
741 rcu_barrier();
742 /*
743 * ksmbd_conn_put() defers the final release onto ksmbd_conn_wq,
744 * so drain it after rcu_barrier() has fired any pending RCU
745 * callbacks that may have queued a release.
746 */
747 ksmbd_conn_wq_destroy();
748 ksmbd_release_inode_hash();
749}
750
751MODULE_AUTHOR("Namjae Jeon <[email protected]>");
752MODULE_DESCRIPTION("Linux kernel CIFS/SMB SERVER");
753MODULE_LICENSE("GPL");
754MODULE_SOFTDEP("pre: nls");
755MODULE_SOFTDEP("pre: aes");
756MODULE_SOFTDEP("pre: aead2");
757MODULE_SOFTDEP("pre: ccm");
758MODULE_SOFTDEP("pre: gcm");
759module_init(ksmbd_server_init)
760module_exit(ksmbd_server_exit)