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