1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 23 * Copyright 2016 Nexenta Systems, Inc. All rights reserved. 24 * Copyright (c) 2017 by Delphix. All rights reserved. 25 */ 26 27 /* 28 * General Structures Layout 29 * ------------------------- 30 * 31 * This is a simplified diagram showing the relationship between most of the 32 * main structures. 33 * 34 * +-------------------+ 35 * | SMB_SERVER | 36 * +-------------------+ 37 * | 38 * | 39 * v 40 * +-------------------+ +-------------------+ +-------------------+ 41 * | SESSION |<----->| SESSION |......| SESSION | 42 * +-------------------+ +-------------------+ +-------------------+ 43 * | 44 * | 45 * v 46 * +-------------------+ +-------------------+ +-------------------+ 47 * | USER |<----->| USER |......| USER | 48 * +-------------------+ +-------------------+ +-------------------+ 49 * | 50 * | 51 * v 52 * +-------------------+ +-------------------+ +-------------------+ 53 * | TREE |<----->| TREE |......| TREE | 54 * +-------------------+ +-------------------+ +-------------------+ 55 * | | 56 * | | 57 * | v 58 * | +-------+ +-------+ +-------+ 59 * | | OFILE |<----->| OFILE |......| OFILE | 60 * | +-------+ +-------+ +-------+ 61 * | 62 * | 63 * v 64 * +-------+ +------+ +------+ 65 * | ODIR |<----->| ODIR |......| ODIR | 66 * +-------+ +------+ +------+ 67 * 68 * 69 * Module Interface Overview 70 * ------------------------- 71 * 72 * 73 * +===================================+ 74 * | smbd daemon | 75 * +===================================+ 76 * | | ^ 77 * | | | 78 * User | | | 79 * -----------|--------------|----------------|-------------------------------- 80 * Kernel | | | 81 * | | | 82 * | | | 83 * +=========|==============|================|=================+ 84 * | v v | | 85 * | +-----------+ +--------------------+ +------------------+ | 86 * | | IO | | Kernel Door Server | | User Door Servers| | 87 * | | Interface | | Interface | | Interface | | 88 * | +-----------+ +--------------------+ +------------------+ | 89 * | | | ^ ^ | 90 * | v v | | | +=========+ 91 * | +-----------------------------------+ | | | | 92 * | + SMB Server Management (this file) |<------------------| ZFS | 93 * | +-----------------------------------+ | | | | 94 * | | | | Module | 95 * | +-----------------------------------+ | | | | 96 * | + SMB Server Internal Layers |------+ | +=========+ 97 * | +-----------------------------------+ | 98 * | | 99 * | | 100 * +===========================================================+ 101 * 102 * 103 * Server State Machine 104 * -------------------- 105 * | 106 * | T0 107 * | 108 * v 109 * +-----------------------------+ 110 * | SMB_SERVER_STATE_CREATED | 111 * +-----------------------------+ 112 * | 113 * | T1 114 * | 115 * v 116 * +-----------------------------+ 117 * | SMB_SERVER_STATE_CONFIGURED | 118 * +-----------------------------+ 119 * | 120 * | T2 121 * | 122 * v 123 * +-----------------------------+ 124 * | SMB_SERVER_STATE_RUNNING / | 125 * | SMB_SERVER_STATE_STOPPING | 126 * +-----------------------------+ 127 * | 128 * | T3 129 * | 130 * v 131 * +-----------------------------+ 132 * | SMB_SERVER_STATE_DELETING | 133 * +-----------------------------+ 134 * | 135 * | 136 * | 137 * v 138 * 139 * States 140 * ------ 141 * 142 * SMB_SERVER_STATE_CREATED 143 * 144 * This is the state of the server just after creation. 145 * 146 * SMB_SERVER_STATE_CONFIGURED 147 * 148 * The server has been configured. 149 * 150 * SMB_SERVER_STATE_RUNNING 151 * 152 * The server has been started. While in this state the threads listening on 153 * the sockets are started. 154 * 155 * When a client establishes a connection the thread listening dispatches 156 * a task with the new session as an argument. If the dispatch fails the new 157 * session context is destroyed. 158 * 159 * SMB_SERVER_STATE_STOPPING 160 * 161 * The threads listening on the NBT and TCP sockets are being terminated. 162 * 163 * 164 * Transitions 165 * ----------- 166 * 167 * Transition T0 168 * 169 * The daemon smbd triggers its creation by opening the smbsrv device. If 170 * the zone where the daemon lives doesn't have an smb server yet it is 171 * created. 172 * 173 * smb_drv_open() --> smb_server_create() 174 * 175 * Transition T1 176 * 177 * This transition occurs in smb_server_configure(). It is triggered by the 178 * daemon through an Ioctl. 179 * 180 * smb_drv_ioctl(SMB_IOC_CONFIG) --> smb_server_configure() 181 * 182 * Transition T2 183 * 184 * This transition occurs in smb_server_start(). It is triggered by the 185 * daemon through an Ioctl. 186 * 187 * smb_drv_ioctl(SMB_IOC_START) --> smb_server_start() 188 * 189 * Transition T3 190 * 191 * This transition occurs in smb_server_delete(). It is triggered by the 192 * daemon when closing the smbsrv device 193 * 194 * smb_drv_close() --> smb_server_delete() 195 * 196 * Comments 197 * -------- 198 * 199 * This files assumes that there will one SMB server per zone. For now the 200 * smb server works only in global zone. There's nothing in this file preventing 201 * an smb server from being created in a non global zone. That limitation is 202 * enforced in user space. 203 */ 204 205 #include <sys/cmn_err.h> 206 #include <sys/priv.h> 207 #include <sys/zone.h> 208 #include <netinet/in.h> 209 #include <netinet/in_systm.h> 210 #include <netinet/ip.h> 211 #include <netinet/ip_icmp.h> 212 #include <netinet/ip_var.h> 213 #include <netinet/tcp.h> 214 #include <smbsrv/smb2_kproto.h> 215 #include <smbsrv/string.h> 216 #include <smbsrv/netbios.h> 217 #include <smbsrv/smb_fsops.h> 218 #include <smbsrv/smb_share.h> 219 #include <smbsrv/smb_door.h> 220 #include <smbsrv/smb_kstat.h> 221 222 static void smb_server_kstat_init(smb_server_t *); 223 static void smb_server_kstat_fini(smb_server_t *); 224 static void smb_server_timers(smb_thread_t *, void *); 225 static void smb_server_store_cfg(smb_server_t *, smb_ioc_cfg_t *); 226 static void smb_server_shutdown(smb_server_t *); 227 static int smb_server_fsop_start(smb_server_t *); 228 static void smb_server_fsop_stop(smb_server_t *); 229 static void smb_event_cancel(smb_server_t *, uint32_t); 230 static uint32_t smb_event_alloc_txid(void); 231 232 static void smb_server_disconnect_share(smb_llist_t *, const char *); 233 static void smb_server_enum_users(smb_llist_t *, smb_svcenum_t *); 234 static void smb_server_enum_trees(smb_llist_t *, smb_svcenum_t *); 235 static int smb_server_session_disconnect(smb_llist_t *, const char *, 236 const char *); 237 static int smb_server_fclose(smb_llist_t *, uint32_t); 238 static int smb_server_kstat_update(kstat_t *, int); 239 static int smb_server_legacy_kstat_update(kstat_t *, int); 240 static void smb_server_listener_init(smb_server_t *, smb_listener_daemon_t *, 241 char *, in_port_t, int); 242 static void smb_server_listener_destroy(smb_listener_daemon_t *); 243 static int smb_server_listener_start(smb_listener_daemon_t *); 244 static void smb_server_listener_stop(smb_listener_daemon_t *); 245 static void smb_server_listener(smb_thread_t *, void *); 246 static void smb_server_receiver(void *); 247 static void smb_server_create_session(smb_listener_daemon_t *, ksocket_t); 248 static void smb_server_destroy_session(smb_session_t *); 249 static uint16_t smb_spool_get_fid(smb_server_t *); 250 static boolean_t smb_spool_lookup_doc_byfid(smb_server_t *, uint16_t, 251 smb_kspooldoc_t *); 252 253 /* 254 * How many "buckets" should our hash tables use? On a "real" server, 255 * make them much larger than the number of CPUs we're likely to have. 256 * On "fksmbd" make it smaller so dtrace logs are shorter. 257 * These must be powers of two. 258 */ 259 #ifdef _KERNEL 260 #define DEFAULT_HASH_NBUCKETS 256 /* real server */ 261 #else 262 #define DEFAULT_HASH_NBUCKETS 16 /* for "fksmbd" */ 263 #endif 264 uint32_t SMB_OFILE_HASH_NBUCKETS = DEFAULT_HASH_NBUCKETS; 265 uint32_t SMB_LEASE_HASH_NBUCKETS = DEFAULT_HASH_NBUCKETS; 266 267 int smb_event_debug = 0; 268 269 static smb_llist_t smb_servers; 270 271 kmem_cache_t *smb_cache_request; 272 kmem_cache_t *smb_cache_session; 273 kmem_cache_t *smb_cache_user; 274 kmem_cache_t *smb_cache_tree; 275 kmem_cache_t *smb_cache_ofile; 276 kmem_cache_t *smb_cache_odir; 277 kmem_cache_t *smb_cache_opipe; 278 kmem_cache_t *smb_cache_event; 279 kmem_cache_t *smb_cache_lock; 280 281 /* 282 * ***************************************************************************** 283 * **************** Functions called from the device interface ***************** 284 * ***************************************************************************** 285 * 286 * These functions typically have to determine the relevant smb server 287 * to which the call applies. 288 */ 289 290 /* 291 * How many zones have an SMB server active? 292 */ 293 int 294 smb_server_get_count(void) 295 { 296 return (smb_llist_get_count(&smb_servers)); 297 } 298 299 /* 300 * smb_server_g_init 301 * 302 * This function must be called from smb_drv_attach(). 303 */ 304 int 305 smb_server_g_init(void) 306 { 307 int rc; 308 309 if ((rc = smb_vop_init()) != 0) 310 goto errout; 311 if ((rc = smb_fem_init()) != 0) 312 goto errout; 313 314 smb_kshare_g_init(); 315 smb_codepage_init(); 316 smb_mbc_init(); /* smb_mbc_cache */ 317 smb_node_init(); /* smb_node_cache, lists */ 318 319 smb_cache_request = kmem_cache_create("smb_request_cache", 320 sizeof (smb_request_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 321 smb_cache_session = kmem_cache_create("smb_session_cache", 322 sizeof (smb_session_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 323 smb_cache_user = kmem_cache_create("smb_user_cache", 324 sizeof (smb_user_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 325 smb_cache_tree = kmem_cache_create("smb_tree_cache", 326 sizeof (smb_tree_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 327 smb_cache_ofile = kmem_cache_create("smb_ofile_cache", 328 sizeof (smb_ofile_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 329 smb_cache_odir = kmem_cache_create("smb_odir_cache", 330 sizeof (smb_odir_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 331 smb_cache_opipe = kmem_cache_create("smb_opipe_cache", 332 sizeof (smb_opipe_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 333 smb_cache_event = kmem_cache_create("smb_event_cache", 334 sizeof (smb_event_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 335 smb_cache_lock = kmem_cache_create("smb_lock_cache", 336 sizeof (smb_lock_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 337 338 smb_llist_init(); 339 smb_llist_constructor(&smb_servers, sizeof (smb_server_t), 340 offsetof(smb_server_t, sv_lnd)); 341 342 return (0); 343 344 errout: 345 smb_fem_fini(); 346 smb_vop_fini(); 347 return (rc); 348 } 349 350 /* 351 * smb_server_g_fini 352 * 353 * This function must called from smb_drv_detach(). It will fail if servers 354 * still exist. 355 */ 356 void 357 smb_server_g_fini(void) 358 { 359 360 ASSERT(smb_llist_get_count(&smb_servers) == 0); 361 362 smb_llist_fini(); 363 364 kmem_cache_destroy(smb_cache_request); 365 kmem_cache_destroy(smb_cache_session); 366 kmem_cache_destroy(smb_cache_user); 367 kmem_cache_destroy(smb_cache_tree); 368 kmem_cache_destroy(smb_cache_ofile); 369 kmem_cache_destroy(smb_cache_odir); 370 kmem_cache_destroy(smb_cache_opipe); 371 kmem_cache_destroy(smb_cache_event); 372 kmem_cache_destroy(smb_cache_lock); 373 374 smb_node_fini(); 375 smb_mbc_fini(); 376 smb_codepage_fini(); 377 smb_kshare_g_fini(); 378 379 smb_fem_fini(); 380 smb_vop_fini(); 381 382 smb_llist_destructor(&smb_servers); 383 } 384 385 /* 386 * smb_server_create 387 * 388 * This function will fail if there's already a server associated with the 389 * caller's zone. 390 */ 391 int 392 smb_server_create(void) 393 { 394 zoneid_t zid; 395 smb_server_t *sv; 396 397 zid = getzoneid(); 398 399 smb_llist_enter(&smb_servers, RW_WRITER); 400 sv = smb_llist_head(&smb_servers); 401 while (sv) { 402 SMB_SERVER_VALID(sv); 403 if (sv->sv_zid == zid) { 404 smb_llist_exit(&smb_servers); 405 return (EPERM); 406 } 407 sv = smb_llist_next(&smb_servers, sv); 408 } 409 410 sv = kmem_zalloc(sizeof (smb_server_t), KM_SLEEP); 411 412 sv->sv_magic = SMB_SERVER_MAGIC; 413 sv->sv_state = SMB_SERVER_STATE_CREATED; 414 sv->sv_zid = zid; 415 sv->sv_pid = ddi_get_pid(); 416 417 mutex_init(&sv->sv_mutex, NULL, MUTEX_DEFAULT, NULL); 418 cv_init(&sv->sv_cv, NULL, CV_DEFAULT, NULL); 419 cv_init(&sv->sp_info.sp_cv, NULL, CV_DEFAULT, NULL); 420 421 sv->sv_persistid_ht = smb_hash_create(sizeof (smb_ofile_t), 422 offsetof(smb_ofile_t, f_dh_lnd), SMB_OFILE_HASH_NBUCKETS); 423 424 smb_llist_constructor(&sv->sv_session_list, sizeof (smb_session_t), 425 offsetof(smb_session_t, s_lnd)); 426 427 smb_llist_constructor(&sv->sv_event_list, sizeof (smb_event_t), 428 offsetof(smb_event_t, se_lnd)); 429 430 smb_llist_constructor(&sv->sp_info.sp_list, sizeof (smb_kspooldoc_t), 431 offsetof(smb_kspooldoc_t, sd_lnd)); 432 433 smb_llist_constructor(&sv->sp_info.sp_fidlist, 434 sizeof (smb_spoolfid_t), offsetof(smb_spoolfid_t, sf_lnd)); 435 436 sv->sv_disp_stats1 = kmem_zalloc(SMB_COM_NUM * 437 sizeof (smb_disp_stats_t), KM_SLEEP); 438 439 sv->sv_disp_stats2 = kmem_zalloc(SMB2__NCMDS * 440 sizeof (smb_disp_stats_t), KM_SLEEP); 441 442 smb_thread_init(&sv->si_thread_timers, "smb_timers", 443 smb_server_timers, sv, smbsrv_timer_pri); 444 445 smb_srqueue_init(&sv->sv_srqueue); 446 447 smb_kdoor_init(sv); 448 smb_kshare_init(sv); 449 smb_server_kstat_init(sv); 450 451 smb_threshold_init(&sv->sv_ssetup_ct, SMB_SSETUP_CMD, 452 smb_ssetup_threshold, smb_ssetup_timeout); 453 smb_threshold_init(&sv->sv_tcon_ct, SMB_TCON_CMD, 454 smb_tcon_threshold, smb_tcon_timeout); 455 smb_threshold_init(&sv->sv_opipe_ct, SMB_OPIPE_CMD, 456 smb_opipe_threshold, smb_opipe_timeout); 457 458 smb_llist_insert_tail(&smb_servers, sv); 459 smb_llist_exit(&smb_servers); 460 461 return (0); 462 } 463 464 /* 465 * smb_server_delete 466 * 467 * This function will delete the server passed in. It will make sure that all 468 * activity associated that server has ceased before destroying it. 469 */ 470 int 471 smb_server_delete(void) 472 { 473 smb_server_t *sv; 474 int rc; 475 476 rc = smb_server_lookup(&sv); 477 if (rc != 0) 478 return (rc); 479 480 mutex_enter(&sv->sv_mutex); 481 switch (sv->sv_state) { 482 case SMB_SERVER_STATE_RUNNING: 483 sv->sv_state = SMB_SERVER_STATE_STOPPING; 484 mutex_exit(&sv->sv_mutex); 485 smb_server_shutdown(sv); 486 mutex_enter(&sv->sv_mutex); 487 cv_broadcast(&sv->sp_info.sp_cv); 488 sv->sv_state = SMB_SERVER_STATE_DELETING; 489 break; 490 case SMB_SERVER_STATE_STOPPING: 491 sv->sv_state = SMB_SERVER_STATE_DELETING; 492 break; 493 case SMB_SERVER_STATE_CONFIGURED: 494 case SMB_SERVER_STATE_CREATED: 495 sv->sv_state = SMB_SERVER_STATE_DELETING; 496 break; 497 default: 498 SMB_SERVER_STATE_VALID(sv->sv_state); 499 mutex_exit(&sv->sv_mutex); 500 smb_server_release(sv); 501 return (ENOTTY); 502 } 503 504 ASSERT(sv->sv_state == SMB_SERVER_STATE_DELETING); 505 506 sv->sv_refcnt--; 507 while (sv->sv_refcnt) 508 cv_wait(&sv->sv_cv, &sv->sv_mutex); 509 510 mutex_exit(&sv->sv_mutex); 511 512 smb_llist_enter(&smb_servers, RW_WRITER); 513 smb_llist_remove(&smb_servers, sv); 514 smb_llist_exit(&smb_servers); 515 516 smb_threshold_fini(&sv->sv_ssetup_ct); 517 smb_threshold_fini(&sv->sv_tcon_ct); 518 smb_threshold_fini(&sv->sv_opipe_ct); 519 520 smb_server_listener_destroy(&sv->sv_nbt_daemon); 521 smb_server_listener_destroy(&sv->sv_tcp_daemon); 522 rw_destroy(&sv->sv_cfg_lock); 523 smb_server_kstat_fini(sv); 524 smb_kshare_fini(sv); 525 smb_kdoor_fini(sv); 526 smb_llist_destructor(&sv->sv_event_list); 527 smb_llist_destructor(&sv->sv_session_list); 528 529 kmem_free(sv->sv_disp_stats1, 530 SMB_COM_NUM * sizeof (smb_disp_stats_t)); 531 532 kmem_free(sv->sv_disp_stats2, 533 SMB2__NCMDS * sizeof (smb_disp_stats_t)); 534 535 smb_srqueue_destroy(&sv->sv_srqueue); 536 smb_thread_destroy(&sv->si_thread_timers); 537 538 mutex_destroy(&sv->sv_mutex); 539 smb_hash_destroy(sv->sv_persistid_ht); 540 cv_destroy(&sv->sv_cv); 541 sv->sv_magic = 0; 542 kmem_free(sv, sizeof (smb_server_t)); 543 544 return (0); 545 } 546 547 /* 548 * smb_server_configure 549 */ 550 int 551 smb_server_configure(smb_ioc_cfg_t *ioc) 552 { 553 int rc = 0; 554 smb_server_t *sv; 555 556 /* 557 * Reality check negotiation token length vs. #define'd maximum. 558 */ 559 if (ioc->negtok_len > SMB_PI_MAX_NEGTOK) 560 return (EINVAL); 561 562 rc = smb_server_lookup(&sv); 563 if (rc) 564 return (rc); 565 566 mutex_enter(&sv->sv_mutex); 567 switch (sv->sv_state) { 568 case SMB_SERVER_STATE_CREATED: 569 smb_server_store_cfg(sv, ioc); 570 sv->sv_state = SMB_SERVER_STATE_CONFIGURED; 571 break; 572 573 case SMB_SERVER_STATE_CONFIGURED: 574 smb_server_store_cfg(sv, ioc); 575 break; 576 577 case SMB_SERVER_STATE_RUNNING: 578 case SMB_SERVER_STATE_STOPPING: 579 rw_enter(&sv->sv_cfg_lock, RW_WRITER); 580 smb_server_store_cfg(sv, ioc); 581 rw_exit(&sv->sv_cfg_lock); 582 break; 583 584 default: 585 SMB_SERVER_STATE_VALID(sv->sv_state); 586 rc = EFAULT; 587 break; 588 } 589 mutex_exit(&sv->sv_mutex); 590 591 smb_server_release(sv); 592 593 return (rc); 594 } 595 596 /* 597 * smb_server_start 598 */ 599 int 600 smb_server_start(smb_ioc_start_t *ioc) 601 { 602 int rc = 0; 603 int family; 604 smb_server_t *sv; 605 606 rc = smb_server_lookup(&sv); 607 if (rc) 608 return (rc); 609 610 mutex_enter(&sv->sv_mutex); 611 switch (sv->sv_state) { 612 case SMB_SERVER_STATE_CONFIGURED: 613 614 if ((rc = smb_server_fsop_start(sv)) != 0) 615 break; 616 617 if ((rc = smb_kshare_start(sv)) != 0) 618 break; 619 620 /* 621 * NB: the proc passed here has to be a "system" one. 622 * Normally that's p0, or the NGZ eqivalent. 623 */ 624 sv->sv_worker_pool = taskq_create_proc("smb_workers", 625 sv->sv_cfg.skc_maxworkers, smbsrv_worker_pri, 626 sv->sv_cfg.skc_maxworkers, INT_MAX, 627 curzone->zone_zsched, TASKQ_DYNAMIC); 628 629 sv->sv_receiver_pool = taskq_create_proc("smb_receivers", 630 sv->sv_cfg.skc_maxconnections, smbsrv_receive_pri, 631 sv->sv_cfg.skc_maxconnections, INT_MAX, 632 curzone->zone_zsched, TASKQ_DYNAMIC); 633 634 sv->sv_session = smb_session_create(NULL, 0, sv, 0); 635 636 if (sv->sv_worker_pool == NULL || sv->sv_session == NULL) { 637 rc = ENOMEM; 638 break; 639 } 640 641 #ifdef _KERNEL 642 ASSERT(sv->sv_lmshrd == NULL); 643 sv->sv_lmshrd = smb_kshare_door_init(ioc->lmshrd); 644 if (sv->sv_lmshrd == NULL) 645 break; 646 if ((rc = smb_kdoor_open(sv, ioc->udoor)) != 0) { 647 cmn_err(CE_WARN, "Cannot open smbd door"); 648 break; 649 } 650 #else /* _KERNEL */ 651 /* Fake kernel does not use the kshare_door */ 652 fksmb_kdoor_open(sv, ioc->udoor_func); 653 #endif /* _KERNEL */ 654 655 if ((rc = smb_thread_start(&sv->si_thread_timers)) != 0) 656 break; 657 658 family = AF_INET; 659 smb_server_listener_init(sv, &sv->sv_nbt_daemon, 660 "smb_nbt_listener", IPPORT_NETBIOS_SSN, family); 661 if (sv->sv_cfg.skc_ipv6_enable) 662 family = AF_INET6; 663 smb_server_listener_init(sv, &sv->sv_tcp_daemon, 664 "smb_tcp_listener", IPPORT_SMB, family); 665 rc = smb_server_listener_start(&sv->sv_tcp_daemon); 666 if (rc != 0) 667 break; 668 if (sv->sv_cfg.skc_netbios_enable) 669 (void) smb_server_listener_start(&sv->sv_nbt_daemon); 670 671 sv->sv_state = SMB_SERVER_STATE_RUNNING; 672 sv->sv_start_time = gethrtime(); 673 mutex_exit(&sv->sv_mutex); 674 smb_server_release(sv); 675 smb_export_start(sv); 676 return (0); 677 default: 678 SMB_SERVER_STATE_VALID(sv->sv_state); 679 mutex_exit(&sv->sv_mutex); 680 smb_server_release(sv); 681 return (ENOTTY); 682 } 683 684 mutex_exit(&sv->sv_mutex); 685 smb_server_shutdown(sv); 686 smb_server_release(sv); 687 return (rc); 688 } 689 690 /* 691 * An smbd is shutting down. 692 */ 693 int 694 smb_server_stop(void) 695 { 696 smb_server_t *sv; 697 int rc; 698 699 if ((rc = smb_server_lookup(&sv)) != 0) 700 return (rc); 701 702 mutex_enter(&sv->sv_mutex); 703 switch (sv->sv_state) { 704 case SMB_SERVER_STATE_RUNNING: 705 sv->sv_state = SMB_SERVER_STATE_STOPPING; 706 mutex_exit(&sv->sv_mutex); 707 smb_server_shutdown(sv); 708 mutex_enter(&sv->sv_mutex); 709 cv_broadcast(&sv->sp_info.sp_cv); 710 break; 711 default: 712 SMB_SERVER_STATE_VALID(sv->sv_state); 713 break; 714 } 715 mutex_exit(&sv->sv_mutex); 716 717 smb_server_release(sv); 718 return (0); 719 } 720 721 boolean_t 722 smb_server_is_stopping(smb_server_t *sv) 723 { 724 boolean_t status; 725 726 SMB_SERVER_VALID(sv); 727 728 mutex_enter(&sv->sv_mutex); 729 730 switch (sv->sv_state) { 731 case SMB_SERVER_STATE_STOPPING: 732 case SMB_SERVER_STATE_DELETING: 733 status = B_TRUE; 734 break; 735 default: 736 status = B_FALSE; 737 break; 738 } 739 740 mutex_exit(&sv->sv_mutex); 741 return (status); 742 } 743 744 void 745 smb_server_cancel_event(smb_server_t *sv, uint32_t txid) 746 { 747 smb_event_cancel(sv, txid); 748 } 749 750 int 751 smb_server_notify_event(smb_ioc_event_t *ioc) 752 { 753 smb_server_t *sv; 754 int rc; 755 756 if ((rc = smb_server_lookup(&sv)) == 0) { 757 smb_event_notify(sv, ioc->txid); 758 smb_server_release(sv); 759 } 760 761 return (rc); 762 } 763 764 /* 765 * smb_server_spooldoc 766 * 767 * Waits for print file close broadcast. 768 * Gets the head of the fid list, 769 * then searches the spooldoc list and returns 770 * this info via the ioctl to user land. 771 * 772 * rc - 0 success 773 */ 774 775 int 776 smb_server_spooldoc(smb_ioc_spooldoc_t *ioc) 777 { 778 smb_server_t *sv; 779 int rc; 780 smb_kspooldoc_t *spdoc; 781 uint16_t fid; 782 783 if ((rc = smb_server_lookup(&sv)) != 0) 784 return (rc); 785 786 if (sv->sv_cfg.skc_print_enable == 0) { 787 rc = ENOTTY; 788 goto out; 789 } 790 791 mutex_enter(&sv->sv_mutex); 792 for (;;) { 793 if (sv->sv_state != SMB_SERVER_STATE_RUNNING) { 794 rc = ECANCELED; 795 break; 796 } 797 if ((fid = smb_spool_get_fid(sv)) != 0) { 798 rc = 0; 799 break; 800 } 801 if (cv_wait_sig(&sv->sp_info.sp_cv, &sv->sv_mutex) == 0) { 802 rc = EINTR; 803 break; 804 } 805 } 806 mutex_exit(&sv->sv_mutex); 807 if (rc != 0) 808 goto out; 809 810 spdoc = kmem_zalloc(sizeof (*spdoc), KM_SLEEP); 811 if (smb_spool_lookup_doc_byfid(sv, fid, spdoc)) { 812 ioc->spool_num = spdoc->sd_spool_num; 813 ioc->ipaddr = spdoc->sd_ipaddr; 814 (void) strlcpy(ioc->path, spdoc->sd_path, 815 MAXPATHLEN); 816 (void) strlcpy(ioc->username, 817 spdoc->sd_username, MAXNAMELEN); 818 } else { 819 /* Did not find that print job. */ 820 rc = EAGAIN; 821 } 822 kmem_free(spdoc, sizeof (*spdoc)); 823 824 out: 825 smb_server_release(sv); 826 return (rc); 827 } 828 829 int 830 smb_server_set_gmtoff(smb_ioc_gmt_t *ioc) 831 { 832 int rc; 833 smb_server_t *sv; 834 835 if ((rc = smb_server_lookup(&sv)) == 0) { 836 sv->si_gmtoff = ioc->offset; 837 smb_server_release(sv); 838 } 839 840 return (rc); 841 } 842 843 int 844 smb_server_numopen(smb_ioc_opennum_t *ioc) 845 { 846 smb_server_t *sv; 847 int rc; 848 849 if ((rc = smb_server_lookup(&sv)) == 0) { 850 ioc->open_users = sv->sv_users; 851 ioc->open_trees = sv->sv_trees; 852 ioc->open_files = sv->sv_files + sv->sv_pipes; 853 smb_server_release(sv); 854 } 855 return (rc); 856 } 857 858 /* 859 * Enumerate objects within the server. The svcenum provides the 860 * enumeration context, i.e. what the caller want to get back. 861 */ 862 int 863 smb_server_enum(smb_ioc_svcenum_t *ioc) 864 { 865 smb_svcenum_t *svcenum = &ioc->svcenum; 866 smb_server_t *sv; 867 int rc; 868 869 /* 870 * Reality check that the buffer-length insize the enum doesn't 871 * overrun the ioctl's total length. 872 */ 873 if (svcenum->se_buflen + sizeof (*ioc) > ioc->hdr.len) 874 return (EINVAL); 875 876 if ((rc = smb_server_lookup(&sv)) != 0) 877 return (rc); 878 879 svcenum->se_bavail = svcenum->se_buflen; 880 svcenum->se_bused = 0; 881 svcenum->se_nitems = 0; 882 883 switch (svcenum->se_type) { 884 case SMB_SVCENUM_TYPE_USER: 885 smb_server_enum_users(&sv->sv_session_list, svcenum); 886 break; 887 case SMB_SVCENUM_TYPE_TREE: 888 case SMB_SVCENUM_TYPE_FILE: 889 smb_server_enum_trees(&sv->sv_session_list, svcenum); 890 break; 891 default: 892 rc = EINVAL; 893 } 894 895 smb_server_release(sv); 896 return (rc); 897 } 898 899 /* 900 * Look for sessions to disconnect by client and user name. 901 */ 902 int 903 smb_server_session_close(smb_ioc_session_t *ioc) 904 { 905 smb_llist_t *ll; 906 smb_server_t *sv; 907 int cnt; 908 int rc; 909 910 if ((rc = smb_server_lookup(&sv)) != 0) 911 return (rc); 912 913 ll = &sv->sv_session_list; 914 cnt = smb_server_session_disconnect(ll, ioc->client, ioc->username); 915 916 smb_server_release(sv); 917 918 if (cnt == 0) 919 return (ENOENT); 920 return (0); 921 } 922 923 /* 924 * Close a file by uniqid. 925 */ 926 int 927 smb_server_file_close(smb_ioc_fileid_t *ioc) 928 { 929 uint32_t uniqid = ioc->uniqid; 930 smb_llist_t *ll; 931 smb_server_t *sv; 932 int rc; 933 934 if ((rc = smb_server_lookup(&sv)) != 0) 935 return (rc); 936 937 ll = &sv->sv_session_list; 938 rc = smb_server_fclose(ll, uniqid); 939 940 smb_server_release(sv); 941 return (rc); 942 } 943 944 /* 945 * These functions determine the relevant smb server to which the call apply. 946 */ 947 948 uint32_t 949 smb_server_get_session_count(smb_server_t *sv) 950 { 951 uint32_t counter = 0; 952 953 counter = smb_llist_get_count(&sv->sv_session_list); 954 955 return (counter); 956 } 957 958 /* 959 * Gets the vnode of the specified share path. 960 * 961 * A hold on the returned vnode pointer is taken so the caller 962 * must call VN_RELE. 963 */ 964 int 965 smb_server_sharevp(smb_server_t *sv, const char *shr_path, vnode_t **vp) 966 { 967 smb_request_t *sr; 968 smb_node_t *fnode = NULL; 969 smb_node_t *dnode; 970 char last_comp[MAXNAMELEN]; 971 int rc = 0; 972 973 ASSERT(shr_path); 974 975 mutex_enter(&sv->sv_mutex); 976 switch (sv->sv_state) { 977 case SMB_SERVER_STATE_RUNNING: 978 break; 979 default: 980 mutex_exit(&sv->sv_mutex); 981 return (ENOTACTIVE); 982 } 983 mutex_exit(&sv->sv_mutex); 984 985 if ((sr = smb_request_alloc(sv->sv_session, 0)) == NULL) { 986 return (ENOTCONN); 987 } 988 sr->user_cr = zone_kcred(); 989 990 rc = smb_pathname_reduce(sr, sr->user_cr, shr_path, 991 NULL, NULL, &dnode, last_comp); 992 993 if (rc == 0) { 994 rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS, 995 sv->si_root_smb_node, dnode, last_comp, &fnode); 996 smb_node_release(dnode); 997 } 998 999 smb_request_free(sr); 1000 1001 if (rc != 0) 1002 return (rc); 1003 1004 ASSERT(fnode->vp && fnode->vp->v_vfsp); 1005 1006 VN_HOLD(fnode->vp); 1007 *vp = fnode->vp; 1008 1009 smb_node_release(fnode); 1010 1011 return (0); 1012 } 1013 1014 #ifdef _KERNEL 1015 /* 1016 * This is a special interface that will be utilized by ZFS to cause a share to 1017 * be added/removed. 1018 * 1019 * arg is either a lmshare_info_t or share_name from userspace. 1020 * It will need to be copied into the kernel. It is lmshare_info_t 1021 * for add operations and share_name for delete operations. 1022 */ 1023 int 1024 smb_server_share(void *arg, boolean_t add_share) 1025 { 1026 smb_server_t *sv; 1027 int rc; 1028 1029 if ((rc = smb_server_lookup(&sv)) == 0) { 1030 mutex_enter(&sv->sv_mutex); 1031 switch (sv->sv_state) { 1032 case SMB_SERVER_STATE_RUNNING: 1033 mutex_exit(&sv->sv_mutex); 1034 (void) smb_kshare_upcall(sv->sv_lmshrd, arg, add_share); 1035 break; 1036 default: 1037 mutex_exit(&sv->sv_mutex); 1038 break; 1039 } 1040 smb_server_release(sv); 1041 } 1042 1043 return (rc); 1044 } 1045 #endif /* _KERNEL */ 1046 1047 int 1048 smb_server_unshare(const char *sharename) 1049 { 1050 smb_server_t *sv; 1051 smb_llist_t *ll; 1052 int rc; 1053 1054 if ((rc = smb_server_lookup(&sv))) 1055 return (rc); 1056 1057 mutex_enter(&sv->sv_mutex); 1058 switch (sv->sv_state) { 1059 case SMB_SERVER_STATE_RUNNING: 1060 case SMB_SERVER_STATE_STOPPING: 1061 break; 1062 default: 1063 mutex_exit(&sv->sv_mutex); 1064 smb_server_release(sv); 1065 return (ENOTACTIVE); 1066 } 1067 mutex_exit(&sv->sv_mutex); 1068 1069 ll = &sv->sv_session_list; 1070 smb_server_disconnect_share(ll, sharename); 1071 1072 smb_server_release(sv); 1073 return (0); 1074 } 1075 1076 /* 1077 * Disconnect the specified share. 1078 * Typically called when a share has been removed. 1079 */ 1080 static void 1081 smb_server_disconnect_share(smb_llist_t *ll, const char *sharename) 1082 { 1083 smb_session_t *session; 1084 1085 smb_llist_enter(ll, RW_READER); 1086 1087 session = smb_llist_head(ll); 1088 while (session) { 1089 SMB_SESSION_VALID(session); 1090 smb_rwx_rwenter(&session->s_lock, RW_READER); 1091 switch (session->s_state) { 1092 case SMB_SESSION_STATE_NEGOTIATED: 1093 smb_rwx_rwexit(&session->s_lock); 1094 smb_session_disconnect_share(session, sharename); 1095 break; 1096 default: 1097 smb_rwx_rwexit(&session->s_lock); 1098 break; 1099 } 1100 session = smb_llist_next(ll, session); 1101 } 1102 1103 smb_llist_exit(ll); 1104 } 1105 1106 /* 1107 * ***************************************************************************** 1108 * **************** Functions called from the internal layers ****************** 1109 * ***************************************************************************** 1110 * 1111 * These functions are provided the relevant smb server by the caller. 1112 */ 1113 1114 void 1115 smb_server_get_cfg(smb_server_t *sv, smb_kmod_cfg_t *cfg) 1116 { 1117 rw_enter(&sv->sv_cfg_lock, RW_READER); 1118 bcopy(&sv->sv_cfg, cfg, sizeof (*cfg)); 1119 rw_exit(&sv->sv_cfg_lock); 1120 } 1121 1122 /* 1123 * 1124 */ 1125 void 1126 smb_server_inc_nbt_sess(smb_server_t *sv) 1127 { 1128 SMB_SERVER_VALID(sv); 1129 atomic_inc_32(&sv->sv_nbt_sess); 1130 } 1131 1132 void 1133 smb_server_dec_nbt_sess(smb_server_t *sv) 1134 { 1135 SMB_SERVER_VALID(sv); 1136 atomic_dec_32(&sv->sv_nbt_sess); 1137 } 1138 1139 void 1140 smb_server_inc_tcp_sess(smb_server_t *sv) 1141 { 1142 SMB_SERVER_VALID(sv); 1143 atomic_inc_32(&sv->sv_tcp_sess); 1144 } 1145 1146 void 1147 smb_server_dec_tcp_sess(smb_server_t *sv) 1148 { 1149 SMB_SERVER_VALID(sv); 1150 atomic_dec_32(&sv->sv_tcp_sess); 1151 } 1152 1153 void 1154 smb_server_inc_users(smb_server_t *sv) 1155 { 1156 SMB_SERVER_VALID(sv); 1157 atomic_inc_32(&sv->sv_users); 1158 } 1159 1160 void 1161 smb_server_dec_users(smb_server_t *sv) 1162 { 1163 SMB_SERVER_VALID(sv); 1164 atomic_dec_32(&sv->sv_users); 1165 } 1166 1167 void 1168 smb_server_inc_trees(smb_server_t *sv) 1169 { 1170 SMB_SERVER_VALID(sv); 1171 atomic_inc_32(&sv->sv_trees); 1172 } 1173 1174 void 1175 smb_server_dec_trees(smb_server_t *sv) 1176 { 1177 SMB_SERVER_VALID(sv); 1178 atomic_dec_32(&sv->sv_trees); 1179 } 1180 1181 void 1182 smb_server_inc_files(smb_server_t *sv) 1183 { 1184 SMB_SERVER_VALID(sv); 1185 atomic_inc_32(&sv->sv_files); 1186 } 1187 1188 void 1189 smb_server_dec_files(smb_server_t *sv) 1190 { 1191 SMB_SERVER_VALID(sv); 1192 atomic_dec_32(&sv->sv_files); 1193 } 1194 1195 void 1196 smb_server_inc_pipes(smb_server_t *sv) 1197 { 1198 SMB_SERVER_VALID(sv); 1199 atomic_inc_32(&sv->sv_pipes); 1200 } 1201 1202 void 1203 smb_server_dec_pipes(smb_server_t *sv) 1204 { 1205 SMB_SERVER_VALID(sv); 1206 atomic_dec_32(&sv->sv_pipes); 1207 } 1208 1209 void 1210 smb_server_add_rxb(smb_server_t *sv, int64_t value) 1211 { 1212 SMB_SERVER_VALID(sv); 1213 atomic_add_64(&sv->sv_rxb, value); 1214 } 1215 1216 void 1217 smb_server_add_txb(smb_server_t *sv, int64_t value) 1218 { 1219 SMB_SERVER_VALID(sv); 1220 atomic_add_64(&sv->sv_txb, value); 1221 } 1222 1223 void 1224 smb_server_inc_req(smb_server_t *sv) 1225 { 1226 SMB_SERVER_VALID(sv); 1227 atomic_inc_64(&sv->sv_nreq); 1228 } 1229 1230 /* 1231 * ***************************************************************************** 1232 * *************************** Static Functions ******************************** 1233 * ***************************************************************************** 1234 */ 1235 1236 static void 1237 smb_server_timers(smb_thread_t *thread, void *arg) 1238 { 1239 smb_server_t *sv = (smb_server_t *)arg; 1240 1241 ASSERT(sv != NULL); 1242 1243 /* 1244 * This kills old inactive sessions and expired durable 1245 * handles. The session code expects one call per minute. 1246 */ 1247 while (smb_thread_continue_timedwait(thread, 60 /* Seconds */)) { 1248 if (sv->sv_cfg.skc_keepalive != 0) 1249 smb_session_timers(sv); 1250 smb2_durable_timers(sv); 1251 } 1252 } 1253 1254 /* 1255 * smb_server_kstat_init 1256 */ 1257 static void 1258 smb_server_kstat_init(smb_server_t *sv) 1259 { 1260 1261 sv->sv_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, 0, 1262 SMBSRV_KSTAT_STATISTICS, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_RAW, 1263 sizeof (smbsrv_kstats_t), 0, sv->sv_zid); 1264 1265 if (sv->sv_ksp != NULL) { 1266 sv->sv_ksp->ks_update = smb_server_kstat_update; 1267 sv->sv_ksp->ks_private = sv; 1268 ((smbsrv_kstats_t *)sv->sv_ksp->ks_data)->ks_start_time = 1269 sv->sv_start_time; 1270 smb_dispatch_stats_init(sv); 1271 smb2_dispatch_stats_init(sv); 1272 kstat_install(sv->sv_ksp); 1273 } else { 1274 cmn_err(CE_WARN, "SMB Server: Statistics unavailable"); 1275 } 1276 1277 sv->sv_legacy_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, 0, 1278 SMBSRV_KSTAT_NAME, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_NAMED, 1279 sizeof (smb_server_legacy_kstat_t) / sizeof (kstat_named_t), 1280 0, sv->sv_zid); 1281 1282 if (sv->sv_legacy_ksp != NULL) { 1283 smb_server_legacy_kstat_t *ksd; 1284 1285 ksd = sv->sv_legacy_ksp->ks_data; 1286 1287 (void) strlcpy(ksd->ls_files.name, "open_files", 1288 sizeof (ksd->ls_files.name)); 1289 ksd->ls_files.data_type = KSTAT_DATA_UINT32; 1290 1291 (void) strlcpy(ksd->ls_trees.name, "connections", 1292 sizeof (ksd->ls_trees.name)); 1293 ksd->ls_trees.data_type = KSTAT_DATA_UINT32; 1294 1295 (void) strlcpy(ksd->ls_users.name, "connections", 1296 sizeof (ksd->ls_users.name)); 1297 ksd->ls_users.data_type = KSTAT_DATA_UINT32; 1298 1299 mutex_init(&sv->sv_legacy_ksmtx, NULL, MUTEX_DEFAULT, NULL); 1300 sv->sv_legacy_ksp->ks_lock = &sv->sv_legacy_ksmtx; 1301 sv->sv_legacy_ksp->ks_update = smb_server_legacy_kstat_update; 1302 kstat_install(sv->sv_legacy_ksp); 1303 } 1304 } 1305 1306 /* 1307 * smb_server_kstat_fini 1308 */ 1309 static void 1310 smb_server_kstat_fini(smb_server_t *sv) 1311 { 1312 if (sv->sv_legacy_ksp != NULL) { 1313 kstat_delete(sv->sv_legacy_ksp); 1314 mutex_destroy(&sv->sv_legacy_ksmtx); 1315 sv->sv_legacy_ksp = NULL; 1316 } 1317 1318 if (sv->sv_ksp != NULL) { 1319 kstat_delete(sv->sv_ksp); 1320 sv->sv_ksp = NULL; 1321 smb_dispatch_stats_fini(sv); 1322 smb2_dispatch_stats_fini(sv); 1323 } 1324 } 1325 1326 /* 1327 * smb_server_kstat_update 1328 */ 1329 static int 1330 smb_server_kstat_update(kstat_t *ksp, int rw) 1331 { 1332 smb_server_t *sv; 1333 smbsrv_kstats_t *ksd; 1334 1335 if (rw == KSTAT_READ) { 1336 sv = ksp->ks_private; 1337 SMB_SERVER_VALID(sv); 1338 ksd = (smbsrv_kstats_t *)ksp->ks_data; 1339 /* 1340 * Counters 1341 */ 1342 ksd->ks_nbt_sess = sv->sv_nbt_sess; 1343 ksd->ks_tcp_sess = sv->sv_tcp_sess; 1344 ksd->ks_users = sv->sv_users; 1345 ksd->ks_trees = sv->sv_trees; 1346 ksd->ks_files = sv->sv_files; 1347 ksd->ks_pipes = sv->sv_pipes; 1348 /* 1349 * Throughput 1350 */ 1351 ksd->ks_txb = sv->sv_txb; 1352 ksd->ks_rxb = sv->sv_rxb; 1353 ksd->ks_nreq = sv->sv_nreq; 1354 /* 1355 * Busyness 1356 */ 1357 ksd->ks_maxreqs = sv->sv_cfg.skc_maxworkers; 1358 smb_srqueue_update(&sv->sv_srqueue, 1359 &ksd->ks_utilization); 1360 /* 1361 * Latency & Throughput of the requests 1362 */ 1363 smb_dispatch_stats_update(sv, ksd->ks_reqs1, 0, SMB_COM_NUM); 1364 smb2_dispatch_stats_update(sv, ksd->ks_reqs2, 0, SMB2__NCMDS); 1365 return (0); 1366 } 1367 if (rw == KSTAT_WRITE) 1368 return (EACCES); 1369 1370 return (EIO); 1371 } 1372 1373 static int 1374 smb_server_legacy_kstat_update(kstat_t *ksp, int rw) 1375 { 1376 smb_server_t *sv; 1377 smb_server_legacy_kstat_t *ksd; 1378 int rc; 1379 1380 switch (rw) { 1381 case KSTAT_WRITE: 1382 rc = EACCES; 1383 break; 1384 case KSTAT_READ: 1385 if (!smb_server_lookup(&sv)) { 1386 ASSERT(MUTEX_HELD(ksp->ks_lock)); 1387 ASSERT(sv->sv_legacy_ksp == ksp); 1388 ksd = (smb_server_legacy_kstat_t *)ksp->ks_data; 1389 ksd->ls_files.value.ui32 = sv->sv_files + sv->sv_pipes; 1390 ksd->ls_trees.value.ui32 = sv->sv_trees; 1391 ksd->ls_users.value.ui32 = sv->sv_users; 1392 smb_server_release(sv); 1393 rc = 0; 1394 break; 1395 } 1396 /* FALLTHROUGH */ 1397 default: 1398 rc = EIO; 1399 break; 1400 } 1401 return (rc); 1402 1403 } 1404 1405 /* 1406 * smb_server_shutdown 1407 */ 1408 static void 1409 smb_server_shutdown(smb_server_t *sv) 1410 { 1411 smb_llist_t *sl = &sv->sv_session_list; 1412 smb_session_t *session; 1413 clock_t time; 1414 1415 SMB_SERVER_VALID(sv); 1416 1417 /* 1418 * Stop the listeners first, so we don't get any more 1419 * new work while we're trying to shut down. 1420 */ 1421 smb_server_listener_stop(&sv->sv_nbt_daemon); 1422 smb_server_listener_stop(&sv->sv_tcp_daemon); 1423 smb_thread_stop(&sv->si_thread_timers); 1424 1425 /* Disconnect all of the sessions */ 1426 smb_llist_enter(sl, RW_READER); 1427 session = smb_llist_head(sl); 1428 while (session != NULL) { 1429 smb_session_disconnect(session); 1430 session = smb_llist_next(sl, session); 1431 } 1432 smb_llist_exit(sl); 1433 1434 /* 1435 * Wake up any threads we might have blocked. 1436 * Must precede kdoor_close etc. because those will 1437 * wait for such threads to get out. 1438 */ 1439 smb_event_cancel(sv, 0); 1440 smb_threshold_wake_all(&sv->sv_ssetup_ct); 1441 smb_threshold_wake_all(&sv->sv_tcon_ct); 1442 smb_threshold_wake_all(&sv->sv_opipe_ct); 1443 1444 /* 1445 * Wait for the session list to empty. 1446 * (cv_signal in smb_server_destroy_session) 1447 * 1448 * This should not take long, but if there are any leaked 1449 * references to ofiles, trees, or users, there could be a 1450 * session hanging around. If that happens, the ll_count 1451 * never gets to zero and we'll never get the sv_signal. 1452 * Defend against that problem using timed wait, then 1453 * complain if we find sessions left over and continue 1454 * with shutdown in spite of any leaked sessions. 1455 * That's better than a server that won't reboot. 1456 */ 1457 time = SEC_TO_TICK(10) + ddi_get_lbolt(); 1458 mutex_enter(&sv->sv_mutex); 1459 while (sv->sv_session_list.ll_count != 0) { 1460 if (cv_timedwait(&sv->sv_cv, &sv->sv_mutex, time) < 0) 1461 break; 1462 } 1463 mutex_exit(&sv->sv_mutex); 1464 #ifdef DEBUG 1465 if (sv->sv_session_list.ll_count != 0) { 1466 cmn_err(CE_NOTE, "shutdown leaked sessions"); 1467 debug_enter("shutdown leaked sessions"); 1468 } 1469 #endif 1470 1471 /* 1472 * Clean out any durable handles. After this we should 1473 * have no ofiles remaining (and no more oplock breaks). 1474 */ 1475 smb2_dh_shutdown(sv); 1476 1477 smb_kdoor_close(sv); 1478 #ifdef _KERNEL 1479 smb_kshare_door_fini(sv->sv_lmshrd); 1480 #endif /* _KERNEL */ 1481 sv->sv_lmshrd = NULL; 1482 1483 smb_export_stop(sv); 1484 smb_kshare_stop(sv); 1485 1486 /* 1487 * Both kshare and the oplock break sub-systems may have 1488 * taskq jobs on the spcial "server" session, until we've 1489 * closed all ofiles and stopped the kshare exporter. 1490 * Now it's safe to destroy the server session, but first 1491 * wait for any requests on it to finish. Note that for 1492 * normal sessions, this happens in smb_session_cancel, 1493 * but that's not called for the server session. 1494 */ 1495 if (sv->sv_session != NULL) { 1496 smb_slist_wait_for_empty(&sv->sv_session->s_req_list); 1497 1498 smb_session_delete(sv->sv_session); 1499 sv->sv_session = NULL; 1500 } 1501 1502 if (sv->sv_receiver_pool != NULL) { 1503 taskq_destroy(sv->sv_receiver_pool); 1504 sv->sv_receiver_pool = NULL; 1505 } 1506 1507 if (sv->sv_worker_pool != NULL) { 1508 taskq_destroy(sv->sv_worker_pool); 1509 sv->sv_worker_pool = NULL; 1510 } 1511 1512 smb_server_fsop_stop(sv); 1513 } 1514 1515 /* 1516 * smb_server_listener_init 1517 * 1518 * Initializes listener contexts. 1519 */ 1520 static void 1521 smb_server_listener_init( 1522 smb_server_t *sv, 1523 smb_listener_daemon_t *ld, 1524 char *name, 1525 in_port_t port, 1526 int family) 1527 { 1528 ASSERT(ld->ld_magic != SMB_LISTENER_MAGIC); 1529 1530 bzero(ld, sizeof (*ld)); 1531 1532 ld->ld_sv = sv; 1533 ld->ld_family = family; 1534 ld->ld_port = port; 1535 1536 if (family == AF_INET) { 1537 ld->ld_sin.sin_family = (uint32_t)family; 1538 ld->ld_sin.sin_port = htons(port); 1539 ld->ld_sin.sin_addr.s_addr = htonl(INADDR_ANY); 1540 } else { 1541 ld->ld_sin6.sin6_family = (uint32_t)family; 1542 ld->ld_sin6.sin6_port = htons(port); 1543 (void) memset(&ld->ld_sin6.sin6_addr.s6_addr, 0, 1544 sizeof (ld->ld_sin6.sin6_addr.s6_addr)); 1545 } 1546 1547 smb_thread_init(&ld->ld_thread, name, smb_server_listener, ld, 1548 smbsrv_listen_pri); 1549 ld->ld_magic = SMB_LISTENER_MAGIC; 1550 } 1551 1552 /* 1553 * smb_server_listener_destroy 1554 * 1555 * Destroyes listener contexts. 1556 */ 1557 static void 1558 smb_server_listener_destroy(smb_listener_daemon_t *ld) 1559 { 1560 /* 1561 * Note that if startup fails early, we can legitimately 1562 * get here with an all-zeros object. 1563 */ 1564 if (ld->ld_magic == 0) 1565 return; 1566 1567 SMB_LISTENER_VALID(ld); 1568 ASSERT(ld->ld_so == NULL); 1569 smb_thread_destroy(&ld->ld_thread); 1570 ld->ld_magic = 0; 1571 } 1572 1573 /* 1574 * smb_server_listener_start 1575 * 1576 * Starts the listener associated with the context passed in. 1577 * 1578 * Return: 0 Success 1579 * not 0 Failure 1580 */ 1581 static int 1582 smb_server_listener_start(smb_listener_daemon_t *ld) 1583 { 1584 int rc; 1585 uint32_t on; 1586 uint32_t off; 1587 1588 SMB_LISTENER_VALID(ld); 1589 1590 if (ld->ld_so != NULL) 1591 return (EINVAL); 1592 1593 ld->ld_so = smb_socreate(ld->ld_family, SOCK_STREAM, 0); 1594 if (ld->ld_so == NULL) { 1595 cmn_err(CE_WARN, "port %d: socket create failed", ld->ld_port); 1596 return (ENOMEM); 1597 } 1598 1599 off = 0; 1600 (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET, 1601 SO_MAC_EXEMPT, &off, sizeof (off), CRED()); 1602 1603 on = 1; 1604 (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET, 1605 SO_REUSEADDR, &on, sizeof (on), CRED()); 1606 1607 if (ld->ld_family == AF_INET) { 1608 rc = ksocket_bind(ld->ld_so, 1609 (struct sockaddr *)&ld->ld_sin, 1610 sizeof (ld->ld_sin), CRED()); 1611 } else { 1612 rc = ksocket_bind(ld->ld_so, 1613 (struct sockaddr *)&ld->ld_sin6, 1614 sizeof (ld->ld_sin6), CRED()); 1615 } 1616 1617 if (rc != 0) { 1618 cmn_err(CE_WARN, "port %d: bind failed", ld->ld_port); 1619 return (rc); 1620 } 1621 1622 rc = ksocket_listen(ld->ld_so, 20, CRED()); 1623 if (rc < 0) { 1624 cmn_err(CE_WARN, "port %d: listen failed", ld->ld_port); 1625 return (rc); 1626 } 1627 1628 ksocket_hold(ld->ld_so); 1629 rc = smb_thread_start(&ld->ld_thread); 1630 if (rc != 0) { 1631 ksocket_rele(ld->ld_so); 1632 cmn_err(CE_WARN, "port %d: listener failed to start", 1633 ld->ld_port); 1634 return (rc); 1635 } 1636 return (0); 1637 } 1638 1639 /* 1640 * smb_server_listener_stop 1641 * 1642 * Stops the listener associated with the context passed in. 1643 */ 1644 static void 1645 smb_server_listener_stop(smb_listener_daemon_t *ld) 1646 { 1647 SMB_LISTENER_VALID(ld); 1648 1649 if (ld->ld_so != NULL) { 1650 smb_soshutdown(ld->ld_so); 1651 smb_sodestroy(ld->ld_so); 1652 smb_thread_stop(&ld->ld_thread); 1653 ld->ld_so = NULL; 1654 } 1655 } 1656 1657 /* 1658 * smb_server_listener 1659 * 1660 * Entry point of the listeners. 1661 */ 1662 static void 1663 smb_server_listener(smb_thread_t *thread, void *arg) 1664 { 1665 _NOTE(ARGUNUSED(thread)) 1666 smb_listener_daemon_t *ld; 1667 ksocket_t s_so; 1668 int on; 1669 int txbuf_size; 1670 1671 ld = (smb_listener_daemon_t *)arg; 1672 1673 SMB_LISTENER_VALID(ld); 1674 1675 DTRACE_PROBE1(so__wait__accept, struct sonode *, ld->ld_so); 1676 1677 for (;;) { 1678 int ret = ksocket_accept(ld->ld_so, NULL, NULL, &s_so, CRED()); 1679 1680 switch (ret) { 1681 case 0: 1682 break; 1683 case ECONNABORTED: 1684 continue; 1685 case EINTR: 1686 case EBADF: /* libfakekernel */ 1687 goto out; 1688 default: 1689 cmn_err(CE_WARN, 1690 "smb_server_listener: ksocket_accept(%d)", 1691 ret); 1692 goto out; 1693 } 1694 1695 DTRACE_PROBE1(so__accept, struct sonode *, s_so); 1696 1697 on = 1; 1698 (void) ksocket_setsockopt(s_so, IPPROTO_TCP, TCP_NODELAY, 1699 &on, sizeof (on), CRED()); 1700 1701 on = 1; 1702 (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_KEEPALIVE, 1703 &on, sizeof (on), CRED()); 1704 1705 txbuf_size = 128*1024; 1706 (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_SNDBUF, 1707 (const void *)&txbuf_size, sizeof (txbuf_size), CRED()); 1708 1709 /* 1710 * Create a session for this connection. 1711 */ 1712 smb_server_create_session(ld, s_so); 1713 } 1714 out: 1715 ksocket_rele(ld->ld_so); 1716 } 1717 1718 /* 1719 * smb_server_receiver 1720 * 1721 * Entry point of the receiver threads. 1722 * Also does cleanup when socket disconnected. 1723 */ 1724 static void 1725 smb_server_receiver(void *arg) 1726 { 1727 smb_session_t *session; 1728 1729 session = (smb_session_t *)arg; 1730 1731 /* We stay in here until socket disconnect. */ 1732 smb_session_receiver(session); 1733 1734 ASSERT(session->s_state == SMB_SESSION_STATE_SHUTDOWN); 1735 smb_server_destroy_session(session); 1736 } 1737 1738 /* 1739 * smb_server_lookup 1740 * 1741 * This function finds the server associated with the zone of the 1742 * caller. Note: requires a fix in the dynamic taskq code: 1743 * 1501 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0 1744 */ 1745 int 1746 smb_server_lookup(smb_server_t **psv) 1747 { 1748 zoneid_t zid; 1749 smb_server_t *sv; 1750 1751 zid = getzoneid(); 1752 1753 smb_llist_enter(&smb_servers, RW_READER); 1754 sv = smb_llist_head(&smb_servers); 1755 while (sv) { 1756 SMB_SERVER_VALID(sv); 1757 if (sv->sv_zid == zid) { 1758 mutex_enter(&sv->sv_mutex); 1759 if (sv->sv_state != SMB_SERVER_STATE_DELETING) { 1760 sv->sv_refcnt++; 1761 mutex_exit(&sv->sv_mutex); 1762 smb_llist_exit(&smb_servers); 1763 *psv = sv; 1764 return (0); 1765 } 1766 mutex_exit(&sv->sv_mutex); 1767 break; 1768 } 1769 sv = smb_llist_next(&smb_servers, sv); 1770 } 1771 smb_llist_exit(&smb_servers); 1772 return (EPERM); 1773 } 1774 1775 /* 1776 * smb_server_release 1777 * 1778 * This function decrements the reference count of the server and signals its 1779 * condition variable if the state of the server is SMB_SERVER_STATE_DELETING. 1780 */ 1781 void 1782 smb_server_release(smb_server_t *sv) 1783 { 1784 SMB_SERVER_VALID(sv); 1785 1786 mutex_enter(&sv->sv_mutex); 1787 ASSERT(sv->sv_refcnt); 1788 sv->sv_refcnt--; 1789 if ((sv->sv_refcnt == 0) && (sv->sv_state == SMB_SERVER_STATE_DELETING)) 1790 cv_signal(&sv->sv_cv); 1791 mutex_exit(&sv->sv_mutex); 1792 } 1793 1794 /* 1795 * Enumerate the users associated with a session list. 1796 */ 1797 static void 1798 smb_server_enum_users(smb_llist_t *ll, smb_svcenum_t *svcenum) 1799 { 1800 smb_session_t *sn; 1801 smb_llist_t *ulist; 1802 smb_user_t *user; 1803 int rc = 0; 1804 1805 smb_llist_enter(ll, RW_READER); 1806 sn = smb_llist_head(ll); 1807 1808 while (sn != NULL) { 1809 SMB_SESSION_VALID(sn); 1810 ulist = &sn->s_user_list; 1811 smb_llist_enter(ulist, RW_READER); 1812 user = smb_llist_head(ulist); 1813 1814 while (user != NULL) { 1815 if (smb_user_hold(user)) { 1816 rc = smb_user_enum(user, svcenum); 1817 smb_user_release(user); 1818 if (rc != 0) 1819 break; 1820 } 1821 1822 user = smb_llist_next(ulist, user); 1823 } 1824 1825 smb_llist_exit(ulist); 1826 1827 if (rc != 0) 1828 break; 1829 1830 sn = smb_llist_next(ll, sn); 1831 } 1832 1833 smb_llist_exit(ll); 1834 } 1835 1836 /* 1837 * Enumerate the trees/files associated with a session list. 1838 */ 1839 static void 1840 smb_server_enum_trees(smb_llist_t *ll, smb_svcenum_t *svcenum) 1841 { 1842 smb_session_t *sn; 1843 smb_llist_t *tlist; 1844 smb_tree_t *tree; 1845 int rc = 0; 1846 1847 smb_llist_enter(ll, RW_READER); 1848 sn = smb_llist_head(ll); 1849 1850 while (sn != NULL) { 1851 SMB_SESSION_VALID(sn); 1852 tlist = &sn->s_tree_list; 1853 smb_llist_enter(tlist, RW_READER); 1854 tree = smb_llist_head(tlist); 1855 1856 while (tree != NULL) { 1857 if (smb_tree_hold(tree)) { 1858 rc = smb_tree_enum(tree, svcenum); 1859 smb_tree_release(tree); 1860 if (rc != 0) 1861 break; 1862 } 1863 1864 tree = smb_llist_next(tlist, tree); 1865 } 1866 1867 smb_llist_exit(tlist); 1868 1869 if (rc != 0) 1870 break; 1871 1872 sn = smb_llist_next(ll, sn); 1873 } 1874 1875 smb_llist_exit(ll); 1876 } 1877 1878 /* 1879 * Disconnect sessions associated with the specified client and username. 1880 * Empty strings are treated as wildcards. 1881 */ 1882 static int 1883 smb_server_session_disconnect(smb_llist_t *ll, 1884 const char *client, const char *name) 1885 { 1886 smb_session_t *sn; 1887 smb_llist_t *ulist; 1888 smb_user_t *user; 1889 int count = 0; 1890 1891 smb_llist_enter(ll, RW_READER); 1892 1893 for (sn = smb_llist_head(ll); 1894 sn != NULL; 1895 sn = smb_llist_next(ll, sn)) { 1896 SMB_SESSION_VALID(sn); 1897 1898 if (*client != '\0' && !smb_session_isclient(sn, client)) 1899 continue; 1900 1901 ulist = &sn->s_user_list; 1902 smb_llist_enter(ulist, RW_READER); 1903 1904 for (user = smb_llist_head(ulist); 1905 user != NULL; 1906 user = smb_llist_next(ulist, user)) { 1907 SMB_USER_VALID(user); 1908 1909 if (*name != '\0' && !smb_user_namecmp(user, name)) 1910 continue; 1911 1912 if (smb_user_hold(user)) { 1913 smb_user_logoff(user); 1914 smb_user_release(user); 1915 count++; 1916 } 1917 } 1918 1919 smb_llist_exit(ulist); 1920 } 1921 1922 smb_llist_exit(ll); 1923 return (count); 1924 } 1925 1926 /* 1927 * Close a file by its unique id. 1928 */ 1929 static int 1930 smb_server_fclose(smb_llist_t *ll, uint32_t uniqid) 1931 { 1932 smb_session_t *sn; 1933 smb_llist_t *tlist; 1934 smb_tree_t *tree; 1935 int rc = ENOENT; 1936 1937 smb_llist_enter(ll, RW_READER); 1938 sn = smb_llist_head(ll); 1939 1940 while ((sn != NULL) && (rc == ENOENT)) { 1941 SMB_SESSION_VALID(sn); 1942 tlist = &sn->s_tree_list; 1943 smb_llist_enter(tlist, RW_READER); 1944 tree = smb_llist_head(tlist); 1945 1946 while ((tree != NULL) && (rc == ENOENT)) { 1947 if (smb_tree_hold(tree)) { 1948 rc = smb_tree_fclose(tree, uniqid); 1949 smb_tree_release(tree); 1950 } 1951 1952 tree = smb_llist_next(tlist, tree); 1953 } 1954 1955 smb_llist_exit(tlist); 1956 sn = smb_llist_next(ll, sn); 1957 } 1958 1959 smb_llist_exit(ll); 1960 return (rc); 1961 } 1962 1963 /* 1964 * This is used by SMB2 session setup to logoff a previous session, 1965 * so it can force a logoff that we haven't noticed yet. 1966 * This is not called frequently, so we just walk the list of 1967 * connections searching for the user. 1968 */ 1969 void 1970 smb_server_logoff_ssnid(smb_request_t *sr, uint64_t ssnid) 1971 { 1972 smb_server_t *sv = sr->sr_server; 1973 smb_llist_t *sess_list; 1974 smb_session_t *sess; 1975 1976 if (sv->sv_state != SMB_SERVER_STATE_RUNNING) 1977 return; 1978 1979 sess_list = &sv->sv_session_list; 1980 smb_llist_enter(sess_list, RW_READER); 1981 1982 for (sess = smb_llist_head(sess_list); 1983 sess != NULL; 1984 sess = smb_llist_next(sess_list, sess)) { 1985 1986 smb_user_t *user; 1987 1988 SMB_SESSION_VALID(sess); 1989 1990 if (sess->dialect < SMB_VERS_2_BASE) 1991 continue; 1992 1993 if (sess->s_state != SMB_SESSION_STATE_NEGOTIATED) 1994 continue; 1995 1996 user = smb_session_lookup_ssnid(sess, ssnid); 1997 if (user == NULL) 1998 continue; 1999 2000 if (!smb_is_same_user(user->u_cred, sr->user_cr)) { 2001 smb_user_release(user); 2002 continue; 2003 } 2004 2005 /* Treat this as if we lost the connection */ 2006 user->preserve_opens = SMB2_DH_PRESERVE_SOME; 2007 smb_user_logoff(user); 2008 smb_user_release(user); 2009 2010 /* 2011 * The above may have left work on the delete queues 2012 */ 2013 smb_llist_flush(&sess->s_tree_list); 2014 smb_llist_flush(&sess->s_user_list); 2015 } 2016 2017 smb_llist_exit(sess_list); 2018 } 2019 2020 /* See also: libsmb smb_kmod_setcfg */ 2021 static void 2022 smb_server_store_cfg(smb_server_t *sv, smb_ioc_cfg_t *ioc) 2023 { 2024 if (ioc->maxconnections == 0) 2025 ioc->maxconnections = 0xFFFFFFFF; 2026 2027 sv->sv_cfg.skc_maxworkers = ioc->maxworkers; 2028 sv->sv_cfg.skc_maxconnections = ioc->maxconnections; 2029 sv->sv_cfg.skc_keepalive = ioc->keepalive; 2030 sv->sv_cfg.skc_restrict_anon = ioc->restrict_anon; 2031 sv->sv_cfg.skc_signing_enable = ioc->signing_enable; 2032 sv->sv_cfg.skc_signing_required = ioc->signing_required; 2033 sv->sv_cfg.skc_oplock_enable = ioc->oplock_enable; 2034 sv->sv_cfg.skc_sync_enable = ioc->sync_enable; 2035 sv->sv_cfg.skc_secmode = ioc->secmode; 2036 sv->sv_cfg.skc_netbios_enable = ioc->netbios_enable; 2037 sv->sv_cfg.skc_ipv6_enable = ioc->ipv6_enable; 2038 sv->sv_cfg.skc_print_enable = ioc->print_enable; 2039 sv->sv_cfg.skc_traverse_mounts = ioc->traverse_mounts; 2040 sv->sv_cfg.skc_max_protocol = ioc->max_protocol; 2041 sv->sv_cfg.skc_execflags = ioc->exec_flags; 2042 sv->sv_cfg.skc_negtok_len = ioc->negtok_len; 2043 sv->sv_cfg.skc_version = ioc->version; 2044 sv->sv_cfg.skc_initial_credits = ioc->initial_credits; 2045 sv->sv_cfg.skc_maximum_credits = ioc->maximum_credits; 2046 2047 (void) memcpy(sv->sv_cfg.skc_machine_uuid, ioc->machine_uuid, 2048 sizeof (uuid_t)); 2049 (void) memcpy(sv->sv_cfg.skc_negtok, ioc->negtok, 2050 sizeof (sv->sv_cfg.skc_negtok)); 2051 (void) memcpy(sv->sv_cfg.skc_native_os, ioc->native_os, 2052 sizeof (sv->sv_cfg.skc_native_os)); 2053 (void) memcpy(sv->sv_cfg.skc_native_lm, ioc->native_lm, 2054 sizeof (sv->sv_cfg.skc_native_lm)); 2055 2056 (void) strlcpy(sv->sv_cfg.skc_nbdomain, ioc->nbdomain, 2057 sizeof (sv->sv_cfg.skc_nbdomain)); 2058 (void) strlcpy(sv->sv_cfg.skc_fqdn, ioc->fqdn, 2059 sizeof (sv->sv_cfg.skc_fqdn)); 2060 (void) strlcpy(sv->sv_cfg.skc_hostname, ioc->hostname, 2061 sizeof (sv->sv_cfg.skc_hostname)); 2062 (void) strlcpy(sv->sv_cfg.skc_system_comment, ioc->system_comment, 2063 sizeof (sv->sv_cfg.skc_system_comment)); 2064 } 2065 2066 static int 2067 smb_server_fsop_start(smb_server_t *sv) 2068 { 2069 int error; 2070 2071 error = smb_node_root_init(sv, &sv->si_root_smb_node); 2072 if (error != 0) 2073 sv->si_root_smb_node = NULL; 2074 2075 return (error); 2076 } 2077 2078 static void 2079 smb_server_fsop_stop(smb_server_t *sv) 2080 { 2081 if (sv->si_root_smb_node != NULL) { 2082 smb_node_release(sv->si_root_smb_node); 2083 sv->si_root_smb_node = NULL; 2084 } 2085 } 2086 2087 smb_event_t * 2088 smb_event_create(smb_server_t *sv, int timeout) 2089 { 2090 smb_event_t *event; 2091 2092 if (smb_server_is_stopping(sv)) 2093 return (NULL); 2094 2095 event = kmem_cache_alloc(smb_cache_event, KM_SLEEP); 2096 2097 bzero(event, sizeof (smb_event_t)); 2098 mutex_init(&event->se_mutex, NULL, MUTEX_DEFAULT, NULL); 2099 cv_init(&event->se_cv, NULL, CV_DEFAULT, NULL); 2100 event->se_magic = SMB_EVENT_MAGIC; 2101 event->se_txid = smb_event_alloc_txid(); 2102 event->se_server = sv; 2103 event->se_timeout = timeout; 2104 2105 smb_llist_enter(&sv->sv_event_list, RW_WRITER); 2106 smb_llist_insert_tail(&sv->sv_event_list, event); 2107 smb_llist_exit(&sv->sv_event_list); 2108 2109 return (event); 2110 } 2111 2112 void 2113 smb_event_destroy(smb_event_t *event) 2114 { 2115 smb_server_t *sv; 2116 2117 if (event == NULL) 2118 return; 2119 2120 SMB_EVENT_VALID(event); 2121 ASSERT(event->se_waittime == 0); 2122 sv = event->se_server; 2123 SMB_SERVER_VALID(sv); 2124 2125 smb_llist_enter(&sv->sv_event_list, RW_WRITER); 2126 smb_llist_remove(&sv->sv_event_list, event); 2127 smb_llist_exit(&sv->sv_event_list); 2128 2129 event->se_magic = (uint32_t)~SMB_EVENT_MAGIC; 2130 cv_destroy(&event->se_cv); 2131 mutex_destroy(&event->se_mutex); 2132 2133 kmem_cache_free(smb_cache_event, event); 2134 } 2135 2136 /* 2137 * Get the txid for the specified event. 2138 */ 2139 uint32_t 2140 smb_event_txid(smb_event_t *event) 2141 { 2142 if (event != NULL) { 2143 SMB_EVENT_VALID(event); 2144 return (event->se_txid); 2145 } 2146 2147 cmn_err(CE_NOTE, "smb_event_txid failed"); 2148 return ((uint32_t)-1); 2149 } 2150 2151 /* 2152 * Wait for event notification. 2153 */ 2154 int 2155 smb_event_wait(smb_event_t *event) 2156 { 2157 int seconds = 1; 2158 int ticks; 2159 int err; 2160 2161 if (event == NULL) 2162 return (EINVAL); 2163 2164 SMB_EVENT_VALID(event); 2165 2166 mutex_enter(&event->se_mutex); 2167 event->se_waittime = 1; 2168 event->se_errno = 0; 2169 2170 while (!(event->se_notified)) { 2171 if (smb_event_debug && ((event->se_waittime % 30) == 0)) 2172 cmn_err(CE_NOTE, "smb_event_wait[%d] (%d sec)", 2173 event->se_txid, event->se_waittime); 2174 2175 if (event->se_errno != 0) 2176 break; 2177 2178 if (event->se_waittime > event->se_timeout) { 2179 event->se_errno = ETIME; 2180 break; 2181 } 2182 2183 ticks = SEC_TO_TICK(seconds); 2184 (void) cv_reltimedwait(&event->se_cv, 2185 &event->se_mutex, (clock_t)ticks, TR_CLOCK_TICK); 2186 ++event->se_waittime; 2187 } 2188 2189 err = event->se_errno; 2190 event->se_waittime = 0; 2191 event->se_notified = B_FALSE; 2192 cv_signal(&event->se_cv); 2193 mutex_exit(&event->se_mutex); 2194 return (err); 2195 } 2196 2197 /* 2198 * If txid is non-zero, cancel the specified event. 2199 * Otherwise, cancel all events. 2200 */ 2201 static void 2202 smb_event_cancel(smb_server_t *sv, uint32_t txid) 2203 { 2204 smb_event_t *event; 2205 smb_llist_t *event_list; 2206 2207 SMB_SERVER_VALID(sv); 2208 2209 event_list = &sv->sv_event_list; 2210 smb_llist_enter(event_list, RW_WRITER); 2211 2212 event = smb_llist_head(event_list); 2213 while (event) { 2214 SMB_EVENT_VALID(event); 2215 2216 if (txid == 0 || event->se_txid == txid) { 2217 mutex_enter(&event->se_mutex); 2218 event->se_errno = ECANCELED; 2219 event->se_notified = B_TRUE; 2220 cv_signal(&event->se_cv); 2221 mutex_exit(&event->se_mutex); 2222 2223 if (txid != 0) 2224 break; 2225 } 2226 2227 event = smb_llist_next(event_list, event); 2228 } 2229 2230 smb_llist_exit(event_list); 2231 } 2232 2233 /* 2234 * If txid is non-zero, notify the specified event. 2235 * Otherwise, notify all events. 2236 */ 2237 void 2238 smb_event_notify(smb_server_t *sv, uint32_t txid) 2239 { 2240 smb_event_t *event; 2241 smb_llist_t *event_list; 2242 2243 SMB_SERVER_VALID(sv); 2244 2245 event_list = &sv->sv_event_list; 2246 smb_llist_enter(event_list, RW_READER); 2247 2248 event = smb_llist_head(event_list); 2249 while (event) { 2250 SMB_EVENT_VALID(event); 2251 2252 if (txid == 0 || event->se_txid == txid) { 2253 mutex_enter(&event->se_mutex); 2254 event->se_notified = B_TRUE; 2255 cv_signal(&event->se_cv); 2256 mutex_exit(&event->se_mutex); 2257 2258 if (txid != 0) 2259 break; 2260 } 2261 2262 event = smb_llist_next(event_list, event); 2263 } 2264 2265 smb_llist_exit(event_list); 2266 } 2267 2268 /* 2269 * Allocate a new transaction id (txid). 2270 * 2271 * 0 or -1 are not assigned because they are used to detect invalid 2272 * conditions or to indicate all open id's. 2273 */ 2274 static uint32_t 2275 smb_event_alloc_txid(void) 2276 { 2277 static kmutex_t txmutex; 2278 static uint32_t txid; 2279 uint32_t txid_ret; 2280 2281 mutex_enter(&txmutex); 2282 2283 if (txid == 0) 2284 txid = ddi_get_lbolt() << 11; 2285 2286 do { 2287 ++txid; 2288 } while (txid == 0 || txid == (uint32_t)-1); 2289 2290 txid_ret = txid; 2291 mutex_exit(&txmutex); 2292 2293 return (txid_ret); 2294 } 2295 2296 /* 2297 * Called by the ioctl to find the corresponding 2298 * spooldoc node. removes node on success 2299 * 2300 * Return values 2301 * rc 2302 * B_FALSE - not found 2303 * B_TRUE - found 2304 * 2305 */ 2306 2307 static boolean_t 2308 smb_spool_lookup_doc_byfid(smb_server_t *sv, uint16_t fid, 2309 smb_kspooldoc_t *spdoc) 2310 { 2311 smb_kspooldoc_t *sp; 2312 smb_llist_t *splist; 2313 2314 splist = &sv->sp_info.sp_list; 2315 smb_llist_enter(splist, RW_WRITER); 2316 sp = smb_llist_head(splist); 2317 while (sp != NULL) { 2318 /* 2319 * check for a matching fid 2320 */ 2321 if (sp->sd_fid == fid) { 2322 *spdoc = *sp; 2323 smb_llist_remove(splist, sp); 2324 smb_llist_exit(splist); 2325 kmem_free(sp, sizeof (smb_kspooldoc_t)); 2326 return (B_TRUE); 2327 } 2328 sp = smb_llist_next(splist, sp); 2329 } 2330 cmn_err(CE_WARN, "smb_spool_lookup_user_byfid: no fid:%d", fid); 2331 smb_llist_exit(splist); 2332 return (B_FALSE); 2333 } 2334 2335 /* 2336 * Adds the spool fid to a linked list to be used 2337 * as a search key in the spooldoc queue 2338 * 2339 * Return values 2340 * rc non-zero error 2341 * rc zero success 2342 * 2343 */ 2344 2345 void 2346 smb_spool_add_fid(smb_server_t *sv, uint16_t fid) 2347 { 2348 smb_llist_t *fidlist; 2349 smb_spoolfid_t *sf; 2350 2351 if (sv->sv_cfg.skc_print_enable == 0) 2352 return; 2353 2354 sf = kmem_zalloc(sizeof (smb_spoolfid_t), KM_SLEEP); 2355 fidlist = &sv->sp_info.sp_fidlist; 2356 smb_llist_enter(fidlist, RW_WRITER); 2357 sf->sf_fid = fid; 2358 smb_llist_insert_tail(fidlist, sf); 2359 smb_llist_exit(fidlist); 2360 cv_broadcast(&sv->sp_info.sp_cv); 2361 } 2362 2363 /* 2364 * Called by the ioctl to get and remove the head of the fid list 2365 * 2366 * Return values 2367 * int fd 2368 * greater than 0 success 2369 * 0 - error 2370 * 2371 */ 2372 2373 static uint16_t 2374 smb_spool_get_fid(smb_server_t *sv) 2375 { 2376 smb_spoolfid_t *spfid; 2377 smb_llist_t *splist; 2378 uint16_t fid; 2379 2380 splist = &sv->sp_info.sp_fidlist; 2381 smb_llist_enter(splist, RW_WRITER); 2382 spfid = smb_llist_head(splist); 2383 if (spfid != NULL) { 2384 fid = spfid->sf_fid; 2385 smb_llist_remove(&sv->sp_info.sp_fidlist, spfid); 2386 kmem_free(spfid, sizeof (smb_spoolfid_t)); 2387 } else { 2388 fid = 0; 2389 } 2390 smb_llist_exit(splist); 2391 return (fid); 2392 } 2393 2394 /* 2395 * Adds the spooldoc to the tail of the spooldoc list 2396 * 2397 * Return values 2398 * rc non-zero error 2399 * rc zero success 2400 */ 2401 int 2402 smb_spool_add_doc(smb_tree_t *tree, smb_kspooldoc_t *sp) 2403 { 2404 smb_llist_t *splist; 2405 smb_server_t *sv = tree->t_server; 2406 int rc = 0; 2407 2408 splist = &sv->sp_info.sp_list; 2409 smb_llist_enter(splist, RW_WRITER); 2410 sp->sd_spool_num = atomic_inc_32_nv(&sv->sp_info.sp_cnt); 2411 smb_llist_insert_tail(splist, sp); 2412 smb_llist_exit(splist); 2413 2414 return (rc); 2415 } 2416 2417 /* 2418 * smb_server_create_session 2419 */ 2420 static void 2421 smb_server_create_session(smb_listener_daemon_t *ld, ksocket_t s_so) 2422 { 2423 smb_session_t *session; 2424 taskqid_t tqid; 2425 smb_llist_t *sl; 2426 smb_server_t *sv = ld->ld_sv; 2427 2428 session = smb_session_create(s_so, ld->ld_port, sv, 2429 ld->ld_family); 2430 2431 if (session == NULL) { 2432 smb_soshutdown(s_so); 2433 smb_sodestroy(s_so); 2434 cmn_err(CE_WARN, "SMB Session: alloc failed"); 2435 return; 2436 } 2437 2438 sl = &sv->sv_session_list; 2439 smb_llist_enter(sl, RW_WRITER); 2440 smb_llist_insert_tail(sl, session); 2441 smb_llist_exit(sl); 2442 2443 /* 2444 * These taskq entries must run independently of one another, 2445 * so TQ_NOQUEUE. TQ_SLEEP (==0) just for clarity. 2446 */ 2447 tqid = taskq_dispatch(sv->sv_receiver_pool, 2448 smb_server_receiver, session, TQ_NOQUEUE | TQ_SLEEP); 2449 if (tqid == TASKQID_INVALID) { 2450 smb_session_disconnect(session); 2451 smb_server_destroy_session(session); 2452 cmn_err(CE_WARN, "SMB Session: taskq_dispatch failed"); 2453 return; 2454 } 2455 /* handy for debugging */ 2456 session->s_receiver_tqid = tqid; 2457 } 2458 2459 static void 2460 smb_server_destroy_session(smb_session_t *session) 2461 { 2462 smb_server_t *sv; 2463 smb_llist_t *ll; 2464 uint32_t count; 2465 2466 ASSERT(session->s_server != NULL); 2467 sv = session->s_server; 2468 ll = &sv->sv_session_list; 2469 2470 smb_llist_flush(&session->s_tree_list); 2471 smb_llist_flush(&session->s_user_list); 2472 2473 /* 2474 * The user and tree lists should be empty now. 2475 */ 2476 #ifdef DEBUG 2477 if (session->s_user_list.ll_count != 0) { 2478 cmn_err(CE_WARN, "user list not empty?"); 2479 debug_enter("s_user_list"); 2480 } 2481 if (session->s_tree_list.ll_count != 0) { 2482 cmn_err(CE_WARN, "tree list not empty?"); 2483 debug_enter("s_tree_list"); 2484 } 2485 #endif 2486 2487 smb_llist_enter(ll, RW_WRITER); 2488 smb_llist_remove(ll, session); 2489 count = ll->ll_count; 2490 smb_llist_exit(ll); 2491 2492 smb_session_delete(session); 2493 if (count == 0) { 2494 /* See smb_server_shutdown */ 2495 cv_signal(&sv->sv_cv); 2496 } 2497 } 2498