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