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