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