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 2008 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 * +-----------------------------+ 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 <smbsrv/smb_kproto.h> 219 #include <smbsrv/netbios.h> 220 #include <smbsrv/smb_incl.h> 221 #include <smbsrv/cifs.h> 222 #include <smbsrv/smb_fsops.h> 223 #include <smbsrv/smb_share.h> 224 #include <smbsrv/smb_door_svc.h> 225 #include <smbsrv/smb_kstat.h> 226 227 extern void smb_dispatch_kstat_init(void); 228 extern void smb_dispatch_kstat_fini(void); 229 extern void smb_reply_notify_change_request(smb_request_t *); 230 231 static int smb_server_kstat_init(smb_server_t *); 232 static void smb_server_kstat_fini(smb_server_t *); 233 static int smb_server_kstat_update_info(kstat_t *, int); 234 static void smb_server_timers(smb_thread_t *, void *); 235 static int smb_server_listen(smb_server_t *, smb_listener_daemon_t *, 236 in_port_t, int); 237 static int smb_server_lookup(smb_server_t **); 238 static void smb_server_release(smb_server_t *); 239 static int smb_server_ulist_geti(smb_session_list_t *, int, 240 smb_opipe_context_t *, int); 241 static void smb_server_store_cfg(smb_server_t *, smb_kmod_cfg_t *); 242 static void smb_server_stop(smb_server_t *); 243 static int smb_server_fsop_start(smb_server_t *); 244 static void smb_server_fsop_stop(smb_server_t *); 245 246 static smb_llist_t smb_servers; 247 248 /* 249 * ***************************************************************************** 250 * **************** Functions called from the device interface ***************** 251 * ***************************************************************************** 252 * 253 * These functions determine the relevant smb server to which the call apply. 254 */ 255 256 /* 257 * smb_server_svc_init 258 * 259 * This function must be called from smb_drv_attach(). 260 */ 261 int 262 smb_server_svc_init(void) 263 { 264 int rc = 0; 265 266 while (rc == 0) { 267 if (rc = smb_vop_init()) 268 continue; 269 if (rc = smb_node_init()) 270 continue; 271 if (rc = smb_fem_init()) 272 continue; 273 if (rc = smb_user_init()) 274 continue; 275 if (rc = smb_notify_init()) 276 continue; 277 if (rc = smb_net_init()) 278 continue; 279 if (rc = smb_kdoor_srv_start()) 280 continue; 281 smb_llist_constructor(&smb_servers, sizeof (smb_server_t), 282 offsetof(smb_server_t, sv_lnd)); 283 return (0); 284 } 285 smb_net_fini(); 286 smb_notify_fini(); 287 smb_user_fini(); 288 smb_fem_fini(); 289 smb_node_fini(); 290 smb_vop_fini(); 291 return (rc); 292 } 293 294 /* 295 * smb_server_svc_fini 296 * 297 * This function must called from smb_drv_detach(). It will fail if servers 298 * still exist. 299 */ 300 int 301 smb_server_svc_fini(void) 302 { 303 int rc = EBUSY; 304 305 if (smb_llist_get_count(&smb_servers) == 0) { 306 smb_kdoor_srv_stop(); 307 smb_net_fini(); 308 smb_notify_fini(); 309 smb_user_fini(); 310 smb_fem_fini(); 311 smb_node_fini(); 312 smb_vop_fini(); 313 smb_llist_destructor(&smb_servers); 314 rc = 0; 315 } 316 return (rc); 317 } 318 319 /* 320 * smb_server_create 321 * 322 * This function will fail if there's already a server associated with the 323 * caller's zone. 324 */ 325 int 326 smb_server_create(void) 327 { 328 zoneid_t zid; 329 smb_server_t *sv; 330 331 zid = getzoneid(); 332 333 smb_llist_enter(&smb_servers, RW_WRITER); 334 sv = smb_llist_head(&smb_servers); 335 while (sv) { 336 ASSERT(sv->sv_magic == SMB_SERVER_MAGIC); 337 if (sv->sv_zid == zid) { 338 smb_llist_exit(&smb_servers); 339 return (EEXIST); 340 } 341 sv = smb_llist_next(&smb_servers, sv); 342 } 343 344 sv = kmem_zalloc(sizeof (smb_server_t), KM_NOSLEEP); 345 if (sv == NULL) { 346 smb_llist_exit(&smb_servers); 347 return (ENOMEM); 348 } 349 350 smb_llist_constructor(&sv->sv_vfs_list, sizeof (smb_vfs_t), 351 offsetof(smb_vfs_t, sv_lnd)); 352 353 smb_session_list_constructor(&sv->sv_nbt_daemon.ld_session_list); 354 smb_session_list_constructor(&sv->sv_tcp_daemon.ld_session_list); 355 356 sv->si_cache_vfs = kmem_cache_create("smb_vfs_cache", 357 sizeof (smb_vfs_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 358 sv->si_cache_request = kmem_cache_create("smb_request_cache", 359 sizeof (smb_request_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 360 sv->si_cache_session = kmem_cache_create("smb_session_cache", 361 sizeof (smb_session_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 362 sv->si_cache_user = kmem_cache_create("smb_user_cache", 363 sizeof (smb_user_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 364 sv->si_cache_tree = kmem_cache_create("smb_tree_cache", 365 sizeof (smb_tree_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 366 sv->si_cache_ofile = kmem_cache_create("smb_ofile_cache", 367 sizeof (smb_ofile_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 368 sv->si_cache_odir = kmem_cache_create("smb_odir_cache", 369 sizeof (smb_odir_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 370 sv->si_cache_node = kmem_cache_create("smb_node_cache", 371 sizeof (smb_node_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 372 373 smb_thread_init(&sv->si_thread_timers, 374 "smb_timers", smb_server_timers, sv, 375 NULL, NULL); 376 377 sv->sv_pid = curproc->p_pid; 378 379 smb_kdoor_clnt_init(); 380 smb_opipe_door_init(); 381 (void) smb_server_kstat_init(sv); 382 383 mutex_init(&sv->sv_mutex, NULL, MUTEX_DEFAULT, NULL); 384 cv_init(&sv->sv_cv, NULL, CV_DEFAULT, NULL); 385 sv->sv_state = SMB_SERVER_STATE_CREATED; 386 sv->sv_magic = SMB_SERVER_MAGIC; 387 sv->sv_zid = zid; 388 389 smb_llist_insert_tail(&smb_servers, sv); 390 smb_llist_exit(&smb_servers); 391 return (0); 392 } 393 394 /* 395 * smb_server_delete 396 * 397 * This function will delete the server passed in. It will make sure that all 398 * activity associated that server has ceased before destroying it. 399 */ 400 int 401 smb_server_delete(void) 402 { 403 smb_server_t *sv; 404 int rc; 405 406 rc = smb_server_lookup(&sv); 407 if (rc != 0) 408 return (rc); 409 410 mutex_enter(&sv->sv_mutex); 411 switch (sv->sv_state) { 412 case SMB_SERVER_STATE_RUNNING: 413 { 414 boolean_t nbt = B_FALSE; 415 boolean_t tcp = B_FALSE; 416 417 if (sv->sv_nbt_daemon.ld_kth) { 418 tsignal(sv->sv_nbt_daemon.ld_kth, SIGINT); 419 nbt = B_TRUE; 420 } 421 if (sv->sv_tcp_daemon.ld_kth) { 422 tsignal(sv->sv_tcp_daemon.ld_kth, SIGINT); 423 tcp = B_TRUE; 424 } 425 sv->sv_state = SMB_SERVER_STATE_DELETING; 426 mutex_exit(&sv->sv_mutex); 427 if (nbt) 428 thread_join(sv->sv_nbt_daemon.ld_ktdid); 429 if (tcp) 430 thread_join(sv->sv_tcp_daemon.ld_ktdid); 431 mutex_enter(&sv->sv_mutex); 432 break; 433 } 434 case SMB_SERVER_STATE_CONFIGURED: 435 case SMB_SERVER_STATE_CREATED: 436 sv->sv_state = SMB_SERVER_STATE_DELETING; 437 break; 438 default: 439 ASSERT(sv->sv_state == SMB_SERVER_STATE_DELETING); 440 mutex_exit(&sv->sv_mutex); 441 smb_server_release(sv); 442 return (ENOTTY); 443 } 444 445 ASSERT(sv->sv_state == SMB_SERVER_STATE_DELETING); 446 447 sv->sv_refcnt--; 448 while (sv->sv_refcnt) 449 cv_wait(&sv->sv_cv, &sv->sv_mutex); 450 451 mutex_exit(&sv->sv_mutex); 452 453 smb_llist_enter(&smb_servers, RW_WRITER); 454 smb_llist_remove(&smb_servers, sv); 455 smb_llist_exit(&smb_servers); 456 457 smb_server_stop(sv); 458 rw_destroy(&sv->sv_cfg_lock); 459 smb_opipe_door_fini(); 460 smb_kdoor_clnt_fini(); 461 smb_server_kstat_fini(sv); 462 smb_llist_destructor(&sv->sv_vfs_list); 463 kmem_cache_destroy(sv->si_cache_vfs); 464 kmem_cache_destroy(sv->si_cache_request); 465 kmem_cache_destroy(sv->si_cache_session); 466 kmem_cache_destroy(sv->si_cache_user); 467 kmem_cache_destroy(sv->si_cache_tree); 468 kmem_cache_destroy(sv->si_cache_ofile); 469 kmem_cache_destroy(sv->si_cache_odir); 470 kmem_cache_destroy(sv->si_cache_node); 471 472 smb_thread_destroy(&sv->si_thread_timers); 473 mutex_destroy(&sv->sv_mutex); 474 cv_destroy(&sv->sv_cv); 475 sv->sv_magic = 0; 476 kmem_free(sv, sizeof (smb_server_t)); 477 478 return (0); 479 } 480 481 /* 482 * smb_server_configure 483 */ 484 int 485 smb_server_configure(smb_kmod_cfg_t *cfg) 486 { 487 int rc = 0; 488 smb_server_t *sv; 489 490 rc = smb_server_lookup(&sv); 491 if (rc) 492 return (rc); 493 494 mutex_enter(&sv->sv_mutex); 495 switch (sv->sv_state) { 496 case SMB_SERVER_STATE_CREATED: 497 smb_server_store_cfg(sv, cfg); 498 sv->sv_state = SMB_SERVER_STATE_CONFIGURED; 499 break; 500 501 case SMB_SERVER_STATE_CONFIGURED: 502 smb_server_store_cfg(sv, cfg); 503 break; 504 505 case SMB_SERVER_STATE_RUNNING: 506 rw_enter(&sv->sv_cfg_lock, RW_WRITER); 507 smb_server_store_cfg(sv, cfg); 508 rw_exit(&sv->sv_cfg_lock); 509 break; 510 511 default: 512 ASSERT(sv->sv_state == SMB_SERVER_STATE_DELETING); 513 rc = EFAULT; 514 break; 515 } 516 mutex_exit(&sv->sv_mutex); 517 518 smb_server_release(sv); 519 520 return (rc); 521 } 522 523 /* 524 * smb_server_start 525 */ 526 int 527 smb_server_start(struct smb_io_start *io_start) 528 { 529 int rc = 0; 530 smb_server_t *sv; 531 532 rc = smb_server_lookup(&sv); 533 if (rc) 534 return (rc); 535 536 mutex_enter(&sv->sv_mutex); 537 switch (sv->sv_state) { 538 case SMB_SERVER_STATE_CONFIGURED: 539 540 sv->sv_thread_pool = taskq_create("smb_workers", 541 sv->sv_cfg.skc_maxworkers, SMB_WORKER_PRIORITY, 542 sv->sv_cfg.skc_maxworkers, INT_MAX, 543 TASKQ_DYNAMIC|TASKQ_PREPOPULATE); 544 545 sv->sv_session = smb_session_create(NULL, 0, sv); 546 547 if (sv->sv_thread_pool == NULL || sv->sv_session == NULL) { 548 rc = ENOMEM; 549 break; 550 } 551 552 if (rc = smb_server_fsop_start(sv)) 553 break; 554 ASSERT(sv->sv_lmshrd == NULL); 555 sv->sv_lmshrd = smb_kshare_init(io_start->lmshrd); 556 if (sv->sv_lmshrd == NULL) 557 break; 558 if (rc = smb_kdoor_clnt_open(io_start->udoor)) 559 break; 560 if (rc = smb_kdoor_srv_set_downcall()) { 561 cmn_err(CE_WARN, "Cannot set downcall descriptor"); 562 break; 563 } 564 if (rc = smb_thread_start(&sv->si_thread_timers)) 565 break; 566 /* 567 * XXX We give up the NET_MAC_AWARE privilege because it keeps 568 * us from re-opening the connection when there are leftover TCP 569 * connections in TCPS_TIME_WAIT state. There seem to be some 570 * security ramifications around reestablishing a connection 571 * while possessing the NET_MAC_AWARE privilege. 572 * 573 * This approach may cause problems when we try to support 574 * zones. An alternative would be to retry the connection setup 575 * for a fixed period of time until the stale connections clear 576 * up but that implies we would be offline for a couple minutes 577 * every time the service is restarted with active connections. 578 */ 579 rc = setpflags(NET_MAC_AWARE, 0, CRED()); 580 if (rc) { 581 cmn_err(CE_WARN, 582 "Cannot remove NET_MAC_AWARE privilege"); 583 break; 584 } 585 if (rc = smb_opipe_door_open(io_start->opipe)) { 586 cmn_err(CE_WARN, "Cannot open opipe door"); 587 break; 588 } 589 sv->sv_state = SMB_SERVER_STATE_RUNNING; 590 mutex_exit(&sv->sv_mutex); 591 smb_server_release(sv); 592 return (0); 593 default: 594 ASSERT((sv->sv_state == SMB_SERVER_STATE_CREATED) || 595 (sv->sv_state == SMB_SERVER_STATE_RUNNING) || 596 (sv->sv_state == SMB_SERVER_STATE_DELETING)); 597 mutex_exit(&sv->sv_mutex); 598 smb_server_release(sv); 599 return (ENOTTY); 600 } 601 602 smb_server_stop(sv); 603 mutex_exit(&sv->sv_mutex); 604 smb_server_release(sv); 605 return (rc); 606 } 607 608 /* 609 * smb_server_nbt_listen: SMB-over-NetBIOS service 610 * 611 * Traditional SMB service over NetBIOS (port 139), which requires 612 * that a NetBIOS session be established. 613 */ 614 int 615 smb_server_nbt_listen(int error) 616 { 617 smb_server_t *sv; 618 int rc; 619 620 rc = smb_server_lookup(&sv); 621 if (rc) 622 return (rc); 623 624 mutex_enter(&sv->sv_mutex); 625 switch (sv->sv_state) { 626 case SMB_SERVER_STATE_RUNNING: 627 if ((sv->sv_nbt_daemon.ld_kth != NULL) && 628 (sv->sv_nbt_daemon.ld_kth != curthread)) { 629 mutex_exit(&sv->sv_mutex); 630 return (EACCES); 631 } else { 632 sv->sv_nbt_daemon.ld_kth = curthread; 633 sv->sv_nbt_daemon.ld_ktdid = curthread->t_did; 634 } 635 break; 636 default: 637 ASSERT((sv->sv_state == SMB_SERVER_STATE_CREATED) || 638 (sv->sv_state == SMB_SERVER_STATE_CONFIGURED) || 639 (sv->sv_state == SMB_SERVER_STATE_DELETING)); 640 mutex_exit(&sv->sv_mutex); 641 smb_server_release(sv); 642 return (EFAULT); 643 } 644 mutex_exit(&sv->sv_mutex); 645 646 rc = smb_server_listen(sv, &sv->sv_nbt_daemon, SSN_SRVC_TCP_PORT, 647 error); 648 649 if (rc) { 650 mutex_enter(&sv->sv_mutex); 651 sv->sv_nbt_daemon.ld_kth = NULL; 652 mutex_exit(&sv->sv_mutex); 653 } 654 655 smb_server_release(sv); 656 657 return (rc); 658 } 659 660 int 661 smb_server_tcp_listen(int error) 662 { 663 smb_server_t *sv; 664 int rc; 665 666 rc = smb_server_lookup(&sv); 667 if (rc) 668 return (rc); 669 670 mutex_enter(&sv->sv_mutex); 671 switch (sv->sv_state) { 672 case SMB_SERVER_STATE_RUNNING: 673 if ((sv->sv_tcp_daemon.ld_kth) && 674 (sv->sv_tcp_daemon.ld_kth != curthread)) { 675 mutex_exit(&sv->sv_mutex); 676 return (EACCES); 677 } else { 678 sv->sv_tcp_daemon.ld_kth = curthread; 679 sv->sv_tcp_daemon.ld_ktdid = curthread->t_did; 680 } 681 break; 682 default: 683 ASSERT((sv->sv_state == SMB_SERVER_STATE_CREATED) || 684 (sv->sv_state == SMB_SERVER_STATE_CONFIGURED) || 685 (sv->sv_state == SMB_SERVER_STATE_DELETING)); 686 mutex_exit(&sv->sv_mutex); 687 return (EFAULT); 688 } 689 mutex_exit(&sv->sv_mutex); 690 691 rc = smb_server_listen(sv, &sv->sv_tcp_daemon, SMB_SRVC_TCP_PORT, 692 error); 693 694 if (rc) { 695 mutex_enter(&sv->sv_mutex); 696 sv->sv_tcp_daemon.ld_kth = NULL; 697 mutex_exit(&sv->sv_mutex); 698 } 699 700 smb_server_release(sv); 701 702 return (rc); 703 } 704 705 /* 706 * smb_server_nbt_receive 707 */ 708 int 709 smb_server_nbt_receive(void) 710 { 711 int rc; 712 smb_server_t *sv; 713 714 rc = smb_server_lookup(&sv); 715 if (rc) 716 return (rc); 717 718 rc = smb_session_daemon(&sv->sv_nbt_daemon.ld_session_list); 719 720 smb_server_release(sv); 721 722 return (rc); 723 } 724 725 /* 726 * smb_server_tcp_receive 727 */ 728 int 729 smb_server_tcp_receive(void) 730 { 731 int rc; 732 smb_server_t *sv; 733 734 rc = smb_server_lookup(&sv); 735 if (rc) 736 return (rc); 737 738 rc = smb_session_daemon(&sv->sv_tcp_daemon.ld_session_list); 739 740 smb_server_release(sv); 741 742 return (rc); 743 } 744 745 int 746 smb_server_set_gmtoff(int32_t goff) 747 { 748 int rc; 749 smb_server_t *sv; 750 751 752 rc = smb_server_lookup(&sv); 753 if (rc) 754 return (rc); 755 756 sv->si_gmtoff = goff; 757 758 smb_server_release(sv); 759 760 return (rc); 761 } 762 763 /* 764 * ***************************************************************************** 765 * ****************** Functions called from the door interface ***************** 766 * ***************************************************************************** 767 * 768 * These functions determine the relevant smb server to which the call apply. 769 */ 770 771 uint32_t 772 smb_server_get_user_count(void) 773 { 774 smb_server_t *sv; 775 uint32_t counter = 0; 776 777 if (smb_server_lookup(&sv)) 778 return (0); 779 780 counter = (uint32_t)sv->sv_open_users; 781 782 smb_server_release(sv); 783 784 return (counter); 785 } 786 787 uint32_t 788 smb_server_get_session_count(void) 789 { 790 smb_server_t *sv; 791 uint32_t counter = 0; 792 793 if (smb_server_lookup(&sv)) 794 return (0); 795 796 rw_enter(&sv->sv_nbt_daemon.ld_session_list.se_lock, RW_READER); 797 counter = sv->sv_nbt_daemon.ld_session_list.se_act.count; 798 rw_exit(&sv->sv_nbt_daemon.ld_session_list.se_lock); 799 rw_enter(&sv->sv_tcp_daemon.ld_session_list.se_lock, RW_READER); 800 counter += sv->sv_tcp_daemon.ld_session_list.se_act.count; 801 rw_exit(&sv->sv_tcp_daemon.ld_session_list.se_lock); 802 803 smb_server_release(sv); 804 805 return (counter); 806 } 807 808 /* 809 * smb_session_disconnect_share 810 * 811 * Disconnects the specified share. This function should be called after the 812 * share passed in has been made unavailable by the "share manager". 813 */ 814 void 815 smb_server_disconnect_share(char *sharename) 816 { 817 smb_server_t *sv; 818 819 if (smb_server_lookup(&sv)) 820 return; 821 822 smb_session_disconnect_share(&sv->sv_nbt_daemon.ld_session_list, 823 sharename); 824 smb_session_disconnect_share(&sv->sv_tcp_daemon.ld_session_list, 825 sharename); 826 827 smb_server_release(sv); 828 } 829 830 void 831 smb_server_disconnect_volume(const char *volname) 832 { 833 smb_server_t *sv; 834 835 if (smb_server_lookup(&sv)) 836 return; 837 838 smb_session_disconnect_volume(&sv->sv_nbt_daemon.ld_session_list, 839 volname); 840 smb_session_disconnect_volume(&sv->sv_tcp_daemon.ld_session_list, 841 volname); 842 843 smb_server_release(sv); 844 } 845 846 int 847 smb_server_dr_ulist_get(int offset, smb_dr_ulist_t *dr_ulist, int max_cnt) 848 { 849 smb_server_t *sv; 850 851 if (!dr_ulist) 852 return (-1); 853 854 if (smb_server_lookup(&sv)) 855 return (-1); 856 857 dr_ulist->dul_cnt = 858 smb_server_ulist_geti(&sv->sv_nbt_daemon.ld_session_list, 859 offset, dr_ulist->dul_users, max_cnt); 860 dr_ulist->dul_cnt += 861 smb_server_ulist_geti(&sv->sv_tcp_daemon.ld_session_list, 862 offset - dr_ulist->dul_cnt, &dr_ulist->dul_users[dr_ulist->dul_cnt], 863 max_cnt); 864 865 return (dr_ulist->dul_cnt); 866 } 867 868 /* 869 * smb_server_share_export() 870 * 871 * This function handles kernel processing at share enable time. 872 * 873 * At share-enable time (LMSHRD_ADD), the file system corresponding to 874 * the share is checked for characteristics that are required for SMB 875 * sharing. If this check passes, then a hold is taken on the root vnode 876 * of the file system (or a reference count on the corresponding smb_vfs_t 877 * is bumped), preventing an unmount. (See smb_vfs_hold()). 878 */ 879 880 int 881 smb_server_share_export(char *path) 882 { 883 smb_server_t *sv; 884 int error; 885 smb_node_t *fnode = NULL; 886 smb_node_t *dnode; 887 smb_attr_t ret_attr; 888 char last_comp[MAXNAMELEN]; 889 smb_request_t *sr; 890 891 if (smb_server_lookup(&sv)) 892 return (EINVAL); 893 894 sr = smb_request_alloc(sv->sv_session, 0); 895 if (sr == NULL) { 896 smb_server_release(sv); 897 return (ENOMEM); 898 } 899 900 sr->user_cr = kcred; 901 902 error = smb_pathname_reduce(sr, kcred, path, NULL, NULL, &dnode, 903 last_comp); 904 905 if (error) { 906 smb_request_free(sr); 907 smb_server_release(sv); 908 return (error); 909 } 910 911 error = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS, NULL, dnode, 912 last_comp, &fnode, &ret_attr, NULL, NULL); 913 914 smb_node_release(dnode); 915 916 if (error) { 917 smb_request_free(sr); 918 smb_server_release(sv); 919 return (error); 920 } 921 922 ASSERT(fnode->vp && fnode->vp->v_vfsp); 923 924 #ifdef SMB_ENFORCE_NODEV 925 if (vfs_optionisset(fnode->vp->v_vfsp, MNTOPT_NODEVICES, NULL) == 0) 926 return (EINVAL); 927 #endif /* SMB_ENFORCE_NODEV */ 928 929 if (!smb_vfs_hold(sv, fnode->vp->v_vfsp)) { 930 smb_node_release(fnode); 931 smb_request_free(sr); 932 smb_server_release(sv); 933 return (ENOMEM); 934 } 935 936 /* 937 * The refcount on the smb_vfs has been incremented. 938 * If it wasn't already, a hold has also been taken 939 * on the root vnode of the file system. 940 */ 941 942 smb_node_release(fnode); 943 smb_request_free(sr); 944 smb_server_release(sv); 945 return (0); 946 } 947 948 949 950 /* 951 * smb_server_share_unexport() 952 * 953 * This function handles kernel processing at share disable time. 954 * 955 * At share-disable time (LMSHRD_DELETE), the reference count on the 956 * corresponding smb_vfs_t is decremented. If this is the last share 957 * on the file system, the hold on the root vnode of the file system 958 * will be released. (See smb_vfs_rele().) 959 */ 960 961 int 962 smb_server_share_unexport(char *path, char *sharename) 963 { 964 smb_server_t *sv; 965 int error; 966 smb_node_t *fnode = NULL; 967 smb_node_t *dnode; 968 smb_attr_t ret_attr; 969 char last_comp[MAXNAMELEN]; 970 smb_request_t *sr; 971 972 if (smb_server_lookup(&sv)) 973 return (EINVAL); 974 975 sr = smb_request_alloc(sv->sv_session, 0); 976 if (sr == NULL) { 977 smb_server_release(sv); 978 return (ENOMEM); 979 } 980 sr->user_cr = kcred; 981 982 error = smb_pathname_reduce(sr, kcred, path, NULL, NULL, &dnode, 983 last_comp); 984 985 if (error) { 986 smb_request_free(sr); 987 smb_server_release(sv); 988 return (error); 989 } 990 991 error = smb_fsop_lookup(sr, kcred, SMB_FOLLOW_LINKS, NULL, dnode, 992 last_comp, &fnode, &ret_attr, NULL, NULL); 993 994 smb_node_release(dnode); 995 996 if (error) { 997 smb_request_free(sr); 998 smb_server_release(sv); 999 return (error); 1000 } 1001 1002 ASSERT(fnode->vp && fnode->vp->v_vfsp); 1003 1004 smb_session_disconnect_share(&sv->sv_nbt_daemon.ld_session_list, 1005 sharename); 1006 smb_session_disconnect_share(&sv->sv_tcp_daemon.ld_session_list, 1007 sharename); 1008 smb_vfs_rele(sv, fnode->vp->v_vfsp); 1009 smb_node_release(fnode); 1010 smb_request_free(sr); 1011 smb_server_release(sv); 1012 return (0); 1013 } 1014 1015 /* 1016 * This is a special interface that will be utilized by ZFS to cause a share to 1017 * be added/removed. 1018 * 1019 * arg is either a lmshare_info_t or share_name from userspace. 1020 * It will need to be copied into the kernel. It is lmshare_info_t 1021 * for add operations and share_name for delete operations. 1022 */ 1023 int 1024 smb_server_share(void *arg, boolean_t add_share) 1025 { 1026 smb_server_t *sv; 1027 int rc; 1028 1029 rc = smb_server_lookup(&sv); 1030 if (rc == 0) { 1031 mutex_enter(&sv->sv_mutex); 1032 if (sv->sv_state == SMB_SERVER_STATE_RUNNING) { 1033 mutex_exit(&sv->sv_mutex); 1034 rc = smb_kshare_upcall(sv->sv_lmshrd, arg, add_share); 1035 } else { 1036 mutex_exit(&sv->sv_mutex); 1037 rc = EPERM; 1038 } 1039 smb_server_release(sv); 1040 } 1041 return (rc); 1042 } 1043 1044 /* 1045 * ***************************************************************************** 1046 * **************** Functions called from the internal layers ****************** 1047 * ***************************************************************************** 1048 * 1049 * These functions are provided the relevant smb server by the caller. 1050 */ 1051 1052 void 1053 smb_server_reconnection_check(smb_server_t *sv, smb_session_t *session) 1054 { 1055 ASSERT(sv == session->s_server); 1056 1057 smb_session_reconnection_check(&sv->sv_nbt_daemon.ld_session_list, 1058 session); 1059 smb_session_reconnection_check(&sv->sv_tcp_daemon.ld_session_list, 1060 session); 1061 } 1062 1063 void 1064 smb_server_get_cfg(smb_server_t *sv, smb_kmod_cfg_t *cfg) 1065 { 1066 rw_enter(&sv->sv_cfg_lock, RW_READER); 1067 bcopy(&sv->sv_cfg, cfg, sizeof (*cfg)); 1068 rw_exit(&sv->sv_cfg_lock); 1069 } 1070 1071 /* 1072 * ***************************************************************************** 1073 * *************************** Static Functions ******************************** 1074 * ***************************************************************************** 1075 */ 1076 1077 static void 1078 smb_server_timers(smb_thread_t *thread, void *arg) 1079 { 1080 smb_server_t *sv = (smb_server_t *)arg; 1081 1082 ASSERT(sv != NULL); 1083 1084 while (smb_thread_continue_timedwait(thread, 1 /* Seconds */)) { 1085 smb_session_timers(&sv->sv_nbt_daemon.ld_session_list); 1086 smb_session_timers(&sv->sv_tcp_daemon.ld_session_list); 1087 } 1088 } 1089 1090 /* 1091 * smb_server_kstat_init 1092 */ 1093 static int 1094 smb_server_kstat_init(smb_server_t *sv) 1095 { 1096 (void) snprintf(sv->sv_ksp_name, sizeof (sv->sv_ksp_name), "%s%d", 1097 SMBSRV_KSTAT_NAME, sv->sv_zid); 1098 1099 sv->sv_ksp = kstat_create(SMBSRV_KSTAT_MODULE, 0, sv->sv_ksp_name, 1100 SMBSRV_KSTAT_CLASS, KSTAT_TYPE_NAMED, 1101 sizeof (sv->sv_ks_data) / sizeof (kstat_named_t), 1102 KSTAT_FLAG_VIRTUAL); 1103 1104 if (sv->sv_ksp) { 1105 (void) strlcpy(sv->sv_ks_data.open_files.name, "open_files", 1106 sizeof (sv->sv_ks_data.open_files.name)); 1107 sv->sv_ks_data.open_files.data_type = KSTAT_DATA_UINT32; 1108 (void) strlcpy(sv->sv_ks_data.open_trees.name, "connections", 1109 sizeof (sv->sv_ks_data.open_trees.name)); 1110 sv->sv_ks_data.open_trees.data_type = KSTAT_DATA_UINT32; 1111 (void) strlcpy(sv->sv_ks_data.open_users.name, "sessions", 1112 sizeof (sv->sv_ks_data.open_users.name)); 1113 sv->sv_ks_data.open_users.data_type = KSTAT_DATA_UINT32; 1114 1115 mutex_init(&sv->sv_ksp_mutex, NULL, MUTEX_DEFAULT, NULL); 1116 sv->sv_ksp->ks_lock = &sv->sv_ksp_mutex; 1117 sv->sv_ksp->ks_data = (void *)&sv->sv_ks_data; 1118 sv->sv_ksp->ks_update = smb_server_kstat_update_info; 1119 kstat_install(sv->sv_ksp); 1120 } 1121 1122 /* create and initialize smb kstats - smb_dispatch stats */ 1123 smb_dispatch_kstat_init(); 1124 1125 return (0); 1126 } 1127 1128 /* 1129 * smb_server_kstat_fini 1130 */ 1131 static void 1132 smb_server_kstat_fini(smb_server_t *sv) 1133 { 1134 if (sv->sv_ksp) { 1135 kstat_delete(sv->sv_ksp); 1136 mutex_destroy(&sv->sv_ksp_mutex); 1137 sv->sv_ksp = NULL; 1138 } 1139 smb_dispatch_kstat_fini(); 1140 } 1141 1142 /* ARGSUSED */ 1143 static int 1144 smb_server_kstat_update_info(kstat_t *ksp, int rw) 1145 { 1146 smb_server_t *sv; 1147 1148 if (rw == KSTAT_WRITE) { 1149 return (EACCES); 1150 } else { 1151 ASSERT(MUTEX_HELD(ksp->ks_lock)); 1152 1153 _NOTE(LINTED("pointer cast may result in improper alignment")) 1154 sv = (smb_server_t *)((uint8_t *)(ksp->ks_data) - 1155 offsetof(smb_server_t, sv_ks_data)); 1156 1157 ASSERT(sv->sv_magic == SMB_SERVER_MAGIC); 1158 1159 sv->sv_ks_data.open_files.value.ui32 = sv->sv_open_files; 1160 sv->sv_ks_data.open_trees.value.ui32 = sv->sv_open_trees; 1161 sv->sv_ks_data.open_users.value.ui32 = sv->sv_open_users; 1162 } 1163 return (0); 1164 } 1165 1166 /* 1167 * smb_server_stop 1168 * 1169 * The mutex of the server must have been entered before calling this function. 1170 */ 1171 static void 1172 smb_server_stop(smb_server_t *sv) 1173 { 1174 ASSERT(sv->sv_magic == SMB_SERVER_MAGIC); 1175 1176 smb_opipe_door_close(); 1177 smb_thread_stop(&sv->si_thread_timers); 1178 smb_kdoor_clnt_close(); 1179 smb_kshare_fini(sv->sv_lmshrd); 1180 sv->sv_lmshrd = NULL; 1181 smb_server_fsop_stop(sv); 1182 1183 if (sv->sv_session) { 1184 smb_session_delete(sv->sv_session); 1185 sv->sv_session = NULL; 1186 } 1187 1188 if (sv->sv_thread_pool) { 1189 taskq_destroy(sv->sv_thread_pool); 1190 sv->sv_thread_pool = NULL; 1191 } 1192 } 1193 1194 static int 1195 smb_server_listen( 1196 smb_server_t *sv, 1197 smb_listener_daemon_t *ld, 1198 in_port_t port, 1199 int pthread_create_error) 1200 { 1201 int rc; 1202 struct sonode *s_so; 1203 uint32_t on = 1; 1204 smb_session_t *session; 1205 1206 if (pthread_create_error) { 1207 /* 1208 * Delete the last session created. The user space thread 1209 * creation failed. 1210 */ 1211 smb_session_list_delete_tail(&ld->ld_session_list); 1212 } 1213 1214 if (ld->ld_so == NULL) { 1215 /* First time listener */ 1216 ld->ld_sin.sin_family = AF_INET; 1217 ld->ld_sin.sin_port = htons(port); 1218 ld->ld_sin.sin_addr.s_addr = htonl(INADDR_ANY); 1219 ld->ld_so = smb_socreate(AF_INET, SOCK_STREAM, 0); 1220 1221 if (ld->ld_so) { 1222 1223 (void) sosetsockopt(ld->ld_so, SOL_SOCKET, 1224 SO_REUSEADDR, (const void *)&on, sizeof (on)); 1225 1226 rc = sobind(ld->ld_so, (struct sockaddr *)&ld->ld_sin, 1227 sizeof (ld->ld_sin), 0, 0); 1228 1229 if (rc == 0) { 1230 rc = solisten(ld->ld_so, 20); 1231 if (rc < 0) { 1232 cmn_err(CE_WARN, 1233 "Port %d: listen failed", port); 1234 smb_soshutdown(ld->ld_so); 1235 smb_sodestroy(ld->ld_so); 1236 ld->ld_so = NULL; 1237 return (rc); 1238 } 1239 } else { 1240 cmn_err(CE_WARN, 1241 "Port %d: bind failed", port); 1242 smb_soshutdown(ld->ld_so); 1243 smb_sodestroy(ld->ld_so); 1244 ld->ld_so = NULL; 1245 return (rc); 1246 } 1247 } else { 1248 cmn_err(CE_WARN, 1249 "Port %d: socket create failed", port); 1250 return (ENOMEM); 1251 } 1252 } 1253 1254 DTRACE_PROBE1(so__wait__accept, struct sonode *, ld->ld_so); 1255 1256 for (;;) { 1257 rc = soaccept(ld->ld_so, 0, &s_so); 1258 if (rc == 0) { 1259 uint32_t txbuf_size = 128*1024; 1260 uint32_t on = 1; 1261 1262 DTRACE_PROBE1(so__accept, struct sonode *, s_so); 1263 1264 (void) sosetsockopt(s_so, IPPROTO_TCP, TCP_NODELAY, 1265 (const void *)&on, sizeof (on)); 1266 (void) sosetsockopt(s_so, SOL_SOCKET, SO_KEEPALIVE, 1267 (const void *)&on, sizeof (on)); 1268 (void) sosetsockopt(s_so, SOL_SOCKET, SO_SNDBUF, 1269 (const void *)&txbuf_size, sizeof (txbuf_size)); 1270 /* 1271 * Create a session for this connection. 1272 */ 1273 session = smb_session_create(s_so, port, sv); 1274 if (session) { 1275 smb_session_list_append(&ld->ld_session_list, 1276 session); 1277 break; 1278 } else { 1279 smb_soshutdown(s_so); 1280 smb_sodestroy(s_so); 1281 } 1282 continue; 1283 } 1284 smb_session_list_signal(&ld->ld_session_list); 1285 smb_soshutdown(ld->ld_so); 1286 smb_sodestroy(ld->ld_so); 1287 ld->ld_so = NULL; 1288 break; 1289 } 1290 1291 return (rc); 1292 } 1293 1294 /* 1295 * smb_server_lookup 1296 * 1297 * This function tries to find the server associated with the zone of the 1298 * caller. 1299 */ 1300 static int 1301 smb_server_lookup(smb_server_t **psv) 1302 { 1303 zoneid_t zid; 1304 smb_server_t *sv; 1305 1306 zid = getzoneid(); 1307 1308 smb_llist_enter(&smb_servers, RW_READER); 1309 sv = smb_llist_head(&smb_servers); 1310 while (sv) { 1311 ASSERT(sv->sv_magic == SMB_SERVER_MAGIC); 1312 if (sv->sv_zid == zid) { 1313 mutex_enter(&sv->sv_mutex); 1314 if (sv->sv_state != SMB_SERVER_STATE_DELETING) { 1315 sv->sv_refcnt++; 1316 mutex_exit(&sv->sv_mutex); 1317 smb_llist_exit(&smb_servers); 1318 *psv = sv; 1319 return (0); 1320 } 1321 mutex_exit(&sv->sv_mutex); 1322 break; 1323 } 1324 sv = smb_llist_next(&smb_servers, sv); 1325 } 1326 smb_llist_exit(&smb_servers); 1327 return (EPERM); 1328 } 1329 1330 /* 1331 * smb_server_release 1332 * 1333 * This function decrements the reference count of the server and signals its 1334 * condition variable if the state of the server is SMB_SERVER_STATE_DELETING. 1335 */ 1336 static void 1337 smb_server_release(smb_server_t *sv) 1338 { 1339 ASSERT(sv->sv_magic == SMB_SERVER_MAGIC); 1340 1341 mutex_enter(&sv->sv_mutex); 1342 ASSERT(sv->sv_refcnt); 1343 sv->sv_refcnt--; 1344 if ((sv->sv_refcnt == 0) && (sv->sv_state == SMB_SERVER_STATE_DELETING)) 1345 cv_signal(&sv->sv_cv); 1346 mutex_exit(&sv->sv_mutex); 1347 } 1348 1349 static int 1350 smb_server_ulist_geti( 1351 smb_session_list_t *se, 1352 int offset, 1353 smb_opipe_context_t *ctx, 1354 int max_cnt) 1355 { 1356 smb_session_t *sn = NULL; 1357 smb_user_t *user; 1358 smb_llist_t *ulist; 1359 int cnt = 0, skip = 0; 1360 1361 rw_enter(&se->se_lock, RW_READER); 1362 sn = list_head(&se->se_act.lst); 1363 while (sn && (cnt < max_cnt)) { 1364 ASSERT(sn->s_magic == SMB_SESSION_MAGIC); 1365 ulist = &sn->s_user_list; 1366 smb_llist_enter(ulist, RW_READER); 1367 user = smb_llist_head(ulist); 1368 while (user && (cnt < max_cnt)) { 1369 ASSERT(user->u_magic == SMB_USER_MAGIC); 1370 mutex_enter(&user->u_mutex); 1371 if (user->u_state == SMB_USER_STATE_LOGGED_IN) { 1372 if (skip++ < offset) { 1373 mutex_exit(&user->u_mutex); 1374 user = smb_llist_next(ulist, user); 1375 continue; 1376 } 1377 1378 smb_user_context_init(user, ctx); 1379 ctx++; 1380 cnt++; 1381 } 1382 mutex_exit(&user->u_mutex); 1383 user = smb_llist_next(ulist, user); 1384 } 1385 smb_llist_exit(ulist); 1386 } 1387 rw_exit(&se->se_lock); 1388 return (cnt); 1389 } 1390 1391 static void 1392 smb_server_store_cfg(smb_server_t *sv, smb_kmod_cfg_t *cfg) 1393 { 1394 if (cfg->skc_maxconnections == 0) 1395 cfg->skc_maxconnections = 0xFFFFFFFF; 1396 1397 smb_session_correct_keep_alive_values( 1398 &sv->sv_nbt_daemon.ld_session_list, cfg->skc_keepalive); 1399 smb_session_correct_keep_alive_values( 1400 &sv->sv_tcp_daemon.ld_session_list, cfg->skc_keepalive); 1401 1402 bcopy(cfg, &sv->sv_cfg, sizeof (sv->sv_cfg)); 1403 } 1404 1405 static int 1406 smb_server_fsop_start(smb_server_t *sv) 1407 { 1408 int error; 1409 1410 error = smb_node_root_init(rootdir, sv, &sv->si_root_smb_node); 1411 if (error != 0) 1412 sv->si_root_smb_node = NULL; 1413 1414 return (error); 1415 } 1416 1417 static void 1418 smb_server_fsop_stop(smb_server_t *sv) 1419 { 1420 if (sv->si_root_smb_node != NULL) { 1421 smb_vfs_rele_all(sv); 1422 smb_node_release(sv->si_root_smb_node); 1423 sv->si_root_smb_node = NULL; 1424 } 1425 } 1426