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 */ 24 25 /* 26 * General Structures Layout 27 * ------------------------- 28 * 29 * This is a simplified diagram showing the relationship between most of the 30 * main structures. 31 * 32 * +-------------------+ 33 * | SMB_SERVER | 34 * +-------------------+ 35 * | 36 * | 37 * v 38 * +-------------------+ +-------------------+ +-------------------+ 39 * | SESSION |<----->| SESSION |......| SESSION | 40 * +-------------------+ +-------------------+ +-------------------+ 41 * | 42 * | 43 * v 44 * +-------------------+ +-------------------+ +-------------------+ 45 * | USER |<----->| USER |......| USER | 46 * +-------------------+ +-------------------+ +-------------------+ 47 * | 48 * | 49 * v 50 * +-------------------+ +-------------------+ +-------------------+ 51 * | TREE |<----->| TREE |......| TREE | 52 * +-------------------+ +-------------------+ +-------------------+ 53 * | | 54 * | | 55 * | v 56 * | +-------+ +-------+ +-------+ 57 * | | OFILE |<----->| OFILE |......| OFILE | 58 * | +-------+ +-------+ +-------+ 59 * | 60 * | 61 * v 62 * +-------+ +------+ +------+ 63 * | ODIR |<----->| ODIR |......| ODIR | 64 * +-------+ +------+ +------+ 65 * 66 * 67 * Module Interface Overview 68 * ------------------------- 69 * 70 * 71 * +===================================+ 72 * | smbd daemon | 73 * +===================================+ 74 * | | ^ 75 * | | | 76 * User | | | 77 * -----------|--------------|----------------|-------------------------------- 78 * Kernel | | | 79 * | | | 80 * | | | 81 * +=========|==============|================|=================+ 82 * | v v | | 83 * | +-----------+ +--------------------+ +------------------+ | 84 * | | IO | | Kernel Door Server | | User Door Servers| | 85 * | | Interface | | Interface | | Interface | | 86 * | +-----------+ +--------------------+ +------------------+ | 87 * | | | ^ ^ | 88 * | v v | | | +=========+ 89 * | +-----------------------------------+ | | | | 90 * | + SMB Server Management (this file) |<------------------| ZFS | 91 * | +-----------------------------------+ | | | | 92 * | | | | Module | 93 * | +-----------------------------------+ | | | | 94 * | + SMB Server Internal Layers |------+ | +=========+ 95 * | +-----------------------------------+ | 96 * | | 97 * | | 98 * +===========================================================+ 99 * 100 * 101 * Server State Machine 102 * -------------------- 103 * | 104 * | T0 105 * | 106 * v 107 * +-----------------------------+ 108 * | SMB_SERVER_STATE_CREATED | 109 * +-----------------------------+ 110 * | 111 * | T1 112 * | 113 * v 114 * +-----------------------------+ 115 * | SMB_SERVER_STATE_CONFIGURED | 116 * +-----------------------------+ 117 * | 118 * | T2 119 * | 120 * v 121 * +-----------------------------+ 122 * | SMB_SERVER_STATE_RUNNING / | 123 * | SMB_SERVER_STATE_STOPPING | 124 * +-----------------------------+ 125 * | 126 * | T3 127 * | 128 * v 129 * +-----------------------------+ 130 * | SMB_SERVER_STATE_DELETING | 131 * +-----------------------------+ 132 * | 133 * | 134 * | 135 * v 136 * 137 * States 138 * ------ 139 * 140 * SMB_SERVER_STATE_CREATED 141 * 142 * This is the state of the server just after creation. 143 * 144 * SMB_SERVER_STATE_CONFIGURED 145 * 146 * The server has been configured. 147 * 148 * SMB_SERVER_STATE_RUNNING 149 * 150 * The server has been started. While in this state the threads listening on 151 * the sockets car be started. The smbd daemon does so through an Ioctl: 152 * 153 * smb_drv_ioctl(SMB_IOC_NBT_LISTEN) --> smb_server_nbt_listen() 154 * smb_drv_ioctl(SMB_IOC_TCP_LISTEN) --> smb_server_nbt_listen() 155 * 156 * When a client establishes a connection the thread listening leaves 157 * temporarily the kernel. While in user space it creates a thread for the 158 * new session. It then returns to kernel with the result of the thread 159 * creation. If the creation failed the new session context is destroyed 160 * before returning listening. 161 * 162 * The new created thread enters the kernel though an Ioctl: 163 * 164 * smb_drv_ioctl(SMB_IOC_NBT_RECEIVE) --> smb_server_nbt_receive() 165 * smb_drv_ioctl(SMB_IOC_TCP_RECEIVE) --> smb_server_tcp_receive() 166 * 167 * SMB_SERVER_STATE_STOPPING 168 * 169 * The threads listening on the NBT and TCP sockets are being terminated. 170 * 171 * 172 * Transitions 173 * ----------- 174 * 175 * Transition T0 176 * 177 * The daemon smbd triggers its creation by opening the smbsrv device. If 178 * the zone where the daemon lives doesn't have an smb server yet it is 179 * created. 180 * 181 * smb_drv_open() --> smb_server_create() 182 * 183 * Transition T1 184 * 185 * This transition occurs in smb_server_configure(). It is triggered by the 186 * daemon through an Ioctl. 187 * 188 * smb_drv_ioctl(SMB_IOC_CONFIG) --> smb_server_configure() 189 * 190 * Transition T2 191 * 192 * This transition occurs in smb_server_start(). It is triggered by the 193 * daemon through an Ioctl. 194 * 195 * smb_drv_ioctl(SMB_IOC_START) --> smb_server_start() 196 * 197 * Transition T3 198 * 199 * This transition occurs in smb_server_delete(). It is triggered by the 200 * daemon when closing the smbsrv device 201 * 202 * smb_drv_close() --> smb_server_delete() 203 * 204 * Comments 205 * -------- 206 * 207 * This files assumes that there will one SMB server per zone. For now the 208 * smb server works only in global zone. There's nothing in this file preventing 209 * an smb server from being created in a non global zone. That limitation is 210 * enforced in user space. 211 */ 212 213 #include <sys/strsubr.h> 214 #include <sys/cmn_err.h> 215 #include <sys/priv.h> 216 #include <sys/socketvar.h> 217 #include <sys/zone.h> 218 #include <netinet/in.h> 219 #include <netinet/in_systm.h> 220 #include <netinet/ip.h> 221 #include <netinet/ip_icmp.h> 222 #include <netinet/ip_var.h> 223 #include <netinet/tcp.h> 224 #include <smbsrv/smb_kproto.h> 225 #include <smbsrv/string.h> 226 #include <smbsrv/netbios.h> 227 #include <smbsrv/smb_fsops.h> 228 #include <smbsrv/smb_share.h> 229 #include <smbsrv/smb_door.h> 230 #include <smbsrv/smb_kstat.h> 231 232 #define SMB_EVENT_TIMEOUT 45 /* seconds */ 233 234 extern void smb_dispatch_kstat_init(void); 235 extern void smb_dispatch_kstat_fini(void); 236 extern void smb_reply_notify_change_request(smb_request_t *); 237 238 static int smb_server_kstat_init(smb_server_t *); 239 static void smb_server_kstat_fini(smb_server_t *); 240 static int smb_server_kstat_update_info(kstat_t *, int); 241 static void smb_server_timers(smb_thread_t *, void *); 242 static int smb_server_listen(smb_server_t *, smb_listener_daemon_t *, 243 in_port_t, int, int); 244 static void smb_server_listen_fini(smb_listener_daemon_t *); 245 static kt_did_t smb_server_listener_tid(smb_listener_daemon_t *); 246 static int smb_server_lookup(smb_server_t **); 247 static void smb_server_release(smb_server_t *); 248 static void smb_server_store_cfg(smb_server_t *, smb_ioc_cfg_t *); 249 static void smb_server_shutdown(smb_server_t *); 250 static int smb_server_fsop_start(smb_server_t *); 251 static void smb_server_fsop_stop(smb_server_t *); 252 static void smb_server_signal_listeners(smb_server_t *); 253 static void smb_event_cancel(smb_server_t *, uint32_t); 254 static void smb_event_notify(smb_server_t *, uint32_t); 255 static uint32_t smb_event_alloc_txid(void); 256 257 static void smb_server_disconnect_share(smb_session_list_t *, const char *); 258 static void smb_server_thread_unexport(smb_thread_t *, void *); 259 static void smb_server_enum_private(smb_session_list_t *, smb_svcenum_t *); 260 static int smb_server_sesion_disconnect(smb_session_list_t *, const char *, 261 const char *); 262 static int smb_server_fclose(smb_session_list_t *, uint32_t); 263 264 int smb_event_debug = 0; 265 266 static smb_llist_t smb_servers; 267 268 /* 269 * ***************************************************************************** 270 * **************** Functions called from the device interface ***************** 271 * ***************************************************************************** 272 * 273 * These functions typically have to determine the relevant smb server 274 * to which the call applies. 275 */ 276 277 /* 278 * smb_server_svc_init 279 * 280 * This function must be called from smb_drv_attach(). 281 */ 282 int 283 smb_server_svc_init(void) 284 { 285 int rc = 0; 286 287 while (rc == 0) { 288 if (rc = smb_mbc_init()) 289 continue; 290 if (rc = smb_vop_init()) 291 continue; 292 if (rc = smb_node_init()) 293 continue; 294 if (rc = smb_fem_init()) 295 continue; 296 if (rc = smb_user_init()) 297 continue; 298 if (rc = smb_notify_init()) 299 continue; 300 if (rc = smb_net_init()) 301 continue; 302 smb_llist_init(); 303 smb_llist_constructor(&smb_servers, sizeof (smb_server_t), 304 offsetof(smb_server_t, sv_lnd)); 305 return (0); 306 } 307 308 smb_llist_fini(); 309 smb_net_fini(); 310 smb_notify_fini(); 311 smb_user_fini(); 312 smb_fem_fini(); 313 smb_node_fini(); 314 smb_vop_fini(); 315 smb_mbc_fini(); 316 return (rc); 317 } 318 319 /* 320 * smb_server_svc_fini 321 * 322 * This function must called from smb_drv_detach(). It will fail if servers 323 * still exist. 324 */ 325 int 326 smb_server_svc_fini(void) 327 { 328 int rc = EBUSY; 329 330 if (smb_llist_get_count(&smb_servers) == 0) { 331 smb_llist_fini(); 332 smb_net_fini(); 333 smb_notify_fini(); 334 smb_user_fini(); 335 smb_fem_fini(); 336 smb_node_fini(); 337 smb_vop_fini(); 338 smb_mbc_fini(); 339 smb_llist_destructor(&smb_servers); 340 rc = 0; 341 } 342 return (rc); 343 } 344 345 /* 346 * smb_server_create 347 * 348 * This function will fail if there's already a server associated with the 349 * caller's zone. 350 */ 351 int 352 smb_server_create(void) 353 { 354 zoneid_t zid; 355 smb_server_t *sv; 356 357 zid = getzoneid(); 358 359 smb_llist_enter(&smb_servers, RW_WRITER); 360 sv = smb_llist_head(&smb_servers); 361 while (sv) { 362 SMB_SERVER_VALID(sv); 363 if (sv->sv_zid == zid) { 364 smb_llist_exit(&smb_servers); 365 return (EPERM); 366 } 367 sv = smb_llist_next(&smb_servers, sv); 368 } 369 370 sv = kmem_zalloc(sizeof (smb_server_t), KM_NOSLEEP); 371 if (sv == NULL) { 372 smb_llist_exit(&smb_servers); 373 return (ENOMEM); 374 } 375 376 smb_llist_constructor(&sv->sv_vfs_list, sizeof (smb_vfs_t), 377 offsetof(smb_vfs_t, sv_lnd)); 378 379 smb_llist_constructor(&sv->sv_opipe_list, sizeof (smb_opipe_t), 380 offsetof(smb_opipe_t, p_lnd)); 381 382 smb_llist_constructor(&sv->sv_event_list, sizeof (smb_event_t), 383 offsetof(smb_event_t, se_lnd)); 384 385 smb_slist_constructor(&sv->sv_unexport_list, sizeof (smb_unexport_t), 386 offsetof(smb_unexport_t, ux_lnd)); 387 388 smb_session_list_constructor(&sv->sv_nbt_daemon.ld_session_list); 389 smb_session_list_constructor(&sv->sv_tcp_daemon.ld_session_list); 390 391 sv->si_cache_unexport = kmem_cache_create("smb_unexport_cache", 392 sizeof (smb_unexport_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 393 sv->si_cache_vfs = kmem_cache_create("smb_vfs_cache", 394 sizeof (smb_vfs_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 395 sv->si_cache_request = kmem_cache_create("smb_request_cache", 396 sizeof (smb_request_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 397 sv->si_cache_session = kmem_cache_create("smb_session_cache", 398 sizeof (smb_session_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 399 sv->si_cache_user = kmem_cache_create("smb_user_cache", 400 sizeof (smb_user_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 401 sv->si_cache_tree = kmem_cache_create("smb_tree_cache", 402 sizeof (smb_tree_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 403 sv->si_cache_ofile = kmem_cache_create("smb_ofile_cache", 404 sizeof (smb_ofile_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 405 sv->si_cache_odir = kmem_cache_create("smb_odir_cache", 406 sizeof (smb_odir_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 407 sv->si_cache_opipe = kmem_cache_create("smb_opipe_cache", 408 sizeof (smb_opipe_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 409 sv->si_cache_event = kmem_cache_create("smb_event_cache", 410 sizeof (smb_event_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 411 412 smb_thread_init(&sv->si_thread_timers, 413 "smb_timers", smb_server_timers, sv, 414 NULL, NULL); 415 416 smb_thread_init(&sv->si_thread_unexport, "smb_thread_unexport", 417 smb_server_thread_unexport, sv, NULL, NULL); 418 419 sv->sv_pid = curproc->p_pid; 420 421 smb_kdoor_init(); 422 smb_opipe_door_init(); 423 (void) smb_server_kstat_init(sv); 424 425 mutex_init(&sv->sv_mutex, NULL, MUTEX_DEFAULT, NULL); 426 cv_init(&sv->sv_cv, NULL, CV_DEFAULT, NULL); 427 sv->sv_state = SMB_SERVER_STATE_CREATED; 428 sv->sv_magic = SMB_SERVER_MAGIC; 429 sv->sv_zid = zid; 430 431 smb_llist_insert_tail(&smb_servers, sv); 432 smb_llist_exit(&smb_servers); 433 return (0); 434 } 435 436 /* 437 * smb_server_delete 438 * 439 * This function will delete the server passed in. It will make sure that all 440 * activity associated that server has ceased before destroying it. 441 */ 442 int 443 smb_server_delete(void) 444 { 445 smb_server_t *sv; 446 smb_unexport_t *ux; 447 kt_did_t nbt_tid; 448 kt_did_t tcp_tid; 449 int rc; 450 451 rc = smb_server_lookup(&sv); 452 if (rc != 0) 453 return (rc); 454 455 mutex_enter(&sv->sv_mutex); 456 switch (sv->sv_state) { 457 case SMB_SERVER_STATE_RUNNING: 458 case SMB_SERVER_STATE_STOPPING: 459 sv->sv_state = SMB_SERVER_STATE_STOPPING; 460 smb_server_signal_listeners(sv); 461 nbt_tid = smb_server_listener_tid(&sv->sv_nbt_daemon); 462 tcp_tid = smb_server_listener_tid(&sv->sv_tcp_daemon); 463 464 sv->sv_state = SMB_SERVER_STATE_DELETING; 465 mutex_exit(&sv->sv_mutex); 466 467 if (nbt_tid != 0) 468 thread_join(nbt_tid); 469 if (tcp_tid != 0) 470 thread_join(tcp_tid); 471 472 smb_server_listen_fini(&sv->sv_nbt_daemon); 473 smb_server_listen_fini(&sv->sv_tcp_daemon); 474 mutex_enter(&sv->sv_mutex); 475 break; 476 case SMB_SERVER_STATE_CONFIGURED: 477 case SMB_SERVER_STATE_CREATED: 478 sv->sv_state = SMB_SERVER_STATE_DELETING; 479 break; 480 default: 481 SMB_SERVER_STATE_VALID(sv->sv_state); 482 mutex_exit(&sv->sv_mutex); 483 smb_server_release(sv); 484 return (ENOTTY); 485 } 486 487 ASSERT(sv->sv_state == SMB_SERVER_STATE_DELETING); 488 489 sv->sv_refcnt--; 490 while (sv->sv_refcnt) 491 cv_wait(&sv->sv_cv, &sv->sv_mutex); 492 493 mutex_exit(&sv->sv_mutex); 494 495 smb_llist_enter(&smb_servers, RW_WRITER); 496 smb_llist_remove(&smb_servers, sv); 497 smb_llist_exit(&smb_servers); 498 499 smb_server_shutdown(sv); 500 rw_destroy(&sv->sv_cfg_lock); 501 smb_opipe_door_fini(); 502 smb_kdoor_fini(); 503 smb_server_kstat_fini(sv); 504 smb_llist_destructor(&sv->sv_vfs_list); 505 smb_llist_destructor(&sv->sv_opipe_list); 506 smb_llist_destructor(&sv->sv_event_list); 507 508 while ((ux = list_head(&sv->sv_unexport_list.sl_list)) != NULL) { 509 smb_slist_remove(&sv->sv_unexport_list, ux); 510 kmem_cache_free(sv->si_cache_unexport, ux); 511 } 512 smb_slist_destructor(&sv->sv_unexport_list); 513 514 kmem_cache_destroy(sv->si_cache_unexport); 515 kmem_cache_destroy(sv->si_cache_vfs); 516 kmem_cache_destroy(sv->si_cache_request); 517 kmem_cache_destroy(sv->si_cache_session); 518 kmem_cache_destroy(sv->si_cache_user); 519 kmem_cache_destroy(sv->si_cache_tree); 520 kmem_cache_destroy(sv->si_cache_ofile); 521 kmem_cache_destroy(sv->si_cache_odir); 522 kmem_cache_destroy(sv->si_cache_opipe); 523 kmem_cache_destroy(sv->si_cache_event); 524 525 smb_thread_destroy(&sv->si_thread_timers); 526 smb_thread_destroy(&sv->si_thread_unexport); 527 mutex_destroy(&sv->sv_mutex); 528 cv_destroy(&sv->sv_cv); 529 sv->sv_magic = 0; 530 kmem_free(sv, sizeof (smb_server_t)); 531 532 return (0); 533 } 534 535 /* 536 * smb_server_configure 537 */ 538 int 539 smb_server_configure(smb_ioc_cfg_t *ioc) 540 { 541 int rc = 0; 542 smb_server_t *sv; 543 544 rc = smb_server_lookup(&sv); 545 if (rc) 546 return (rc); 547 548 mutex_enter(&sv->sv_mutex); 549 switch (sv->sv_state) { 550 case SMB_SERVER_STATE_CREATED: 551 smb_server_store_cfg(sv, ioc); 552 sv->sv_state = SMB_SERVER_STATE_CONFIGURED; 553 break; 554 555 case SMB_SERVER_STATE_CONFIGURED: 556 smb_server_store_cfg(sv, ioc); 557 break; 558 559 case SMB_SERVER_STATE_RUNNING: 560 case SMB_SERVER_STATE_STOPPING: 561 rw_enter(&sv->sv_cfg_lock, RW_WRITER); 562 smb_server_store_cfg(sv, ioc); 563 rw_exit(&sv->sv_cfg_lock); 564 break; 565 566 default: 567 SMB_SERVER_STATE_VALID(sv->sv_state); 568 rc = EFAULT; 569 break; 570 } 571 mutex_exit(&sv->sv_mutex); 572 573 smb_server_release(sv); 574 575 return (rc); 576 } 577 578 /* 579 * smb_server_start 580 */ 581 int 582 smb_server_start(smb_ioc_start_t *ioc) 583 { 584 int rc = 0; 585 smb_server_t *sv; 586 587 rc = smb_server_lookup(&sv); 588 if (rc) 589 return (rc); 590 591 mutex_enter(&sv->sv_mutex); 592 switch (sv->sv_state) { 593 case SMB_SERVER_STATE_CONFIGURED: 594 smb_codepage_init(); 595 596 sv->sv_thread_pool = taskq_create("smb_workers", 597 sv->sv_cfg.skc_maxworkers, SMB_WORKER_PRIORITY, 598 sv->sv_cfg.skc_maxworkers, INT_MAX, 599 TASKQ_DYNAMIC|TASKQ_PREPOPULATE); 600 601 sv->sv_session = smb_session_create(NULL, 0, sv, 0); 602 603 if (sv->sv_thread_pool == NULL || sv->sv_session == NULL) { 604 rc = ENOMEM; 605 break; 606 } 607 608 if (rc = smb_server_fsop_start(sv)) 609 break; 610 ASSERT(sv->sv_lmshrd == NULL); 611 sv->sv_lmshrd = smb_kshare_init(ioc->lmshrd); 612 if (sv->sv_lmshrd == NULL) 613 break; 614 if (rc = smb_kdoor_open(ioc->udoor)) { 615 cmn_err(CE_WARN, "Cannot open smbd door"); 616 break; 617 } 618 if (rc = smb_opipe_door_open(ioc->opipe)) { 619 cmn_err(CE_WARN, "Cannot open opipe door"); 620 break; 621 } 622 if (rc = smb_thread_start(&sv->si_thread_timers)) 623 break; 624 if (rc = smb_thread_start(&sv->si_thread_unexport)) 625 break; 626 sv->sv_state = SMB_SERVER_STATE_RUNNING; 627 mutex_exit(&sv->sv_mutex); 628 smb_server_release(sv); 629 return (0); 630 default: 631 SMB_SERVER_STATE_VALID(sv->sv_state); 632 mutex_exit(&sv->sv_mutex); 633 smb_server_release(sv); 634 return (ENOTTY); 635 } 636 637 smb_server_shutdown(sv); 638 mutex_exit(&sv->sv_mutex); 639 smb_server_release(sv); 640 return (rc); 641 } 642 643 /* 644 * An smbd is shutting down. 645 */ 646 int 647 smb_server_stop(void) 648 { 649 smb_server_t *sv; 650 int rc; 651 652 if ((rc = smb_server_lookup(&sv)) != 0) 653 return (rc); 654 655 mutex_enter(&sv->sv_mutex); 656 switch (sv->sv_state) { 657 case SMB_SERVER_STATE_RUNNING: 658 sv->sv_state = SMB_SERVER_STATE_STOPPING; 659 smb_server_signal_listeners(sv); 660 break; 661 default: 662 SMB_SERVER_STATE_VALID(sv->sv_state); 663 break; 664 } 665 mutex_exit(&sv->sv_mutex); 666 667 smb_server_release(sv); 668 return (0); 669 } 670 671 boolean_t 672 smb_server_is_stopping(void) 673 { 674 smb_server_t *sv; 675 boolean_t status; 676 677 if (smb_server_lookup(&sv) != 0) 678 return (B_TRUE); 679 680 SMB_SERVER_VALID(sv); 681 682 mutex_enter(&sv->sv_mutex); 683 684 switch (sv->sv_state) { 685 case SMB_SERVER_STATE_STOPPING: 686 case SMB_SERVER_STATE_DELETING: 687 status = B_TRUE; 688 break; 689 default: 690 status = B_FALSE; 691 break; 692 } 693 694 mutex_exit(&sv->sv_mutex); 695 smb_server_release(sv); 696 return (status); 697 } 698 699 int 700 smb_server_cancel_event(uint32_t txid) 701 { 702 smb_server_t *sv; 703 int rc; 704 705 if ((rc = smb_server_lookup(&sv)) == 0) { 706 smb_event_cancel(sv, txid); 707 smb_server_release(sv); 708 } 709 710 return (rc); 711 } 712 713 int 714 smb_server_notify_event(smb_ioc_event_t *ioc) 715 { 716 smb_server_t *sv; 717 int rc; 718 719 if ((rc = smb_server_lookup(&sv)) == 0) { 720 smb_event_notify(sv, ioc->txid); 721 smb_server_release(sv); 722 } 723 724 return (rc); 725 } 726 727 /* 728 * SMB-over-NetBIOS (port 139) 729 * 730 * Traditional SMB service over NetBIOS, which requires that a NetBIOS 731 * session be established. 732 */ 733 int 734 smb_server_nbt_listen(smb_ioc_listen_t *ioc) 735 { 736 smb_server_t *sv; 737 int rc; 738 739 rc = smb_server_lookup(&sv); 740 if (rc) 741 return (rc); 742 743 mutex_enter(&sv->sv_mutex); 744 switch (sv->sv_state) { 745 case SMB_SERVER_STATE_RUNNING: 746 if ((sv->sv_nbt_daemon.ld_kth != NULL) && 747 (sv->sv_nbt_daemon.ld_kth != curthread)) { 748 mutex_exit(&sv->sv_mutex); 749 smb_server_release(sv); 750 return (EACCES); 751 } else { 752 sv->sv_nbt_daemon.ld_kth = curthread; 753 sv->sv_nbt_daemon.ld_ktdid = curthread->t_did; 754 } 755 break; 756 case SMB_SERVER_STATE_STOPPING: 757 mutex_exit(&sv->sv_mutex); 758 smb_server_release(sv); 759 return (ECANCELED); 760 default: 761 SMB_SERVER_STATE_VALID(sv->sv_state); 762 mutex_exit(&sv->sv_mutex); 763 smb_server_release(sv); 764 return (EFAULT); 765 } 766 mutex_exit(&sv->sv_mutex); 767 768 /* 769 * netbios must be ipv4 770 */ 771 rc = smb_server_listen(sv, &sv->sv_nbt_daemon, IPPORT_NETBIOS_SSN, 772 AF_INET, ioc->error); 773 774 mutex_enter(&sv->sv_mutex); 775 sv->sv_nbt_daemon.ld_kth = NULL; 776 777 mutex_exit(&sv->sv_mutex); 778 779 smb_server_release(sv); 780 return (rc); 781 } 782 783 /* 784 * SMB-over-TCP (port 445) 785 */ 786 int 787 smb_server_tcp_listen(smb_ioc_listen_t *ioc) 788 { 789 smb_server_t *sv; 790 int rc; 791 792 rc = smb_server_lookup(&sv); 793 if (rc) 794 return (rc); 795 796 mutex_enter(&sv->sv_mutex); 797 switch (sv->sv_state) { 798 case SMB_SERVER_STATE_RUNNING: 799 if ((sv->sv_tcp_daemon.ld_kth != NULL) && 800 (sv->sv_tcp_daemon.ld_kth != curthread)) { 801 mutex_exit(&sv->sv_mutex); 802 smb_server_release(sv); 803 return (EACCES); 804 } else { 805 sv->sv_tcp_daemon.ld_kth = curthread; 806 sv->sv_tcp_daemon.ld_ktdid = curthread->t_did; 807 } 808 break; 809 case SMB_SERVER_STATE_STOPPING: 810 mutex_exit(&sv->sv_mutex); 811 smb_server_release(sv); 812 return (ECANCELED); 813 default: 814 SMB_SERVER_STATE_VALID(sv->sv_state); 815 mutex_exit(&sv->sv_mutex); 816 smb_server_release(sv); 817 return (EFAULT); 818 } 819 mutex_exit(&sv->sv_mutex); 820 821 if (sv->sv_cfg.skc_ipv6_enable) 822 rc = smb_server_listen(sv, &sv->sv_tcp_daemon, 823 IPPORT_SMB, AF_INET6, ioc->error); 824 else 825 rc = smb_server_listen(sv, &sv->sv_tcp_daemon, 826 IPPORT_SMB, AF_INET, ioc->error); 827 828 mutex_enter(&sv->sv_mutex); 829 sv->sv_tcp_daemon.ld_kth = NULL; 830 831 mutex_exit(&sv->sv_mutex); 832 833 smb_server_release(sv); 834 return (rc); 835 } 836 837 /* 838 * smb_server_nbt_receive 839 */ 840 int 841 smb_server_nbt_receive(void) 842 { 843 int rc; 844 smb_server_t *sv; 845 846 if ((rc = smb_server_lookup(&sv)) == 0) { 847 rc = smb_session_daemon(&sv->sv_nbt_daemon.ld_session_list); 848 smb_server_release(sv); 849 } 850 851 return (rc); 852 } 853 854 /* 855 * smb_server_tcp_receive 856 */ 857 int 858 smb_server_tcp_receive(void) 859 { 860 int rc; 861 smb_server_t *sv; 862 863 if ((rc = smb_server_lookup(&sv)) == 0) { 864 rc = smb_session_daemon(&sv->sv_tcp_daemon.ld_session_list); 865 smb_server_release(sv); 866 } 867 868 return (rc); 869 } 870 871 int 872 smb_server_set_gmtoff(smb_ioc_gmt_t *ioc) 873 { 874 int rc; 875 smb_server_t *sv; 876 877 if ((rc = smb_server_lookup(&sv)) == 0) { 878 sv->si_gmtoff = ioc->offset; 879 smb_server_release(sv); 880 } 881 882 return (rc); 883 } 884 885 int 886 smb_server_numopen(smb_ioc_opennum_t *ioc) 887 { 888 smb_server_t *sv; 889 int rc; 890 891 if ((rc = smb_server_lookup(&sv)) == 0) { 892 ioc->open_users = sv->sv_open_users; 893 ioc->open_trees = sv->sv_open_trees; 894 ioc->open_files = sv->sv_open_files; 895 smb_server_release(sv); 896 } 897 return (rc); 898 } 899 900 /* 901 * Enumerate objects within the server. The svcenum provides the 902 * enumeration context, i.e. what the caller want to get back. 903 */ 904 int 905 smb_server_enum(smb_ioc_svcenum_t *ioc) 906 { 907 smb_svcenum_t *svcenum = &ioc->svcenum; 908 smb_server_t *sv; 909 smb_session_list_t *se; 910 int rc; 911 912 switch (svcenum->se_type) { 913 case SMB_SVCENUM_TYPE_USER: 914 case SMB_SVCENUM_TYPE_TREE: 915 case SMB_SVCENUM_TYPE_FILE: 916 break; 917 default: 918 return (EINVAL); 919 } 920 921 if ((rc = smb_server_lookup(&sv)) != 0) 922 return (rc); 923 924 svcenum->se_bavail = svcenum->se_buflen; 925 svcenum->se_bused = 0; 926 svcenum->se_nitems = 0; 927 928 se = &sv->sv_nbt_daemon.ld_session_list; 929 smb_server_enum_private(se, svcenum); 930 931 se = &sv->sv_tcp_daemon.ld_session_list; 932 smb_server_enum_private(se, svcenum); 933 934 smb_server_release(sv); 935 return (0); 936 } 937 938 /* 939 * Look for sessions to disconnect by client and user name. 940 */ 941 int 942 smb_server_session_close(smb_ioc_session_t *ioc) 943 { 944 smb_session_list_t *se; 945 smb_server_t *sv; 946 int nbt_cnt; 947 int tcp_cnt; 948 int rc; 949 950 if ((rc = smb_server_lookup(&sv)) != 0) 951 return (rc); 952 953 se = &sv->sv_nbt_daemon.ld_session_list; 954 nbt_cnt = smb_server_sesion_disconnect(se, ioc->client, ioc->username); 955 956 se = &sv->sv_tcp_daemon.ld_session_list; 957 tcp_cnt = smb_server_sesion_disconnect(se, ioc->client, ioc->username); 958 959 smb_server_release(sv); 960 961 if ((nbt_cnt == 0) && (tcp_cnt == 0)) 962 return (ENOENT); 963 return (0); 964 } 965 966 /* 967 * Close a file by uniqid. 968 */ 969 int 970 smb_server_file_close(smb_ioc_fileid_t *ioc) 971 { 972 uint32_t uniqid = ioc->uniqid; 973 smb_session_list_t *se; 974 smb_server_t *sv; 975 int rc; 976 977 if ((rc = smb_server_lookup(&sv)) != 0) 978 return (rc); 979 980 se = &sv->sv_nbt_daemon.ld_session_list; 981 rc = smb_server_fclose(se, uniqid); 982 983 if (rc == ENOENT) { 984 se = &sv->sv_tcp_daemon.ld_session_list; 985 rc = smb_server_fclose(se, uniqid); 986 } 987 988 smb_server_release(sv); 989 return (rc); 990 } 991 992 /* 993 * These functions determine the relevant smb server to which the call apply. 994 */ 995 996 uint32_t 997 smb_server_get_session_count(void) 998 { 999 smb_server_t *sv; 1000 uint32_t counter = 0; 1001 1002 if (smb_server_lookup(&sv)) 1003 return (0); 1004 1005 rw_enter(&sv->sv_nbt_daemon.ld_session_list.se_lock, RW_READER); 1006 counter = sv->sv_nbt_daemon.ld_session_list.se_act.count; 1007 rw_exit(&sv->sv_nbt_daemon.ld_session_list.se_lock); 1008 rw_enter(&sv->sv_tcp_daemon.ld_session_list.se_lock, RW_READER); 1009 counter += sv->sv_tcp_daemon.ld_session_list.se_act.count; 1010 rw_exit(&sv->sv_tcp_daemon.ld_session_list.se_lock); 1011 1012 smb_server_release(sv); 1013 1014 return (counter); 1015 } 1016 1017 /* 1018 * Disconnect the specified share. 1019 * Typically called when a share has been removed. 1020 */ 1021 static void 1022 smb_server_disconnect_share(smb_session_list_t *slist, const char *sharename) 1023 { 1024 smb_session_t *session; 1025 1026 rw_enter(&slist->se_lock, RW_READER); 1027 1028 session = list_head(&slist->se_act.lst); 1029 while (session) { 1030 ASSERT(session->s_magic == SMB_SESSION_MAGIC); 1031 smb_rwx_rwenter(&session->s_lock, RW_READER); 1032 switch (session->s_state) { 1033 case SMB_SESSION_STATE_NEGOTIATED: 1034 case SMB_SESSION_STATE_OPLOCK_BREAKING: 1035 case SMB_SESSION_STATE_WRITE_RAW_ACTIVE: 1036 smb_session_disconnect_share(session, sharename); 1037 break; 1038 default: 1039 break; 1040 } 1041 smb_rwx_rwexit(&session->s_lock); 1042 session = list_next(&slist->se_act.lst, session); 1043 } 1044 1045 rw_exit(&slist->se_lock); 1046 } 1047 1048 /* 1049 * smb_server_share_export() 1050 * 1051 * This function handles kernel processing at share enable time. 1052 * 1053 * At share-enable time (LMSHRD_ADD), the file system corresponding to 1054 * the share is checked for characteristics that are required for SMB 1055 * sharing. If this check passes, then a hold is taken on the root vnode 1056 * of the file system (or a reference count on the corresponding smb_vfs_t 1057 * is bumped), preventing an unmount. (See smb_vfs_hold()). 1058 */ 1059 1060 int 1061 smb_server_share_export(smb_ioc_share_t *ioc) 1062 { 1063 smb_server_t *sv; 1064 int error = 0; 1065 smb_node_t *fnode = NULL; 1066 smb_node_t *dnode; 1067 char last_comp[MAXNAMELEN]; 1068 smb_request_t *sr; 1069 1070 if (smb_server_lookup(&sv)) 1071 return (EINVAL); 1072 1073 mutex_enter(&sv->sv_mutex); 1074 switch (sv->sv_state) { 1075 case SMB_SERVER_STATE_RUNNING: 1076 case SMB_SERVER_STATE_STOPPING: 1077 break; 1078 default: 1079 mutex_exit(&sv->sv_mutex); 1080 return (ENOTACTIVE); 1081 } 1082 mutex_exit(&sv->sv_mutex); 1083 1084 sr = smb_request_alloc(sv->sv_session, 0); 1085 if (sr == NULL) { 1086 smb_server_release(sv); 1087 return (ENOMEM); 1088 } 1089 1090 sr->user_cr = kcred; 1091 1092 error = smb_pathname_reduce(sr, kcred, ioc->path, 1093 NULL, NULL, &dnode, last_comp); 1094 1095 if (error) { 1096 smb_request_free(sr); 1097 smb_server_release(sv); 1098 return (error); 1099 } 1100 1101 error = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS, 1102 sv->si_root_smb_node, dnode, last_comp, &fnode); 1103 1104 smb_node_release(dnode); 1105 1106 if (error) { 1107 smb_request_free(sr); 1108 smb_server_release(sv); 1109 return (error); 1110 } 1111 1112 ASSERT(fnode->vp && fnode->vp->v_vfsp); 1113 1114 #ifdef SMB_ENFORCE_NODEV 1115 if (vfs_optionisset(fnode->vp->v_vfsp, MNTOPT_NODEVICES, NULL) == 0) { 1116 smb_node_release(fnode); 1117 smb_request_free(sr); 1118 smb_server_release(sv); 1119 return (EINVAL); 1120 } 1121 #endif /* SMB_ENFORCE_NODEV */ 1122 1123 if (!smb_vfs_hold(sv, fnode->vp->v_vfsp)) 1124 error = ENOMEM; 1125 1126 /* 1127 * The refcount on the smb_vfs has been incremented. 1128 * If it wasn't already, a hold has also been taken 1129 * on the root vnode of the file system. 1130 */ 1131 1132 smb_node_release(fnode); 1133 smb_request_free(sr); 1134 smb_server_release(sv); 1135 return (error); 1136 } 1137 1138 /* 1139 * smb_server_share_unexport() 1140 * 1141 * This function is invoked when a share is disabled to disconnect trees 1142 * and close files. Cleaning up may involve VOP and/or VFS calls, which 1143 * may conflict/deadlock with stuck threads if something is amiss with the 1144 * file system. Queueing the request for asynchronous processing allows the 1145 * call to return immediately so that, if the unshare is being done in the 1146 * context of a forced unmount, the forced unmount will always be able to 1147 * proceed (unblocking stuck I/O and eventually allowing all blocked unshare 1148 * processes to complete). 1149 * 1150 * The path lookup to find the root vnode of the VFS in question and the 1151 * release of this vnode are done synchronously prior to any associated 1152 * unmount. Doing these asynchronous to an associated unmount could run 1153 * the risk of a spurious EBUSY for a standard unmount or an EIO during 1154 * the path lookup due to a forced unmount finishing first. 1155 */ 1156 1157 int 1158 smb_server_share_unexport(smb_ioc_share_t *ioc) 1159 { 1160 smb_server_t *sv; 1161 smb_request_t *sr; 1162 smb_unexport_t *ux; 1163 smb_node_t *fnode = NULL; 1164 smb_node_t *dnode; 1165 char last_comp[MAXNAMELEN]; 1166 int rc; 1167 1168 if ((rc = smb_server_lookup(&sv))) 1169 return (rc); 1170 1171 mutex_enter(&sv->sv_mutex); 1172 switch (sv->sv_state) { 1173 case SMB_SERVER_STATE_RUNNING: 1174 case SMB_SERVER_STATE_STOPPING: 1175 break; 1176 default: 1177 mutex_exit(&sv->sv_mutex); 1178 return (ENOTACTIVE); 1179 } 1180 mutex_exit(&sv->sv_mutex); 1181 1182 sr = smb_request_alloc(sv->sv_session, 0); 1183 1184 if (sr == NULL) { 1185 smb_server_release(sv); 1186 return (ENOMEM); 1187 } 1188 1189 sr->user_cr = kcred; 1190 1191 rc = smb_pathname_reduce(sr, kcred, ioc->path, NULL, NULL, 1192 &dnode, last_comp); 1193 1194 if (rc) { 1195 smb_request_free(sr); 1196 smb_server_release(sv); 1197 return (rc); 1198 } 1199 1200 rc = smb_fsop_lookup(sr, kcred, SMB_FOLLOW_LINKS, sv->si_root_smb_node, 1201 dnode, last_comp, &fnode); 1202 1203 smb_node_release(dnode); 1204 smb_request_free(sr); 1205 1206 if (rc) { 1207 smb_server_release(sv); 1208 return (rc); 1209 } 1210 1211 ASSERT(fnode->vp && fnode->vp->v_vfsp); 1212 1213 smb_vfs_rele(sv, fnode->vp->v_vfsp); 1214 1215 smb_node_release(fnode); 1216 1217 ux = kmem_cache_alloc(sv->si_cache_unexport, KM_SLEEP); 1218 1219 (void) strlcpy(ux->ux_sharename, ioc->name, MAXNAMELEN); 1220 1221 smb_slist_insert_tail(&sv->sv_unexport_list, ux); 1222 smb_thread_signal(&sv->si_thread_unexport); 1223 1224 smb_server_release(sv); 1225 return (0); 1226 } 1227 1228 /* 1229 * smb_server_thread_unexport 1230 * 1231 * This function processes the unexport event list and disconnects shares 1232 * asynchronously. The function executes as a zone-specific thread. 1233 * 1234 * The server arg passed in is safe to use without a reference count, because 1235 * the server cannot be deleted until smb_thread_stop()/destroy() return, 1236 * which is also when the thread exits. 1237 */ 1238 1239 static void 1240 smb_server_thread_unexport(smb_thread_t *thread, void *arg) 1241 { 1242 smb_server_t *sv = (smb_server_t *)arg; 1243 smb_unexport_t *ux; 1244 smb_session_list_t *slist; 1245 1246 while (smb_thread_continue(thread)) { 1247 while ((ux = list_head(&sv->sv_unexport_list.sl_list)) 1248 != NULL) { 1249 smb_slist_remove(&sv->sv_unexport_list, ux); 1250 1251 slist = &sv->sv_nbt_daemon.ld_session_list; 1252 smb_server_disconnect_share(slist, ux->ux_sharename); 1253 1254 slist = &sv->sv_tcp_daemon.ld_session_list; 1255 smb_server_disconnect_share(slist, ux->ux_sharename); 1256 1257 kmem_cache_free(sv->si_cache_unexport, ux); 1258 } 1259 } 1260 } 1261 1262 /* 1263 * This is a special interface that will be utilized by ZFS to cause a share to 1264 * be added/removed. 1265 * 1266 * arg is either a lmshare_info_t or share_name from userspace. 1267 * It will need to be copied into the kernel. It is lmshare_info_t 1268 * for add operations and share_name for delete operations. 1269 */ 1270 int 1271 smb_server_share(void *arg, boolean_t add_share) 1272 { 1273 smb_server_t *sv; 1274 int rc; 1275 1276 rc = smb_server_lookup(&sv); 1277 if (rc == 0) { 1278 mutex_enter(&sv->sv_mutex); 1279 switch (sv->sv_state) { 1280 case SMB_SERVER_STATE_RUNNING: 1281 mutex_exit(&sv->sv_mutex); 1282 (void) smb_kshare_upcall(sv->sv_lmshrd, arg, add_share); 1283 break; 1284 default: 1285 mutex_exit(&sv->sv_mutex); 1286 break; 1287 } 1288 smb_server_release(sv); 1289 } 1290 return (0); 1291 } 1292 1293 /* 1294 * ***************************************************************************** 1295 * **************** Functions called from the internal layers ****************** 1296 * ***************************************************************************** 1297 * 1298 * These functions are provided the relevant smb server by the caller. 1299 */ 1300 1301 void 1302 smb_server_reconnection_check(smb_server_t *sv, smb_session_t *session) 1303 { 1304 ASSERT(sv == session->s_server); 1305 1306 smb_session_reconnection_check(&sv->sv_nbt_daemon.ld_session_list, 1307 session); 1308 smb_session_reconnection_check(&sv->sv_tcp_daemon.ld_session_list, 1309 session); 1310 } 1311 1312 void 1313 smb_server_get_cfg(smb_server_t *sv, smb_kmod_cfg_t *cfg) 1314 { 1315 rw_enter(&sv->sv_cfg_lock, RW_READER); 1316 bcopy(&sv->sv_cfg, cfg, sizeof (*cfg)); 1317 rw_exit(&sv->sv_cfg_lock); 1318 } 1319 1320 /* 1321 * ***************************************************************************** 1322 * *************************** Static Functions ******************************** 1323 * ***************************************************************************** 1324 */ 1325 1326 static void 1327 smb_server_timers(smb_thread_t *thread, void *arg) 1328 { 1329 smb_server_t *sv = (smb_server_t *)arg; 1330 1331 ASSERT(sv != NULL); 1332 1333 while (smb_thread_continue_timedwait(thread, 1 /* Seconds */)) { 1334 smb_session_timers(&sv->sv_nbt_daemon.ld_session_list); 1335 smb_session_timers(&sv->sv_tcp_daemon.ld_session_list); 1336 } 1337 } 1338 1339 /* 1340 * smb_server_kstat_init 1341 */ 1342 static int 1343 smb_server_kstat_init(smb_server_t *sv) 1344 { 1345 (void) snprintf(sv->sv_ksp_name, sizeof (sv->sv_ksp_name), "%s%d", 1346 SMBSRV_KSTAT_NAME, sv->sv_zid); 1347 1348 sv->sv_ksp = kstat_create(SMBSRV_KSTAT_MODULE, 0, sv->sv_ksp_name, 1349 SMBSRV_KSTAT_CLASS, KSTAT_TYPE_NAMED, 1350 sizeof (sv->sv_ks_data) / sizeof (kstat_named_t), 1351 KSTAT_FLAG_VIRTUAL); 1352 1353 if (sv->sv_ksp) { 1354 (void) strlcpy(sv->sv_ks_data.open_files.name, "open_files", 1355 sizeof (sv->sv_ks_data.open_files.name)); 1356 sv->sv_ks_data.open_files.data_type = KSTAT_DATA_UINT32; 1357 (void) strlcpy(sv->sv_ks_data.open_trees.name, "connections", 1358 sizeof (sv->sv_ks_data.open_trees.name)); 1359 sv->sv_ks_data.open_trees.data_type = KSTAT_DATA_UINT32; 1360 (void) strlcpy(sv->sv_ks_data.open_users.name, "sessions", 1361 sizeof (sv->sv_ks_data.open_users.name)); 1362 sv->sv_ks_data.open_users.data_type = KSTAT_DATA_UINT32; 1363 1364 mutex_init(&sv->sv_ksp_mutex, NULL, MUTEX_DEFAULT, NULL); 1365 sv->sv_ksp->ks_lock = &sv->sv_ksp_mutex; 1366 sv->sv_ksp->ks_data = (void *)&sv->sv_ks_data; 1367 sv->sv_ksp->ks_update = smb_server_kstat_update_info; 1368 kstat_install(sv->sv_ksp); 1369 } 1370 1371 /* create and initialize smb kstats - smb_dispatch stats */ 1372 smb_dispatch_kstat_init(); 1373 1374 return (0); 1375 } 1376 1377 /* 1378 * smb_server_kstat_fini 1379 */ 1380 static void 1381 smb_server_kstat_fini(smb_server_t *sv) 1382 { 1383 if (sv->sv_ksp) { 1384 kstat_delete(sv->sv_ksp); 1385 mutex_destroy(&sv->sv_ksp_mutex); 1386 sv->sv_ksp = NULL; 1387 } 1388 smb_dispatch_kstat_fini(); 1389 } 1390 1391 /* ARGSUSED */ 1392 static int 1393 smb_server_kstat_update_info(kstat_t *ksp, int rw) 1394 { 1395 smb_server_t *sv; 1396 1397 if (rw == KSTAT_WRITE) { 1398 return (EACCES); 1399 } else { 1400 ASSERT(MUTEX_HELD(ksp->ks_lock)); 1401 1402 _NOTE(LINTED("pointer cast may result in improper alignment")) 1403 sv = (smb_server_t *)((uint8_t *)(ksp->ks_data) - 1404 offsetof(smb_server_t, sv_ks_data)); 1405 1406 SMB_SERVER_VALID(sv); 1407 1408 sv->sv_ks_data.open_files.value.ui32 = sv->sv_open_files; 1409 sv->sv_ks_data.open_trees.value.ui32 = sv->sv_open_trees; 1410 sv->sv_ks_data.open_users.value.ui32 = sv->sv_open_users; 1411 } 1412 return (0); 1413 } 1414 1415 /* 1416 * The mutex of the server must have been entered before calling this function. 1417 */ 1418 static void 1419 smb_server_shutdown(smb_server_t *sv) 1420 { 1421 SMB_SERVER_VALID(sv); 1422 1423 smb_opipe_door_close(); 1424 smb_thread_stop(&sv->si_thread_timers); 1425 smb_thread_stop(&sv->si_thread_unexport); 1426 smb_kdoor_close(); 1427 smb_kshare_fini(sv->sv_lmshrd); 1428 sv->sv_lmshrd = NULL; 1429 smb_server_fsop_stop(sv); 1430 1431 if (sv->sv_session) { 1432 smb_session_delete(sv->sv_session); 1433 sv->sv_session = NULL; 1434 } 1435 1436 if (sv->sv_thread_pool) { 1437 taskq_destroy(sv->sv_thread_pool); 1438 sv->sv_thread_pool = NULL; 1439 } 1440 } 1441 1442 static int 1443 smb_server_listen( 1444 smb_server_t *sv, 1445 smb_listener_daemon_t *ld, 1446 in_port_t port, 1447 int family, 1448 int pthread_create_error) 1449 { 1450 int rc = 0; 1451 ksocket_t s_so; 1452 uint32_t on; 1453 uint32_t off; 1454 uint32_t txbuf_size; 1455 smb_session_t *session; 1456 1457 if (pthread_create_error) { 1458 /* 1459 * Delete the last session created. The user space thread 1460 * creation failed. 1461 */ 1462 smb_session_list_delete_tail(&ld->ld_session_list); 1463 } 1464 1465 if (ld->ld_so == NULL) { 1466 /* First time listener */ 1467 if (family == AF_INET) { 1468 ld->ld_sin.sin_family = (uint32_t)family; 1469 ld->ld_sin.sin_port = htons(port); 1470 ld->ld_sin.sin_addr.s_addr = htonl(INADDR_ANY); 1471 } else { 1472 ld->ld_sin6.sin6_family = (uint32_t)family; 1473 ld->ld_sin6.sin6_port = htons(port); 1474 (void) memset(&ld->ld_sin6.sin6_addr.s6_addr, 0, 1475 sizeof (ld->ld_sin6.sin6_addr.s6_addr)); 1476 } 1477 1478 ld->ld_so = smb_socreate(family, SOCK_STREAM, 0); 1479 if (ld->ld_so == NULL) { 1480 cmn_err(CE_WARN, "port %d: socket create failed", port); 1481 return (ENOMEM); 1482 } 1483 1484 off = 0; 1485 (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET, 1486 SO_MAC_EXEMPT, &off, sizeof (off), CRED()); 1487 1488 on = 1; 1489 (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET, 1490 SO_REUSEADDR, &on, sizeof (on), CRED()); 1491 1492 if (family == AF_INET) { 1493 rc = ksocket_bind(ld->ld_so, 1494 (struct sockaddr *)&ld->ld_sin, 1495 sizeof (ld->ld_sin), CRED()); 1496 } else { 1497 rc = ksocket_bind(ld->ld_so, 1498 (struct sockaddr *)&ld->ld_sin6, 1499 sizeof (ld->ld_sin6), CRED()); 1500 } 1501 1502 if (rc != 0) { 1503 cmn_err(CE_WARN, "port %d: bind failed (%d)", port, rc); 1504 smb_server_listen_fini(ld); 1505 return (rc); 1506 } 1507 1508 rc = ksocket_listen(ld->ld_so, 20, CRED()); 1509 if (rc < 0) { 1510 cmn_err(CE_WARN, "port %d: listen failed", port); 1511 smb_server_listen_fini(ld); 1512 return (rc); 1513 } 1514 } 1515 1516 DTRACE_PROBE1(so__wait__accept, struct sonode *, ld->ld_so); 1517 1518 for (;;) { 1519 if (smb_server_is_stopping()) { 1520 rc = ECANCELED; 1521 break; 1522 } 1523 1524 rc = ksocket_accept(ld->ld_so, NULL, NULL, &s_so, CRED()); 1525 if (rc != 0) 1526 break; 1527 1528 if (smb_server_is_stopping()) { 1529 smb_soshutdown(s_so); 1530 smb_sodestroy(s_so); 1531 rc = ECANCELED; 1532 break; 1533 } 1534 1535 DTRACE_PROBE1(so__accept, struct sonode *, s_so); 1536 1537 on = 1; 1538 (void) ksocket_setsockopt(s_so, IPPROTO_TCP, TCP_NODELAY, 1539 &on, sizeof (on), CRED()); 1540 1541 on = 1; 1542 (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_KEEPALIVE, 1543 &on, sizeof (on), CRED()); 1544 1545 txbuf_size = 128*1024; 1546 (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_SNDBUF, 1547 (const void *)&txbuf_size, sizeof (txbuf_size), CRED()); 1548 1549 /* 1550 * Create a session for this connection. 1551 */ 1552 session = smb_session_create(s_so, port, sv, family); 1553 if (session) { 1554 smb_session_list_append(&ld->ld_session_list, session); 1555 rc = 0; 1556 break; 1557 } else { 1558 smb_soshutdown(s_so); 1559 smb_sodestroy(s_so); 1560 } 1561 } 1562 1563 if (rc != 0) 1564 smb_server_listen_fini(ld); 1565 1566 return (rc); 1567 } 1568 1569 static void 1570 smb_server_listen_fini(smb_listener_daemon_t *ld) 1571 { 1572 if (ld->ld_so != NULL) { 1573 smb_session_list_signal(&ld->ld_session_list); 1574 smb_soshutdown(ld->ld_so); 1575 smb_sodestroy(ld->ld_so); 1576 ld->ld_so = NULL; 1577 } 1578 } 1579 1580 static kt_did_t 1581 smb_server_listener_tid(smb_listener_daemon_t *ld) 1582 { 1583 kt_did_t tid; 1584 1585 if (ld->ld_ktdid != 0) { 1586 tid = ld->ld_ktdid; 1587 ld->ld_ktdid = 0; 1588 } 1589 1590 return (tid); 1591 } 1592 1593 /* 1594 * smb_server_lookup 1595 * 1596 * This function tries to find the server associated with the zone of the 1597 * caller. 1598 */ 1599 static int 1600 smb_server_lookup(smb_server_t **psv) 1601 { 1602 zoneid_t zid; 1603 smb_server_t *sv; 1604 1605 zid = getzoneid(); 1606 1607 smb_llist_enter(&smb_servers, RW_READER); 1608 sv = smb_llist_head(&smb_servers); 1609 while (sv) { 1610 SMB_SERVER_VALID(sv); 1611 if (sv->sv_zid == zid) { 1612 mutex_enter(&sv->sv_mutex); 1613 if (sv->sv_state != SMB_SERVER_STATE_DELETING) { 1614 sv->sv_refcnt++; 1615 mutex_exit(&sv->sv_mutex); 1616 smb_llist_exit(&smb_servers); 1617 *psv = sv; 1618 return (0); 1619 } 1620 mutex_exit(&sv->sv_mutex); 1621 break; 1622 } 1623 sv = smb_llist_next(&smb_servers, sv); 1624 } 1625 smb_llist_exit(&smb_servers); 1626 return (EPERM); 1627 } 1628 1629 /* 1630 * smb_server_release 1631 * 1632 * This function decrements the reference count of the server and signals its 1633 * condition variable if the state of the server is SMB_SERVER_STATE_DELETING. 1634 */ 1635 static void 1636 smb_server_release(smb_server_t *sv) 1637 { 1638 SMB_SERVER_VALID(sv); 1639 1640 mutex_enter(&sv->sv_mutex); 1641 ASSERT(sv->sv_refcnt); 1642 sv->sv_refcnt--; 1643 if ((sv->sv_refcnt == 0) && (sv->sv_state == SMB_SERVER_STATE_DELETING)) 1644 cv_signal(&sv->sv_cv); 1645 mutex_exit(&sv->sv_mutex); 1646 } 1647 1648 /* 1649 * Enumerate the users associated with a session list. 1650 */ 1651 static void 1652 smb_server_enum_private(smb_session_list_t *se, smb_svcenum_t *svcenum) 1653 { 1654 smb_session_t *sn; 1655 smb_llist_t *ulist; 1656 smb_user_t *user; 1657 int rc = 0; 1658 1659 rw_enter(&se->se_lock, RW_READER); 1660 sn = list_head(&se->se_act.lst); 1661 1662 while (sn != NULL) { 1663 ASSERT(sn->s_magic == SMB_SESSION_MAGIC); 1664 ulist = &sn->s_user_list; 1665 smb_llist_enter(ulist, RW_READER); 1666 user = smb_llist_head(ulist); 1667 1668 while (user != NULL) { 1669 if (smb_user_hold(user)) { 1670 rc = smb_user_enum(user, svcenum); 1671 smb_user_release(user); 1672 } 1673 1674 user = smb_llist_next(ulist, user); 1675 } 1676 1677 smb_llist_exit(ulist); 1678 1679 if (rc != 0) 1680 break; 1681 1682 sn = list_next(&se->se_act.lst, sn); 1683 } 1684 1685 rw_exit(&se->se_lock); 1686 } 1687 1688 /* 1689 * Disconnect sessions associated with the specified client and username. 1690 * Empty strings are treated as wildcards. 1691 */ 1692 static int 1693 smb_server_sesion_disconnect(smb_session_list_t *se, 1694 const char *client, const char *name) 1695 { 1696 smb_session_t *sn; 1697 smb_llist_t *ulist; 1698 smb_user_t *user; 1699 boolean_t match; 1700 int count = 0; 1701 1702 rw_enter(&se->se_lock, RW_READER); 1703 sn = list_head(&se->se_act.lst); 1704 1705 while (sn != NULL) { 1706 ASSERT(sn->s_magic == SMB_SESSION_MAGIC); 1707 1708 if ((*client != '\0') && (!smb_session_isclient(sn, client))) { 1709 sn = list_next(&se->se_act.lst, sn); 1710 continue; 1711 } 1712 1713 ulist = &sn->s_user_list; 1714 smb_llist_enter(ulist, RW_READER); 1715 user = smb_llist_head(ulist); 1716 1717 while (user != NULL) { 1718 if (smb_user_hold(user)) { 1719 match = (*name == '\0'); 1720 if (!match) 1721 match = smb_user_namecmp(user, name); 1722 1723 if (match) { 1724 smb_llist_exit(ulist); 1725 smb_user_logoff(user); 1726 ++count; 1727 smb_user_release(user); 1728 smb_llist_enter(ulist, RW_READER); 1729 user = smb_llist_head(ulist); 1730 continue; 1731 } 1732 1733 smb_user_release(user); 1734 } 1735 1736 user = smb_llist_next(ulist, user); 1737 } 1738 1739 smb_llist_exit(ulist); 1740 sn = list_next(&se->se_act.lst, sn); 1741 } 1742 1743 rw_exit(&se->se_lock); 1744 return (count); 1745 } 1746 1747 /* 1748 * Close a file by its unique id. 1749 */ 1750 static int 1751 smb_server_fclose(smb_session_list_t *se, uint32_t uniqid) 1752 { 1753 smb_session_t *sn; 1754 smb_llist_t *ulist; 1755 smb_user_t *user; 1756 int rc = ENOENT; 1757 1758 rw_enter(&se->se_lock, RW_READER); 1759 sn = list_head(&se->se_act.lst); 1760 1761 while ((sn != NULL) && (rc == ENOENT)) { 1762 ASSERT(sn->s_magic == SMB_SESSION_MAGIC); 1763 ulist = &sn->s_user_list; 1764 smb_llist_enter(ulist, RW_READER); 1765 user = smb_llist_head(ulist); 1766 1767 while ((user != NULL) && (rc == ENOENT)) { 1768 if (smb_user_hold(user)) { 1769 rc = smb_user_fclose(user, uniqid); 1770 smb_user_release(user); 1771 } 1772 1773 user = smb_llist_next(ulist, user); 1774 } 1775 1776 smb_llist_exit(ulist); 1777 sn = list_next(&se->se_act.lst, sn); 1778 } 1779 1780 rw_exit(&se->se_lock); 1781 return (rc); 1782 } 1783 1784 static void 1785 smb_server_store_cfg(smb_server_t *sv, smb_ioc_cfg_t *ioc) 1786 { 1787 if (ioc->maxconnections == 0) 1788 ioc->maxconnections = 0xFFFFFFFF; 1789 1790 smb_session_correct_keep_alive_values( 1791 &sv->sv_nbt_daemon.ld_session_list, ioc->keepalive); 1792 smb_session_correct_keep_alive_values( 1793 &sv->sv_tcp_daemon.ld_session_list, ioc->keepalive); 1794 1795 sv->sv_cfg.skc_maxworkers = ioc->maxworkers; 1796 sv->sv_cfg.skc_maxconnections = ioc->maxconnections; 1797 sv->sv_cfg.skc_keepalive = ioc->keepalive; 1798 sv->sv_cfg.skc_restrict_anon = ioc->restrict_anon; 1799 sv->sv_cfg.skc_signing_enable = ioc->signing_enable; 1800 sv->sv_cfg.skc_signing_required = ioc->signing_required; 1801 sv->sv_cfg.skc_oplock_enable = ioc->oplock_enable; 1802 sv->sv_cfg.skc_sync_enable = ioc->sync_enable; 1803 sv->sv_cfg.skc_secmode = ioc->secmode; 1804 sv->sv_cfg.skc_ipv6_enable = ioc->ipv6_enable; 1805 (void) strlcpy(sv->sv_cfg.skc_nbdomain, ioc->nbdomain, 1806 sizeof (sv->sv_cfg.skc_nbdomain)); 1807 (void) strlcpy(sv->sv_cfg.skc_fqdn, ioc->fqdn, 1808 sizeof (sv->sv_cfg.skc_fqdn)); 1809 (void) strlcpy(sv->sv_cfg.skc_hostname, ioc->hostname, 1810 sizeof (sv->sv_cfg.skc_hostname)); 1811 (void) strlcpy(sv->sv_cfg.skc_system_comment, ioc->system_comment, 1812 sizeof (sv->sv_cfg.skc_system_comment)); 1813 } 1814 1815 static int 1816 smb_server_fsop_start(smb_server_t *sv) 1817 { 1818 int error; 1819 1820 error = smb_node_root_init(rootdir, sv, &sv->si_root_smb_node); 1821 if (error != 0) 1822 sv->si_root_smb_node = NULL; 1823 1824 return (error); 1825 } 1826 1827 static void 1828 smb_server_fsop_stop(smb_server_t *sv) 1829 { 1830 if (sv->si_root_smb_node != NULL) { 1831 smb_vfs_rele_all(sv); 1832 smb_node_release(sv->si_root_smb_node); 1833 sv->si_root_smb_node = NULL; 1834 } 1835 } 1836 1837 static void 1838 smb_server_signal_listeners(smb_server_t *sv) 1839 { 1840 SMB_SERVER_VALID(sv); 1841 ASSERT(sv->sv_state == SMB_SERVER_STATE_STOPPING); 1842 ASSERT(MUTEX_HELD(&sv->sv_mutex)); 1843 1844 smb_event_cancel(sv, 0); 1845 1846 if (sv->sv_nbt_daemon.ld_kth != NULL) { 1847 tsignal(sv->sv_nbt_daemon.ld_kth, SIGINT); 1848 sv->sv_nbt_daemon.ld_kth = NULL; 1849 } 1850 1851 if (sv->sv_tcp_daemon.ld_kth != NULL) { 1852 tsignal(sv->sv_tcp_daemon.ld_kth, SIGINT); 1853 sv->sv_tcp_daemon.ld_kth = NULL; 1854 } 1855 } 1856 1857 smb_event_t * 1858 smb_event_create(void) 1859 { 1860 smb_server_t *sv; 1861 smb_event_t *event; 1862 1863 if (smb_server_is_stopping()) 1864 return (NULL); 1865 1866 if (smb_server_lookup(&sv) != 0) { 1867 cmn_err(CE_NOTE, "smb_event_create failed"); 1868 return (NULL); 1869 } 1870 1871 event = kmem_cache_alloc(sv->si_cache_event, KM_SLEEP); 1872 1873 bzero(event, sizeof (smb_event_t)); 1874 mutex_init(&event->se_mutex, NULL, MUTEX_DEFAULT, NULL); 1875 cv_init(&event->se_cv, NULL, CV_DEFAULT, NULL); 1876 event->se_magic = SMB_EVENT_MAGIC; 1877 event->se_txid = smb_event_alloc_txid(); 1878 event->se_server = sv; 1879 1880 smb_llist_enter(&sv->sv_event_list, RW_WRITER); 1881 smb_llist_insert_tail(&sv->sv_event_list, event); 1882 smb_llist_exit(&sv->sv_event_list); 1883 1884 smb_server_release(sv); 1885 return (event); 1886 } 1887 1888 void 1889 smb_event_destroy(smb_event_t *event) 1890 { 1891 smb_server_t *sv; 1892 1893 if (event == NULL) 1894 return; 1895 1896 SMB_EVENT_VALID(event); 1897 ASSERT(event->se_waittime == 0); 1898 1899 if (smb_server_lookup(&sv) != 0) 1900 return; 1901 1902 smb_llist_enter(&sv->sv_event_list, RW_WRITER); 1903 smb_llist_remove(&sv->sv_event_list, event); 1904 smb_llist_exit(&sv->sv_event_list); 1905 1906 event->se_magic = (uint32_t)~SMB_EVENT_MAGIC; 1907 cv_destroy(&event->se_cv); 1908 mutex_destroy(&event->se_mutex); 1909 1910 kmem_cache_free(sv->si_cache_event, event); 1911 smb_server_release(sv); 1912 } 1913 1914 /* 1915 * Get the txid for the specified event. 1916 */ 1917 uint32_t 1918 smb_event_txid(smb_event_t *event) 1919 { 1920 if (event != NULL) { 1921 SMB_EVENT_VALID(event); 1922 return (event->se_txid); 1923 } 1924 1925 cmn_err(CE_NOTE, "smb_event_txid failed"); 1926 return ((uint32_t)-1); 1927 } 1928 1929 /* 1930 * Wait for event notification. 1931 */ 1932 int 1933 smb_event_wait(smb_event_t *event) 1934 { 1935 int seconds = 1; 1936 int ticks; 1937 1938 if (event == NULL) 1939 return (EINVAL); 1940 1941 SMB_EVENT_VALID(event); 1942 1943 mutex_enter(&event->se_mutex); 1944 event->se_waittime = 1; 1945 event->se_errno = 0; 1946 1947 while (!(event->se_notified)) { 1948 if (smb_event_debug && ((event->se_waittime % 30) == 0)) 1949 cmn_err(CE_NOTE, "smb_event_wait[%d] (%d sec)", 1950 event->se_txid, event->se_waittime); 1951 1952 if (event->se_errno != 0) 1953 break; 1954 1955 if (event->se_waittime > SMB_EVENT_TIMEOUT) { 1956 event->se_errno = ETIME; 1957 break; 1958 } 1959 1960 ticks = SEC_TO_TICK(seconds); 1961 (void) cv_reltimedwait(&event->se_cv, 1962 &event->se_mutex, (clock_t)ticks, TR_CLOCK_TICK); 1963 ++event->se_waittime; 1964 } 1965 1966 event->se_waittime = 0; 1967 event->se_notified = B_FALSE; 1968 cv_signal(&event->se_cv); 1969 mutex_exit(&event->se_mutex); 1970 return (event->se_errno); 1971 } 1972 1973 /* 1974 * If txid is non-zero, cancel the specified event. 1975 * Otherwise, cancel all events. 1976 */ 1977 static void 1978 smb_event_cancel(smb_server_t *sv, uint32_t txid) 1979 { 1980 smb_event_t *event; 1981 smb_llist_t *event_list; 1982 1983 SMB_SERVER_VALID(sv); 1984 1985 event_list = &sv->sv_event_list; 1986 smb_llist_enter(event_list, RW_WRITER); 1987 1988 event = smb_llist_head(event_list); 1989 while (event) { 1990 SMB_EVENT_VALID(event); 1991 1992 if (txid == 0 || event->se_txid == txid) { 1993 mutex_enter(&event->se_mutex); 1994 event->se_errno = ECANCELED; 1995 event->se_notified = B_TRUE; 1996 cv_signal(&event->se_cv); 1997 mutex_exit(&event->se_mutex); 1998 1999 if (txid != 0) 2000 break; 2001 } 2002 2003 event = smb_llist_next(event_list, event); 2004 } 2005 2006 smb_llist_exit(event_list); 2007 } 2008 2009 /* 2010 * If txid is non-zero, notify the specified event. 2011 * Otherwise, notify all events. 2012 */ 2013 static void 2014 smb_event_notify(smb_server_t *sv, uint32_t txid) 2015 { 2016 smb_event_t *event; 2017 smb_llist_t *event_list; 2018 2019 SMB_SERVER_VALID(sv); 2020 2021 event_list = &sv->sv_event_list; 2022 smb_llist_enter(event_list, RW_READER); 2023 2024 event = smb_llist_head(event_list); 2025 while (event) { 2026 SMB_EVENT_VALID(event); 2027 2028 if (txid == 0 || event->se_txid == txid) { 2029 mutex_enter(&event->se_mutex); 2030 event->se_notified = B_TRUE; 2031 cv_signal(&event->se_cv); 2032 mutex_exit(&event->se_mutex); 2033 2034 if (txid != 0) 2035 break; 2036 } 2037 2038 event = smb_llist_next(event_list, event); 2039 } 2040 2041 smb_llist_exit(event_list); 2042 } 2043 2044 /* 2045 * Allocate a new transaction id (txid). 2046 * 2047 * 0 or -1 are not assigned because they are used to detect invalid 2048 * conditions or to indicate all open id's. 2049 */ 2050 static uint32_t 2051 smb_event_alloc_txid(void) 2052 { 2053 static kmutex_t txmutex; 2054 static uint32_t txid; 2055 uint32_t txid_ret; 2056 2057 mutex_enter(&txmutex); 2058 2059 if (txid == 0) 2060 txid = ddi_get_lbolt() << 11; 2061 2062 do { 2063 ++txid; 2064 } while (txid == 0 || txid == (uint32_t)-1); 2065 2066 txid_ret = txid; 2067 mutex_exit(&txmutex); 2068 2069 return (txid_ret); 2070 } 2071