xref: /linux/fs/smb/server/mgmt/user_session.c (revision 50a400cff59f534254ace2828f2eb9d844517fbb)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
4  */
5 
6 #include <linux/list.h>
7 #include <linux/slab.h>
8 #include <linux/rwsem.h>
9 #include <linux/xarray.h>
10 
11 #include "ksmbd_ida.h"
12 #include "user_session.h"
13 #include "user_config.h"
14 #include "tree_connect.h"
15 #include "share_config.h"
16 #include "../transport_ipc.h"
17 #include "../connection.h"
18 #include "../vfs_cache.h"
19 #include "../misc.h"
20 #include "../stats.h"
21 
22 static DEFINE_IDA(session_ida);
23 
24 #define SESSION_HASH_BITS		12
25 static DEFINE_HASHTABLE(sessions_table, SESSION_HASH_BITS);
26 static DECLARE_RWSEM(sessions_table_lock);
27 
28 struct ksmbd_session_rpc {
29 	int			id;
30 	unsigned int		method;
31 };
32 
33 #ifdef CONFIG_PROC_FS
34 
35 static const struct ksmbd_const_name ksmbd_sess_cap_const_names[] = {
36 	{SMB2_GLOBAL_CAP_DFS, "dfs"},
37 	{SMB2_GLOBAL_CAP_LEASING, "lease"},
38 	{SMB2_GLOBAL_CAP_LARGE_MTU, "large-mtu"},
39 	{SMB2_GLOBAL_CAP_MULTI_CHANNEL, "multi-channel"},
40 	{SMB2_GLOBAL_CAP_PERSISTENT_HANDLES, "persistent-handles"},
41 	{SMB2_GLOBAL_CAP_DIRECTORY_LEASING, "dir-lease"},
42 	{SMB2_GLOBAL_CAP_ENCRYPTION, "encryption"}
43 };
44 
45 static const struct ksmbd_const_name ksmbd_cipher_const_names[] = {
46 	{le16_to_cpu(SMB2_ENCRYPTION_AES128_CCM), "aes128-ccm"},
47 	{le16_to_cpu(SMB2_ENCRYPTION_AES128_GCM), "aes128-gcm"},
48 	{le16_to_cpu(SMB2_ENCRYPTION_AES256_CCM), "aes256-ccm"},
49 	{le16_to_cpu(SMB2_ENCRYPTION_AES256_GCM), "aes256-gcm"},
50 };
51 
52 static const struct ksmbd_const_name ksmbd_signing_const_names[] = {
53 	{SIGNING_ALG_HMAC_SHA256, "hmac-sha256"},
54 	{SIGNING_ALG_AES_CMAC, "aes-cmac"},
55 	{SIGNING_ALG_AES_GMAC, "aes-gmac"},
56 };
57 
58 static const char *session_state_string(struct ksmbd_session *session)
59 {
60 	switch (session->state) {
61 	case SMB2_SESSION_VALID:
62 		return "valid";
63 	case SMB2_SESSION_IN_PROGRESS:
64 		return "progress";
65 	case SMB2_SESSION_EXPIRED:
66 		return "expired";
67 	default:
68 		return "";
69 	}
70 }
71 
72 static const char *session_user_name(struct ksmbd_session *session)
73 {
74 	if (user_guest(session->user))
75 		return "(Guest)";
76 	else if (ksmbd_anonymous_user(session->user))
77 		return "(Anonymous)";
78 	return session->user->name;
79 }
80 
81 static const char *session_account_type(struct ksmbd_session *session)
82 {
83 	if (user_guest(session->user))
84 		return "guest";
85 	if (ksmbd_anonymous_user(session->user))
86 		return "anonymous";
87 	return "user";
88 }
89 
90 static unsigned int session_open_file_count(struct ksmbd_session *session)
91 {
92 	struct ksmbd_file *fp;
93 	unsigned int count = 0;
94 	unsigned int id;
95 
96 	read_lock(&session->file_table.lock);
97 	idr_for_each_entry(session->file_table.idr, fp, id)
98 		count++;
99 	read_unlock(&session->file_table.lock);
100 	return count;
101 }
102 
103 static int show_proc_session(struct seq_file *m, void *v)
104 {
105 	struct ksmbd_session *sess;
106 	struct ksmbd_tree_connect *tree_conn;
107 	struct ksmbd_share_config *share_conf;
108 	struct channel *chan;
109 	unsigned long id;
110 	int i = 0;
111 
112 	sess = (struct ksmbd_session *)m->private;
113 	ksmbd_user_session_get(sess);
114 
115 	seq_printf(m, "user:\t%s\n", session_user_name(sess));
116 	seq_printf(m, "account_type:\t%s\n",
117 		   session_account_type(sess));
118 	seq_printf(m, "id:\t%llu\n", sess->id);
119 	seq_printf(m, "state:\t%s\n", session_state_string(sess));
120 	seq_printf(m, "dialect:\t0x%04x\n", sess->dialect);
121 	seq_printf(m, "last_active_seconds:\t%lu\n",
122 		   jiffies_to_msecs(jiffies - sess->last_active) / MSEC_PER_SEC);
123 	seq_printf(m, "open_files:\t%u\n",
124 		   session_open_file_count(sess));
125 
126 	i = 0;
127 	down_read(&sess->chann_lock);
128 	xa_for_each(&sess->ksmbd_chann_list, id, chan) {
129 		const char *name;
130 
131 #if IS_ENABLED(CONFIG_IPV6)
132 		if (chan->conn->inet_addr)
133 			seq_printf(m, "client:\t%pI4\n",
134 					&chan->conn->inet_addr);
135 		else
136 			seq_printf(m, "client:\t%pI6c\n",
137 					&chan->conn->inet6_addr);
138 #else
139 		seq_printf(m, "client:\t%pI4\n",
140 				&chan->conn->inet_addr);
141 #endif
142 		seq_puts(m, "capabilities:\t");
143 		ksmbd_proc_show_flag_names(m,
144 				ksmbd_sess_cap_const_names,
145 				ARRAY_SIZE(ksmbd_sess_cap_const_names),
146 				chan->conn->vals->req_capabilities);
147 		seq_putc(m, '\n');
148 		seq_printf(m, "posix_extensions:\t%s\n",
149 			   chan->conn->posix_ext_supported ? "yes" : "no");
150 
151 		if (sess->sign) {
152 			unsigned int algorithm =
153 				le16_to_cpu(chan->conn->signing_algorithm);
154 
155 			name = ksmbd_proc_const_name(ksmbd_signing_const_names,
156 						     ARRAY_SIZE(ksmbd_signing_const_names),
157 						     algorithm);
158 			if (name)
159 				seq_printf(m, "signing:\t%s\n", name);
160 			else
161 				seq_printf(m, "signing:\t0x%04x\n",
162 					   algorithm);
163 		}
164 		if (sess->enc) {
165 			unsigned int cipher = le16_to_cpu(chan->conn->cipher_type);
166 
167 			name = ksmbd_proc_const_name(ksmbd_cipher_const_names,
168 						     ARRAY_SIZE(ksmbd_cipher_const_names),
169 						     cipher);
170 			if (name)
171 				seq_printf(m, "encryption:\t%s\n", name);
172 			else
173 				seq_printf(m, "encryption:\t0x%04x\n",
174 					   cipher);
175 		}
176 		i++;
177 	}
178 	up_read(&sess->chann_lock);
179 
180 	seq_printf(m, "channels:\t%d\n", i);
181 
182 	i = 0;
183 	down_read(&sess->tree_conns_lock);
184 	xa_for_each(&sess->tree_conns, id, tree_conn) {
185 		share_conf = tree_conn->share_conf;
186 		seq_printf(m, "share:\t%s\n", share_conf->name);
187 		seq_printf(m, "tree_id:\t%d\n", tree_conn->id);
188 		seq_printf(m, "share_type:\t%s\n",
189 			   test_share_config_flag(share_conf, KSMBD_SHARE_FLAG_PIPE) ?
190 			   "pipe" : "disk");
191 		i++;
192 	}
193 	up_read(&sess->tree_conns_lock);
194 	seq_printf(m, "tree_connects:\t%d\n", i);
195 
196 	ksmbd_user_session_put(sess);
197 	return 0;
198 }
199 
200 static int create_proc_session(struct ksmbd_session *sess)
201 {
202 	char name[30];
203 
204 	snprintf(name, sizeof(name), "sessions/%llu", sess->id);
205 	sess->proc_entry = ksmbd_proc_create(name,
206 					     show_proc_session, sess);
207 	return 0;
208 }
209 
210 static void delete_proc_session(struct ksmbd_session *sess)
211 {
212 	if (sess->proc_entry)
213 		proc_remove(sess->proc_entry);
214 }
215 
216 static int show_proc_sessions(struct seq_file *m, void *v)
217 {
218 	struct ksmbd_session *session;
219 	struct channel *chan;
220 	int i;
221 	unsigned long id;
222 
223 	down_read(&sessions_table_lock);
224 	hash_for_each(sessions_table, i, session, hlist) {
225 		down_read(&session->chann_lock);
226 		xa_for_each(&session->ksmbd_chann_list, id, chan) {
227 			down_read(&chan->conn->session_lock);
228 			ksmbd_user_session_get(session);
229 
230 #if IS_ENABLED(CONFIG_IPV6)
231 			if (!chan->conn->inet_addr)
232 				seq_printf(m, "client:\t%pI6c\n", &chan->conn->inet6_addr);
233 			else
234 #endif
235 				seq_printf(m, "client:\t%pI4\n", &chan->conn->inet_addr);
236 			seq_printf(m, "user:\t%s\n", session_user_name(session));
237 			seq_printf(m, "id:\t%llu\n", session->id);
238 			seq_printf(m, "state:\t%s\n\n",
239 				   session_state_string(session));
240 
241 			ksmbd_user_session_put(session);
242 			up_read(&chan->conn->session_lock);
243 		}
244 		up_read(&session->chann_lock);
245 	}
246 	up_read(&sessions_table_lock);
247 	return 0;
248 }
249 
250 int create_proc_sessions(void)
251 {
252 	if (!ksmbd_proc_create("sessions/sessions",
253 			       show_proc_sessions, NULL))
254 		return -ENOMEM;
255 	return 0;
256 }
257 #else
258 int create_proc_sessions(void) { return 0; }
259 static int create_proc_session(struct ksmbd_session *sess) { return 0; }
260 static void delete_proc_session(struct ksmbd_session *sess) {}
261 #endif
262 
263 static void free_channel_list(struct ksmbd_session *sess)
264 {
265 	struct channel *chann;
266 	unsigned long index;
267 
268 	down_write(&sess->chann_lock);
269 	xa_for_each(&sess->ksmbd_chann_list, index, chann) {
270 		xa_erase(&sess->ksmbd_chann_list, index);
271 		kfree_sensitive(chann);
272 	}
273 
274 	xa_destroy(&sess->ksmbd_chann_list);
275 	up_write(&sess->chann_lock);
276 }
277 
278 static void __session_rpc_close(struct ksmbd_session *sess,
279 				struct ksmbd_session_rpc *entry)
280 {
281 	struct ksmbd_rpc_command *resp;
282 
283 	resp = ksmbd_rpc_close(sess, entry->id);
284 	if (!resp)
285 		pr_err("Unable to close RPC pipe %d\n", entry->id);
286 
287 	kvfree(resp);
288 	ksmbd_rpc_id_free(entry->id);
289 	kfree(entry);
290 }
291 
292 static void ksmbd_session_rpc_clear_list(struct ksmbd_session *sess)
293 {
294 	struct ksmbd_session_rpc *entry;
295 	long index;
296 
297 	down_write(&sess->rpc_lock);
298 	xa_for_each(&sess->rpc_handle_list, index, entry) {
299 		xa_erase(&sess->rpc_handle_list, index);
300 		__session_rpc_close(sess, entry);
301 	}
302 	up_write(&sess->rpc_lock);
303 
304 	xa_destroy(&sess->rpc_handle_list);
305 }
306 
307 static int __rpc_method(char *rpc_name)
308 {
309 	if (!strcmp(rpc_name, "\\srvsvc") || !strcmp(rpc_name, "srvsvc"))
310 		return KSMBD_RPC_SRVSVC_METHOD_INVOKE;
311 
312 	if (!strcmp(rpc_name, "\\wkssvc") || !strcmp(rpc_name, "wkssvc"))
313 		return KSMBD_RPC_WKSSVC_METHOD_INVOKE;
314 
315 	if (!strcmp(rpc_name, "LANMAN") || !strcmp(rpc_name, "lanman"))
316 		return KSMBD_RPC_RAP_METHOD;
317 
318 	if (!strcmp(rpc_name, "\\samr") || !strcmp(rpc_name, "samr"))
319 		return KSMBD_RPC_SAMR_METHOD_INVOKE;
320 
321 	if (!strcmp(rpc_name, "\\lsarpc") || !strcmp(rpc_name, "lsarpc"))
322 		return KSMBD_RPC_LSARPC_METHOD_INVOKE;
323 
324 	if (!strcmp(rpc_name, "\\mdssvc") || !strcmp(rpc_name, "mdssvc"))
325 		return -ENOENT;
326 
327 	pr_err("Unsupported RPC: %s\n", rpc_name);
328 	return -ENOENT;
329 }
330 
331 int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name)
332 {
333 	struct ksmbd_session_rpc *entry, *old;
334 	struct ksmbd_rpc_command *resp;
335 	int method, id;
336 
337 	method = __rpc_method(rpc_name);
338 	if (method < 0)
339 		return method;
340 
341 	entry = kzalloc_obj(struct ksmbd_session_rpc, KSMBD_DEFAULT_GFP);
342 	if (!entry)
343 		return -ENOMEM;
344 
345 	entry->method = method;
346 	entry->id = id = ksmbd_ipc_id_alloc();
347 	if (id < 0)
348 		goto free_entry;
349 
350 	down_write(&sess->rpc_lock);
351 	old = xa_store(&sess->rpc_handle_list, id, entry, KSMBD_DEFAULT_GFP);
352 	if (xa_is_err(old)) {
353 		up_write(&sess->rpc_lock);
354 		goto free_id;
355 	}
356 
357 	resp = ksmbd_rpc_open(sess, id);
358 	if (!resp) {
359 		xa_erase(&sess->rpc_handle_list, entry->id);
360 		up_write(&sess->rpc_lock);
361 		goto free_id;
362 	}
363 
364 	up_write(&sess->rpc_lock);
365 	kvfree(resp);
366 	return id;
367 free_id:
368 	ksmbd_rpc_id_free(entry->id);
369 free_entry:
370 	kfree(entry);
371 	return -EINVAL;
372 }
373 
374 void ksmbd_session_rpc_close(struct ksmbd_session *sess, int id)
375 {
376 	struct ksmbd_session_rpc *entry;
377 
378 	down_write(&sess->rpc_lock);
379 	entry = xa_erase(&sess->rpc_handle_list, id);
380 	if (entry)
381 		__session_rpc_close(sess, entry);
382 	up_write(&sess->rpc_lock);
383 }
384 
385 int ksmbd_session_rpc_method(struct ksmbd_session *sess, int id)
386 {
387 	struct ksmbd_session_rpc *entry;
388 
389 	lockdep_assert_held(&sess->rpc_lock);
390 	entry = xa_load(&sess->rpc_handle_list, id);
391 
392 	return entry ? entry->method : 0;
393 }
394 
395 void ksmbd_session_destroy(struct ksmbd_session *sess)
396 {
397 	if (!sess)
398 		return;
399 
400 	delete_proc_session(sess);
401 	ksmbd_tree_conn_session_logoff(sess);
402 	ksmbd_destroy_file_table(sess);
403 	if (sess->user)
404 		ksmbd_free_user(sess->user);
405 	ksmbd_launch_ksmbd_durable_scavenger();
406 	ksmbd_session_rpc_clear_list(sess);
407 	free_channel_list(sess);
408 	kfree_sensitive(sess->Preauth_HashValue);
409 	ksmbd_release_id(&session_ida, sess->id);
410 	ida_destroy(&sess->tree_conn_ida);
411 	kfree_sensitive(sess);
412 }
413 
414 struct ksmbd_session *__session_lookup(unsigned long long id)
415 {
416 	struct ksmbd_session *sess;
417 
418 	hash_for_each_possible(sessions_table, sess, hlist, id) {
419 		if (id == sess->id) {
420 			sess->last_active = jiffies;
421 			return sess;
422 		}
423 	}
424 	return NULL;
425 }
426 
427 static void ksmbd_expire_session(struct ksmbd_conn *conn)
428 {
429 	unsigned long id;
430 	struct ksmbd_session *sess;
431 
432 	down_write(&sessions_table_lock);
433 	down_write(&conn->session_lock);
434 	xa_for_each(&conn->sessions, id, sess) {
435 		if (atomic_read(&sess->refcnt) <= 1 &&
436 		    (sess->state != SMB2_SESSION_VALID ||
437 		     time_after(jiffies,
438 			       sess->last_active + SMB2_SESSION_TIMEOUT))) {
439 			xa_erase(&conn->sessions, sess->id);
440 			hash_del(&sess->hlist);
441 			ksmbd_session_destroy(sess);
442 			continue;
443 		}
444 	}
445 	up_write(&conn->session_lock);
446 	up_write(&sessions_table_lock);
447 }
448 
449 int ksmbd_session_register(struct ksmbd_conn *conn,
450 			   struct ksmbd_session *sess)
451 {
452 	sess->dialect = conn->dialect;
453 	memcpy(sess->ClientGUID, conn->ClientGUID, SMB2_CLIENT_GUID_SIZE);
454 	ksmbd_expire_session(conn);
455 	return xa_err(xa_store(&conn->sessions, sess->id, sess, KSMBD_DEFAULT_GFP));
456 }
457 
458 static int ksmbd_chann_del(struct ksmbd_conn *conn, struct ksmbd_session *sess)
459 {
460 	struct channel *chann;
461 
462 	down_write(&sess->chann_lock);
463 	chann = xa_erase(&sess->ksmbd_chann_list, (long)conn);
464 	up_write(&sess->chann_lock);
465 	if (!chann)
466 		return -ENOENT;
467 
468 	kfree_sensitive(chann);
469 	return 0;
470 }
471 
472 void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
473 {
474 	struct ksmbd_session *sess;
475 	unsigned long id;
476 	struct hlist_node *tmp;
477 	int bkt;
478 
479 	down_write(&sessions_table_lock);
480 	hash_for_each_safe(sessions_table, bkt, tmp, sess, hlist) {
481 		if (!ksmbd_chann_del(conn, sess) &&
482 		    xa_empty(&sess->ksmbd_chann_list)) {
483 			hash_del(&sess->hlist);
484 			down_write(&conn->session_lock);
485 			xa_erase(&conn->sessions, sess->id);
486 			up_write(&conn->session_lock);
487 			if (atomic_dec_and_test(&sess->refcnt))
488 				ksmbd_session_destroy(sess);
489 		}
490 	}
491 
492 	down_write(&conn->session_lock);
493 	xa_for_each(&conn->sessions, id, sess) {
494 		ksmbd_chann_del(conn, sess);
495 		if (xa_empty(&sess->ksmbd_chann_list)) {
496 			xa_erase(&conn->sessions, sess->id);
497 			hash_del(&sess->hlist);
498 			if (atomic_dec_and_test(&sess->refcnt))
499 				ksmbd_session_destroy(sess);
500 		}
501 	}
502 	up_write(&conn->session_lock);
503 	up_write(&sessions_table_lock);
504 }
505 
506 bool is_ksmbd_session_in_connection(struct ksmbd_conn *conn,
507 				   unsigned long long id)
508 {
509 	struct ksmbd_session *sess;
510 
511 	down_read(&conn->session_lock);
512 	sess = xa_load(&conn->sessions, id);
513 	if (sess) {
514 		up_read(&conn->session_lock);
515 		return true;
516 	}
517 	up_read(&conn->session_lock);
518 
519 	return false;
520 }
521 
522 struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
523 					   unsigned long long id)
524 {
525 	struct ksmbd_session *sess;
526 
527 	down_read(&conn->session_lock);
528 	sess = xa_load(&conn->sessions, id);
529 	if (sess) {
530 		sess->last_active = jiffies;
531 		ksmbd_user_session_get(sess);
532 	}
533 	up_read(&conn->session_lock);
534 	return sess;
535 }
536 
537 struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id)
538 {
539 	struct ksmbd_session *sess;
540 
541 	down_read(&sessions_table_lock);
542 	sess = __session_lookup(id);
543 	if (sess)
544 		ksmbd_user_session_get(sess);
545 	up_read(&sessions_table_lock);
546 
547 	return sess;
548 }
549 
550 struct ksmbd_session *ksmbd_session_lookup_all_states(struct ksmbd_conn *conn,
551 						      unsigned long long id)
552 {
553 	struct ksmbd_session *sess;
554 
555 	sess = ksmbd_session_lookup(conn, id);
556 	if (!sess && conn->binding) {
557 		sess = ksmbd_session_lookup_slowpath(id);
558 		if (sess && !xa_load(&sess->ksmbd_chann_list, (long)conn)) {
559 			ksmbd_user_session_put(sess);
560 			sess = NULL;
561 		}
562 	}
563 	return sess;
564 }
565 
566 struct ksmbd_session *ksmbd_session_lookup_all(struct ksmbd_conn *conn,
567 					       unsigned long long id)
568 {
569 	struct ksmbd_session *sess;
570 
571 	sess = ksmbd_session_lookup_all_states(conn, id);
572 	if (sess && sess->state != SMB2_SESSION_VALID) {
573 		ksmbd_user_session_put(sess);
574 		sess = NULL;
575 	}
576 	return sess;
577 }
578 
579 void ksmbd_user_session_get(struct ksmbd_session *sess)
580 {
581 	atomic_inc(&sess->refcnt);
582 }
583 
584 void ksmbd_user_session_put(struct ksmbd_session *sess)
585 {
586 	if (!sess)
587 		return;
588 
589 	if (atomic_read(&sess->refcnt) <= 0)
590 		WARN_ON(1);
591 	else if (atomic_dec_and_test(&sess->refcnt))
592 		ksmbd_session_destroy(sess);
593 }
594 
595 struct preauth_session *ksmbd_preauth_session_alloc(struct ksmbd_conn *conn,
596 						    u64 sess_id)
597 {
598 	struct preauth_session *sess;
599 
600 	sess = kmalloc_obj(struct preauth_session, KSMBD_DEFAULT_GFP);
601 	if (!sess)
602 		return NULL;
603 
604 	sess->id = sess_id;
605 	memcpy(sess->Preauth_HashValue, conn->preauth_info->Preauth_HashValue,
606 	       PREAUTH_HASHVALUE_SIZE);
607 	list_add(&sess->preauth_entry, &conn->preauth_sess_table);
608 
609 	return sess;
610 }
611 
612 void ksmbd_preauth_session_destroy(struct ksmbd_conn *conn)
613 {
614 	struct preauth_session *sess, *tmp;
615 
616 	list_for_each_entry_safe(sess, tmp, &conn->preauth_sess_table,
617 				 preauth_entry) {
618 		list_del(&sess->preauth_entry);
619 		kfree(sess);
620 	}
621 }
622 
623 void destroy_previous_session(struct ksmbd_conn *conn,
624 			      struct ksmbd_user *user, u64 id)
625 {
626 	struct ksmbd_session *prev_sess;
627 	struct ksmbd_user *prev_user;
628 	int err;
629 
630 	down_write(&sessions_table_lock);
631 	down_write(&conn->session_lock);
632 	prev_sess = __session_lookup(id);
633 	if (!prev_sess || prev_sess->state == SMB2_SESSION_EXPIRED)
634 		goto out;
635 
636 	prev_user = prev_sess->user;
637 	if (!prev_user ||
638 	    strcmp(user->name, prev_user->name) ||
639 	    user->passkey_sz != prev_user->passkey_sz ||
640 	    memcmp(user->passkey, prev_user->passkey, user->passkey_sz))
641 		goto out;
642 
643 	ksmbd_all_conn_set_status(id, KSMBD_SESS_NEED_RECONNECT);
644 	err = ksmbd_conn_wait_idle_sess_id(conn, id);
645 	if (err) {
646 		ksmbd_all_conn_set_status(id, KSMBD_SESS_NEED_SETUP);
647 		goto out;
648 	}
649 
650 	ksmbd_destroy_file_table(prev_sess);
651 	prev_sess->kerberos_expiry = 0;
652 	prev_sess->state = SMB2_SESSION_EXPIRED;
653 	ksmbd_all_conn_set_status(id, KSMBD_SESS_NEED_SETUP);
654 	ksmbd_launch_ksmbd_durable_scavenger();
655 out:
656 	up_write(&conn->session_lock);
657 	up_write(&sessions_table_lock);
658 }
659 
660 static bool ksmbd_preauth_session_id_match(struct preauth_session *sess,
661 					   unsigned long long id)
662 {
663 	return sess->id == id;
664 }
665 
666 struct preauth_session *ksmbd_preauth_session_lookup(struct ksmbd_conn *conn,
667 						     unsigned long long id)
668 {
669 	struct preauth_session *sess = NULL;
670 
671 	list_for_each_entry(sess, &conn->preauth_sess_table, preauth_entry) {
672 		if (ksmbd_preauth_session_id_match(sess, id))
673 			return sess;
674 	}
675 	return NULL;
676 }
677 
678 static int __init_smb2_session(struct ksmbd_session *sess)
679 {
680 	int id = ksmbd_acquire_smb2_uid(&session_ida);
681 
682 	if (id < 0)
683 		return -EINVAL;
684 	sess->id = id;
685 	return 0;
686 }
687 
688 static struct ksmbd_session *__session_create(int protocol)
689 {
690 	struct ksmbd_session *sess;
691 	int ret;
692 
693 	if (protocol != CIFDS_SESSION_FLAG_SMB2)
694 		return NULL;
695 
696 	sess = kzalloc_obj(struct ksmbd_session, KSMBD_DEFAULT_GFP);
697 	if (!sess)
698 		return NULL;
699 
700 	ida_init(&sess->tree_conn_ida);
701 
702 	if (ksmbd_init_file_table(&sess->file_table))
703 		goto error;
704 
705 	sess->last_active = jiffies;
706 	sess->state = SMB2_SESSION_IN_PROGRESS;
707 	set_session_flag(sess, protocol);
708 	xa_init(&sess->tree_conns);
709 	xa_init(&sess->ksmbd_chann_list);
710 	xa_init(&sess->rpc_handle_list);
711 	sess->sequence_number = 1;
712 	atomic_set(&sess->refcnt, 2);
713 	init_rwsem(&sess->tree_conns_lock);
714 	init_rwsem(&sess->rpc_lock);
715 	init_rwsem(&sess->chann_lock);
716 
717 	ret = __init_smb2_session(sess);
718 	if (ret)
719 		goto error;
720 
721 	down_write(&sessions_table_lock);
722 	hash_add(sessions_table, &sess->hlist, sess->id);
723 	up_write(&sessions_table_lock);
724 
725 	create_proc_session(sess);
726 	ksmbd_counter_inc(KSMBD_COUNTER_SESSIONS);
727 	return sess;
728 
729 error:
730 	ksmbd_session_destroy(sess);
731 	return NULL;
732 }
733 
734 struct ksmbd_session *ksmbd_smb2_session_create(void)
735 {
736 	return __session_create(CIFDS_SESSION_FLAG_SMB2);
737 }
738 
739 int ksmbd_acquire_tree_conn_id(struct ksmbd_session *sess)
740 {
741 	int id = -EINVAL;
742 
743 	if (test_session_flag(sess, CIFDS_SESSION_FLAG_SMB2))
744 		id = ksmbd_acquire_smb2_tid(&sess->tree_conn_ida);
745 
746 	return id;
747 }
748 
749 void ksmbd_release_tree_conn_id(struct ksmbd_session *sess, int id)
750 {
751 	if (id >= 0)
752 		ksmbd_release_id(&sess->tree_conn_ida, id);
753 }
754