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