Print this page
NEX-17669 SMB shares missing after CA share import
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
NEX-16519 Panic while running IOmeter to a pool through an SMB share
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-17095 illumos 8935 SMB ioctl fixes incomplete
8935 SMB ioctl fixes incomplete
Reviewed by: Alex Wilson <alex.wilson@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Rui Loura <rui.loura@joyent.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Dominik Hassler <hasslerd@gmx.li>
Approved by: Garrett D'Amore <garrett@damore.org>
NEX-9808 SMB3 persistent handles
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15578 SMB2 durable handle redesign
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15581 SMB keep-alive feature is just noise
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-9808 SMB3 persistent handles
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15578 SMB2 durable handle redesign
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15581 SMB keep-alive feature is just noise
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-10019 SMB server min_protocol setting
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5273 SMB 3 Encryption
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-6096 Enable compile warnings re. parentheses in smbsrv
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Jean McCormack <jean.mccormack@nexenta.com>
NEX-6041 Should pass the smbtorture lock tests
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-4541 SMB server listener stops after a SYN-ACK flood (fksmbd noise)
NEX-4541 SMB server listener stops after a SYN-ACK flood (lint fix)
NEX-5983 remove post-merge cruft in usr/src/uts/intel/io/vmxnet3s
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-4541 SMB server listener stops after a SYN-ACK flood
Reviewed by: Gordon Ross <gwr@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-3553 SMB2/3 durable handles
Reviewed by: Gordon Ross <gwr@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-3776 SMB should handle PreviousSessionID
Reviewed by: Gordon Ross <gwr@nexenta.com>
NEX-5537 Want reference counts for users, trees...
Reviewed by: Gordon Ross <gwr@nexenta.com>
NEX-5330 SMB server should combine TCP+NBT session lists
Reviewed by: Gordon Ross <gwr@nexenta.com>
NEX-4811 SMB needs to export a header for kstats
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Jeffry Molanus <jeffry.molanus@nexenta.com>
NEX-2522 svcadm disable network/smb/server may hang
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
NEX-4083 Upstream changes from illumos 5917 and 5995
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-3738 Should support SMB2_CAP_LARGE_MTU
Reviewed by: Alek Pinchuk <alek@nexenta.com>
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
NEX-3620 need upstream cleanups for smbsrv
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
NEX-3611 CLONE NEX-3550 Replace smb2_enable with max_protocol
Reviewed by: Yuri Pankov <Yuri.Pankov@nexenta.com>
NEX-2485 SMB authentication flood handled poorly
SUP-866 smbd lwps stuck in libsocket recv() for no apparent reason
NEX-1050 enable_smb2 should be smb2_enable
SMB-11 SMB2 message parse & dispatch
SMB-12 SMB2 Negotiate Protocol
SMB-13 SMB2 Session Setup
SMB-14 SMB2 Logoff
SMB-15 SMB2 Tree Connect
SMB-16 SMB2 Tree Disconnect
SMB-17 SMB2 Create
SMB-18 SMB2 Close
SMB-19 SMB2 Flush
SMB-20 SMB2 Read
SMB-21 SMB2 Write
SMB-22 SMB2 Lock/Unlock
SMB-23 SMB2 Ioctl
SMB-24 SMB2 Cancel
SMB-25 SMB2 Echo
SMB-26 SMB2 Query Dir
SMB-27 SMB2 Change Notify
SMB-28 SMB2 Query Info
SMB-29 SMB2 Set Info
SMB-30 SMB2 Oplocks
SMB-53 SMB2 Create Context options
(SMB2 code review cleanup 1, 2, 3)
SMB-39 Use AF_UNIX pipes for RPC (fix a leak)
SMB-75 smb_session_timers way too frequent
SMB-74 Process oplock breaks as session requests
SMB-69 read-raw, write-raw are dead code
SMB-50 User-mode SMB server (oops)
SMB-56 extended security NTLMSSP, inbound
SMB-39 Use AF_UNIX pipes for RPC
SMB-50 User-mode SMB server
 Includes work by these authors:
 Thomas Keiser <thomas.keiser@nexenta.com>
 Albert Lee <trisk@nexenta.com>
SMB-65 SMB server in non-global zones (use zone_kcred())
SUP-694 panic on bad mutex in smb_event_wait()
SMB-65 SMB server in non-global zones (data structure changes)
Many things move to the smb_server_t object, and
many functions gain an sv arg (which server).
SMB-65 SMB server in non-global zones (kmem_caches)
common kmem_cache instances across zones
separate GZ-only init from NGZ init
SMB-64 smbsrv workers run at excessively high priority
SMB-63 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0
re #11974 CIFS Share - Tree connect fails from Windows 7 Clients
re #11215 rb3676 sesctl to SGI JBOD hangs in biowait() with a command stuck in mptsas driver
re #10734 NT Trans. Notify returning too quickly
re #9812 rb3153 System panic'd with assertion failed: sl->sl_count == 0 in smb_slist_destructor after hostname change, smbd restart and attempts to rejoin active directory domain
re #6813 rb1757 port 2976 Child folder visibility through shares
re #6812 rb1753 backport illumos 1604 smbd print_enable doesn't really work
re #6811 rb1752 backport illumos 1603 smbsrv raw mode is ill-advised


   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  24  * Copyright (c) 2017 by Delphix. All rights reserved.

  25  */
  26 
  27 /*
  28  * General Structures Layout
  29  * -------------------------
  30  *
  31  * This is a simplified diagram showing the relationship between most of the
  32  * main structures.
  33  *
  34  * +-------------------+
  35  * |     SMB_SERVER    |
  36  * +-------------------+
  37  *          |
  38  *          |
  39  *          v
  40  * +-------------------+       +-------------------+      +-------------------+
  41  * |     SESSION       |<----->|     SESSION       |......|      SESSION      |
  42  * +-------------------+       +-------------------+      +-------------------+
  43  *          |
  44  *          |


 202  * enforced in user space.
 203  */
 204 
 205 #include <sys/cmn_err.h>
 206 #include <sys/priv.h>
 207 #include <sys/zone.h>
 208 #include <netinet/in.h>
 209 #include <netinet/in_systm.h>
 210 #include <netinet/ip.h>
 211 #include <netinet/ip_icmp.h>
 212 #include <netinet/ip_var.h>
 213 #include <netinet/tcp.h>
 214 #include <smbsrv/smb2_kproto.h>
 215 #include <smbsrv/string.h>
 216 #include <smbsrv/netbios.h>
 217 #include <smbsrv/smb_fsops.h>
 218 #include <smbsrv/smb_share.h>
 219 #include <smbsrv/smb_door.h>
 220 #include <smbsrv/smb_kstat.h>
 221 
 222 extern void smb_reply_notify_change_request(smb_request_t *);
 223 
 224 typedef struct {
 225         smb_listener_daemon_t   *ra_listener;
 226         smb_session_t           *ra_session;
 227 } smb_receiver_arg_t;
 228 
 229 static void smb_server_kstat_init(smb_server_t *);
 230 static void smb_server_kstat_fini(smb_server_t *);
 231 static void smb_server_timers(smb_thread_t *, void *);
 232 static void smb_server_store_cfg(smb_server_t *, smb_ioc_cfg_t *);
 233 static void smb_server_shutdown(smb_server_t *);
 234 static int smb_server_fsop_start(smb_server_t *);
 235 static void smb_server_fsop_stop(smb_server_t *);
 236 static void smb_event_cancel(smb_server_t *, uint32_t);
 237 static uint32_t smb_event_alloc_txid(void);
 238 
 239 static void smb_server_disconnect_share(smb_llist_t *, const char *);
 240 static void smb_server_enum_users(smb_llist_t *, smb_svcenum_t *);
 241 static void smb_server_enum_trees(smb_llist_t *, smb_svcenum_t *);
 242 static int smb_server_session_disconnect(smb_llist_t *, const char *,
 243     const char *);
 244 static int smb_server_fclose(smb_llist_t *, uint32_t);
 245 static int smb_server_kstat_update(kstat_t *, int);
 246 static int smb_server_legacy_kstat_update(kstat_t *, int);
 247 static void smb_server_listener_init(smb_server_t *, smb_listener_daemon_t *,
 248     char *, in_port_t, int);
 249 static void smb_server_listener_destroy(smb_listener_daemon_t *);
 250 static int smb_server_listener_start(smb_listener_daemon_t *);
 251 static void smb_server_listener_stop(smb_listener_daemon_t *);
 252 static void smb_server_listener(smb_thread_t *, void *);
 253 static void smb_server_receiver(void *);
 254 static void smb_server_create_session(smb_listener_daemon_t *, ksocket_t);
 255 static void smb_server_destroy_session(smb_listener_daemon_t *,
 256     smb_session_t *);
 257 static uint16_t smb_spool_get_fid(smb_server_t *);
 258 static boolean_t smb_spool_lookup_doc_byfid(smb_server_t *, uint16_t,
 259     smb_kspooldoc_t *);
 260 














 261 int smb_event_debug = 0;
 262 
 263 static smb_llist_t      smb_servers;
 264 
 265 kmem_cache_t            *smb_cache_request;
 266 kmem_cache_t            *smb_cache_session;
 267 kmem_cache_t            *smb_cache_user;
 268 kmem_cache_t            *smb_cache_tree;
 269 kmem_cache_t            *smb_cache_ofile;
 270 kmem_cache_t            *smb_cache_odir;
 271 kmem_cache_t            *smb_cache_opipe;
 272 kmem_cache_t            *smb_cache_event;

 273 
 274 /*
 275  * *****************************************************************************
 276  * **************** Functions called from the device interface *****************
 277  * *****************************************************************************
 278  *
 279  * These functions typically have to determine the relevant smb server
 280  * to which the call applies.
 281  */
 282 
 283 /*
 284  * How many zones have an SMB server active?
 285  */
 286 int
 287 smb_server_get_count(void)
 288 {
 289         return (smb_llist_get_count(&smb_servers));
 290 }
 291 
 292 /*
 293  * smb_server_g_init
 294  *
 295  * This function must be called from smb_drv_attach().
 296  */
 297 int
 298 smb_server_g_init(void)
 299 {
 300         int rc;
 301 
 302         if ((rc = smb_vop_init()) != 0)
 303                 goto errout;
 304         if ((rc = smb_fem_init()) != 0)
 305                 goto errout;
 306 
 307         smb_kshare_g_init();
 308         smb_codepage_init();
 309         smb_mbc_init();         /* smb_mbc_cache */
 310         smb_node_init();        /* smb_node_cache, lists */

 311 
 312         smb_cache_request = kmem_cache_create("smb_request_cache",
 313             sizeof (smb_request_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 314         smb_cache_session = kmem_cache_create("smb_session_cache",
 315             sizeof (smb_session_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 316         smb_cache_user = kmem_cache_create("smb_user_cache",
 317             sizeof (smb_user_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 318         smb_cache_tree = kmem_cache_create("smb_tree_cache",
 319             sizeof (smb_tree_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 320         smb_cache_ofile = kmem_cache_create("smb_ofile_cache",
 321             sizeof (smb_ofile_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 322         smb_cache_odir = kmem_cache_create("smb_odir_cache",
 323             sizeof (smb_odir_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 324         smb_cache_opipe = kmem_cache_create("smb_opipe_cache",
 325             sizeof (smb_opipe_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 326         smb_cache_event = kmem_cache_create("smb_event_cache",
 327             sizeof (smb_event_t), 8, NULL, NULL, NULL, NULL, NULL, 0);


 328 
 329         smb_llist_init();
 330         smb_llist_constructor(&smb_servers, sizeof (smb_server_t),
 331             offsetof(smb_server_t, sv_lnd));
 332 
 333         return (0);
 334 
 335 errout:
 336         smb_fem_fini();
 337         smb_vop_fini();
 338         return (rc);
 339 }
 340 
 341 /*
 342  * smb_server_g_fini
 343  *
 344  * This function must called from smb_drv_detach(). It will fail if servers
 345  * still exist.
 346  */
 347 void
 348 smb_server_g_fini(void)
 349 {
 350 
 351         ASSERT(smb_llist_get_count(&smb_servers) == 0);
 352 
 353         smb_llist_fini();
 354 
 355         kmem_cache_destroy(smb_cache_request);
 356         kmem_cache_destroy(smb_cache_session);
 357         kmem_cache_destroy(smb_cache_user);
 358         kmem_cache_destroy(smb_cache_tree);
 359         kmem_cache_destroy(smb_cache_ofile);
 360         kmem_cache_destroy(smb_cache_odir);
 361         kmem_cache_destroy(smb_cache_opipe);
 362         kmem_cache_destroy(smb_cache_event);

 363 

 364         smb_node_fini();
 365         smb_mbc_fini();
 366         smb_codepage_fini();
 367         smb_kshare_g_fini();
 368 
 369         smb_fem_fini();
 370         smb_vop_fini();
 371 
 372         smb_llist_destructor(&smb_servers);
 373 }
 374 
 375 /*
 376  * smb_server_create
 377  *
 378  * This function will fail if there's already a server associated with the
 379  * caller's zone.
 380  */
 381 int
 382 smb_server_create(void)
 383 {


 391         while (sv) {
 392                 SMB_SERVER_VALID(sv);
 393                 if (sv->sv_zid == zid) {
 394                         smb_llist_exit(&smb_servers);
 395                         return (EPERM);
 396                 }
 397                 sv = smb_llist_next(&smb_servers, sv);
 398         }
 399 
 400         sv = kmem_zalloc(sizeof (smb_server_t), KM_SLEEP);
 401 
 402         sv->sv_magic = SMB_SERVER_MAGIC;
 403         sv->sv_state = SMB_SERVER_STATE_CREATED;
 404         sv->sv_zid = zid;
 405         sv->sv_pid = ddi_get_pid();
 406 
 407         mutex_init(&sv->sv_mutex, NULL, MUTEX_DEFAULT, NULL);
 408         cv_init(&sv->sv_cv, NULL, CV_DEFAULT, NULL);
 409         cv_init(&sv->sp_info.sp_cv, NULL, CV_DEFAULT, NULL);
 410 









 411         smb_llist_constructor(&sv->sv_event_list, sizeof (smb_event_t),
 412             offsetof(smb_event_t, se_lnd));
 413 
 414         smb_llist_constructor(&sv->sp_info.sp_list, sizeof (smb_kspooldoc_t),
 415             offsetof(smb_kspooldoc_t, sd_lnd));
 416 
 417         smb_llist_constructor(&sv->sp_info.sp_fidlist,
 418             sizeof (smb_spoolfid_t), offsetof(smb_spoolfid_t, sf_lnd));
 419 
 420         sv->sv_disp_stats1 = kmem_zalloc(SMB_COM_NUM *
 421             sizeof (smb_disp_stats_t), KM_SLEEP);
 422 
 423         sv->sv_disp_stats2 = kmem_zalloc(SMB2__NCMDS *
 424             sizeof (smb_disp_stats_t), KM_SLEEP);
 425 
 426         smb_thread_init(&sv->si_thread_timers, "smb_timers",
 427             smb_server_timers, sv, smbsrv_timer_pri);
 428 
 429         smb_srqueue_init(&sv->sv_srqueue);
 430 


 435         smb_threshold_init(&sv->sv_ssetup_ct, SMB_SSETUP_CMD,
 436             smb_ssetup_threshold, smb_ssetup_timeout);
 437         smb_threshold_init(&sv->sv_tcon_ct, SMB_TCON_CMD,
 438             smb_tcon_threshold, smb_tcon_timeout);
 439         smb_threshold_init(&sv->sv_opipe_ct, SMB_OPIPE_CMD,
 440             smb_opipe_threshold, smb_opipe_timeout);
 441 
 442         smb_llist_insert_tail(&smb_servers, sv);
 443         smb_llist_exit(&smb_servers);
 444 
 445         return (0);
 446 }
 447 
 448 /*
 449  * smb_server_delete
 450  *
 451  * This function will delete the server passed in. It will make sure that all
 452  * activity associated that server has ceased before destroying it.
 453  */
 454 int
 455 smb_server_delete(void)
 456 {
 457         smb_server_t    *sv;
 458         int             rc;
 459 
 460         rc = smb_server_lookup(&sv);
 461         if (rc != 0)
 462                 return (rc);
 463 
 464         mutex_enter(&sv->sv_mutex);
 465         switch (sv->sv_state) {
 466         case SMB_SERVER_STATE_RUNNING:
 467                 sv->sv_state = SMB_SERVER_STATE_STOPPING;
 468                 mutex_exit(&sv->sv_mutex);
 469                 smb_server_shutdown(sv);
 470                 mutex_enter(&sv->sv_mutex);
 471                 cv_broadcast(&sv->sp_info.sp_cv);
 472                 sv->sv_state = SMB_SERVER_STATE_DELETING;
 473                 break;
 474         case SMB_SERVER_STATE_STOPPING:
 475                 sv->sv_state = SMB_SERVER_STATE_DELETING;
 476                 break;
 477         case SMB_SERVER_STATE_CONFIGURED:
 478         case SMB_SERVER_STATE_CREATED:
 479                 sv->sv_state = SMB_SERVER_STATE_DELETING;
 480                 break;
 481         default:
 482                 SMB_SERVER_STATE_VALID(sv->sv_state);
 483                 mutex_exit(&sv->sv_mutex);


 491         while (sv->sv_refcnt)
 492                 cv_wait(&sv->sv_cv, &sv->sv_mutex);
 493 
 494         mutex_exit(&sv->sv_mutex);
 495 
 496         smb_llist_enter(&smb_servers, RW_WRITER);
 497         smb_llist_remove(&smb_servers, sv);
 498         smb_llist_exit(&smb_servers);
 499 
 500         smb_threshold_fini(&sv->sv_ssetup_ct);
 501         smb_threshold_fini(&sv->sv_tcon_ct);
 502         smb_threshold_fini(&sv->sv_opipe_ct);
 503 
 504         smb_server_listener_destroy(&sv->sv_nbt_daemon);
 505         smb_server_listener_destroy(&sv->sv_tcp_daemon);
 506         rw_destroy(&sv->sv_cfg_lock);
 507         smb_server_kstat_fini(sv);
 508         smb_kshare_fini(sv);
 509         smb_kdoor_fini(sv);
 510         smb_llist_destructor(&sv->sv_event_list);

 511 
 512         kmem_free(sv->sv_disp_stats1,
 513             SMB_COM_NUM * sizeof (smb_disp_stats_t));
 514 
 515         kmem_free(sv->sv_disp_stats2,
 516             SMB2__NCMDS * sizeof (smb_disp_stats_t));
 517 
 518         smb_srqueue_destroy(&sv->sv_srqueue);
 519         smb_thread_destroy(&sv->si_thread_timers);
 520 
 521         mutex_destroy(&sv->sv_mutex);


 522         cv_destroy(&sv->sv_cv);
 523         sv->sv_magic = 0;
 524         kmem_free(sv, sizeof (smb_server_t));
 525 
 526         return (0);
 527 }
 528 
 529 /*
 530  * smb_server_configure
 531  */
 532 int
 533 smb_server_configure(smb_ioc_cfg_t *ioc)
 534 {
 535         int             rc = 0;
 536         smb_server_t    *sv;
 537 
 538         /*
 539          * Reality check negotiation token length vs. #define'd maximum.
 540          */
 541         if (ioc->negtok_len > SMB_PI_MAX_NEGTOK)


 567                 SMB_SERVER_STATE_VALID(sv->sv_state);
 568                 rc = EFAULT;
 569                 break;
 570         }
 571         mutex_exit(&sv->sv_mutex);
 572 
 573         smb_server_release(sv);
 574 
 575         return (rc);
 576 }
 577 
 578 /*
 579  * smb_server_start
 580  */
 581 int
 582 smb_server_start(smb_ioc_start_t *ioc)
 583 {
 584         int             rc = 0;
 585         int             family;
 586         smb_server_t    *sv;

 587 
 588         rc = smb_server_lookup(&sv);
 589         if (rc)
 590                 return (rc);
 591 
 592         mutex_enter(&sv->sv_mutex);
 593         switch (sv->sv_state) {
 594         case SMB_SERVER_STATE_CONFIGURED:
 595 
 596                 if ((rc = smb_server_fsop_start(sv)) != 0)
 597                         break;
 598 

























 599                 if ((rc = smb_kshare_start(sv)) != 0)
 600                         break;
 601 
 602                 /*
 603                  * NB: the proc passed here has to be a "system" one.
 604                  * Normally that's p0, or the NGZ eqivalent.
 605                  */
 606                 sv->sv_worker_pool = taskq_create_proc("smb_workers",
 607                     sv->sv_cfg.skc_maxworkers, smbsrv_worker_pri,
 608                     sv->sv_cfg.skc_maxworkers, INT_MAX,
 609                     curzone->zone_zsched, TASKQ_DYNAMIC);
 610 
 611                 sv->sv_receiver_pool = taskq_create_proc("smb_receivers",
 612                     sv->sv_cfg.skc_maxconnections, smbsrv_receive_pri,
 613                     sv->sv_cfg.skc_maxconnections, INT_MAX,
 614                     curzone->zone_zsched, TASKQ_DYNAMIC);
 615 
 616                 sv->sv_session = smb_session_create(NULL, 0, sv, 0);
 617 
 618                 if (sv->sv_worker_pool == NULL || sv->sv_session == NULL) {
 619                         rc = ENOMEM;
 620                         break;
 621                 }
 622 
 623 #ifdef  _KERNEL
 624                 ASSERT(sv->sv_lmshrd == NULL);
 625                 sv->sv_lmshrd = smb_kshare_door_init(ioc->lmshrd);
 626                 if (sv->sv_lmshrd == NULL)
 627                         break;
 628                 if (rc = smb_kdoor_open(sv, ioc->udoor)) {
 629                         cmn_err(CE_WARN, "Cannot open smbd door");
 630                         break;
 631                 }
 632 #else   /* _KERNEL */
 633                 /* Fake kernel does not use the kshare_door */
 634                 fksmb_kdoor_open(sv, ioc->udoor_func);
 635 #endif  /* _KERNEL */
 636 
 637                 if (rc = smb_thread_start(&sv->si_thread_timers))
 638                         break;
 639 
 640                 family = AF_INET;
 641                 smb_server_listener_init(sv, &sv->sv_nbt_daemon,
 642                     "smb_nbt_listener", IPPORT_NETBIOS_SSN, family);
 643                 if (sv->sv_cfg.skc_ipv6_enable)
 644                         family = AF_INET6;
 645                 smb_server_listener_init(sv, &sv->sv_tcp_daemon,
 646                     "smb_tcp_listener", IPPORT_SMB, family);
 647                 rc = smb_server_listener_start(&sv->sv_tcp_daemon);
 648                 if (rc != 0)
 649                         break;
 650                 if (sv->sv_cfg.skc_netbios_enable)
 651                         (void) smb_server_listener_start(&sv->sv_nbt_daemon);
 652 
 653                 sv->sv_state = SMB_SERVER_STATE_RUNNING;
 654                 sv->sv_start_time = gethrtime();
 655                 mutex_exit(&sv->sv_mutex);
 656                 smb_server_release(sv);
 657                 smb_export_start(sv);


 847         smb_svcenum_t   *svcenum = &ioc->svcenum;
 848         smb_server_t    *sv;
 849         int             rc;
 850 
 851         /*
 852          * Reality check that the buffer-length insize the enum doesn't
 853          * overrun the ioctl's total length.
 854          */
 855         if (svcenum->se_buflen + sizeof (*ioc) > ioc->hdr.len)
 856                 return (EINVAL);
 857 
 858         if ((rc = smb_server_lookup(&sv)) != 0)
 859                 return (rc);
 860 
 861         svcenum->se_bavail = svcenum->se_buflen;
 862         svcenum->se_bused = 0;
 863         svcenum->se_nitems = 0;
 864 
 865         switch (svcenum->se_type) {
 866         case SMB_SVCENUM_TYPE_USER:
 867                 smb_server_enum_users(&sv->sv_nbt_daemon.ld_session_list,
 868                     svcenum);
 869                 smb_server_enum_users(&sv->sv_tcp_daemon.ld_session_list,
 870                     svcenum);
 871                 break;
 872         case SMB_SVCENUM_TYPE_TREE:
 873         case SMB_SVCENUM_TYPE_FILE:
 874                 smb_server_enum_trees(&sv->sv_nbt_daemon.ld_session_list,
 875                     svcenum);
 876                 smb_server_enum_trees(&sv->sv_tcp_daemon.ld_session_list,
 877                     svcenum);
 878                 break;
 879         default:
 880                 rc = EINVAL;
 881         }
 882 
 883         smb_server_release(sv);
 884         return (rc);
 885 }
 886 
 887 /*
 888  * Look for sessions to disconnect by client and user name.
 889  */
 890 int
 891 smb_server_session_close(smb_ioc_session_t *ioc)
 892 {
 893         smb_llist_t     *ll;
 894         smb_server_t    *sv;
 895         int             nbt_cnt;
 896         int             tcp_cnt;
 897         int             rc;
 898 
 899         if ((rc = smb_server_lookup(&sv)) != 0)
 900                 return (rc);
 901 
 902         ll = &sv->sv_nbt_daemon.ld_session_list;
 903         nbt_cnt = smb_server_session_disconnect(ll, ioc->client, ioc->username);
 904 
 905         ll = &sv->sv_tcp_daemon.ld_session_list;
 906         tcp_cnt = smb_server_session_disconnect(ll, ioc->client, ioc->username);
 907 
 908         smb_server_release(sv);
 909 
 910         if ((nbt_cnt == 0) && (tcp_cnt == 0))
 911                 return (ENOENT);
 912         return (0);
 913 }
 914 
 915 /*
 916  * Close a file by uniqid.
 917  */
 918 int
 919 smb_server_file_close(smb_ioc_fileid_t *ioc)
 920 {
 921         uint32_t        uniqid = ioc->uniqid;
 922         smb_llist_t     *ll;
 923         smb_server_t    *sv;
 924         int             rc;
 925 
 926         if ((rc = smb_server_lookup(&sv)) != 0)
 927                 return (rc);
 928 
 929         ll = &sv->sv_nbt_daemon.ld_session_list;
 930         rc = smb_server_fclose(ll, uniqid);
 931 
 932         if (rc == ENOENT) {
 933                 ll = &sv->sv_tcp_daemon.ld_session_list;
 934                 rc = smb_server_fclose(ll, uniqid);
 935         }
 936 
 937         smb_server_release(sv);
 938         return (rc);
 939 }
 940 
 941 /*
 942  * These functions determine the relevant smb server to which the call apply.
 943  */
 944 
 945 uint32_t
 946 smb_server_get_session_count(smb_server_t *sv)
 947 {
 948         uint32_t        counter = 0;
 949 
 950         counter = smb_llist_get_count(&sv->sv_nbt_daemon.ld_session_list);
 951         counter += smb_llist_get_count(&sv->sv_tcp_daemon.ld_session_list);
 952 
 953         return (counter);
 954 }
 955 
 956 /*
 957  * Gets the vnode of the specified share path.
 958  *
 959  * A hold on the returned vnode pointer is taken so the caller
 960  * must call VN_RELE.
 961  */
 962 int
 963 smb_server_sharevp(smb_server_t *sv, const char *shr_path, vnode_t **vp)

 964 {
 965         smb_request_t   *sr;
 966         smb_node_t      *fnode = NULL;
 967         smb_node_t      *dnode;
 968         char            last_comp[MAXNAMELEN];
 969         int             rc = 0;
 970 
 971         ASSERT(shr_path);
 972 
 973         mutex_enter(&sv->sv_mutex);
 974         switch (sv->sv_state) {
 975         case SMB_SERVER_STATE_RUNNING:
 976                 break;
 977         default:
 978                 mutex_exit(&sv->sv_mutex);
 979                 return (ENOTACTIVE);
 980         }
 981         mutex_exit(&sv->sv_mutex);
 982 
 983         if ((sr = smb_request_alloc(sv->sv_session, 0)) == NULL) {
 984                 return (ENOMEM);
 985         }
 986         sr->user_cr = zone_kcred();
 987 
 988         rc = smb_pathname_reduce(sr, sr->user_cr, shr_path,
 989             NULL, NULL, &dnode, last_comp);
 990 
 991         if (rc == 0) {
 992                 rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
 993                     sv->si_root_smb_node, dnode, last_comp, &fnode);
 994                 smb_node_release(dnode);
 995         }
 996 
 997         smb_request_free(sr);
 998 
 999         if (rc != 0)
1000                 return (rc);
1001 
1002         ASSERT(fnode->vp && fnode->vp->v_vfsp);
1003 
1004         VN_HOLD(fnode->vp);
1005         *vp = fnode->vp;
1006 
1007         smb_node_release(fnode);
1008 
1009         return (0);
1010 }
1011 
1012 #ifdef  _KERNEL
1013 /*
1014  * This is a special interface that will be utilized by ZFS to cause a share to
1015  * be added/removed.
1016  *
1017  * arg is either a lmshare_info_t or share_name from userspace.
1018  * It will need to be copied into the kernel.   It is lmshare_info_t
1019  * for add operations and share_name for delete operations.
1020  */
1021 int
1022 smb_server_share(void *arg, boolean_t add_share)
1023 {
1024         smb_server_t    *sv;
1025         int             rc;
1026 
1027         if ((rc = smb_server_lookup(&sv)) == 0) {
1028                 mutex_enter(&sv->sv_mutex);
1029                 switch (sv->sv_state) {
1030                 case SMB_SERVER_STATE_RUNNING:
1031                         mutex_exit(&sv->sv_mutex);
1032                         (void) smb_kshare_upcall(sv->sv_lmshrd, arg, add_share);
1033                         break;
1034                 default:
1035                         mutex_exit(&sv->sv_mutex);
1036                         break;
1037                 }
1038                 smb_server_release(sv);
1039         }
1040 
1041         return (rc);
1042 }
1043 #endif  /* _KERNEL */
1044 
1045 int
1046 smb_server_unshare(const char *sharename)
1047 {
1048         smb_server_t    *sv;
1049         smb_llist_t     *ll;
1050         int             rc;
1051 
1052         if ((rc = smb_server_lookup(&sv)))
1053                 return (rc);
1054 
1055         mutex_enter(&sv->sv_mutex);
1056         switch (sv->sv_state) {
1057         case SMB_SERVER_STATE_RUNNING:
1058         case SMB_SERVER_STATE_STOPPING:
1059                 break;
1060         default:
1061                 mutex_exit(&sv->sv_mutex);
1062                 smb_server_release(sv);
1063                 return (ENOTACTIVE);
1064         }
1065         mutex_exit(&sv->sv_mutex);
1066 
1067         ll = &sv->sv_nbt_daemon.ld_session_list;
1068         smb_server_disconnect_share(ll, sharename);
1069 
1070         ll = &sv->sv_tcp_daemon.ld_session_list;
1071         smb_server_disconnect_share(ll, sharename);
1072 
1073         smb_server_release(sv);
1074         return (0);
1075 }
1076 
1077 /*
1078  * Disconnect the specified share.
1079  * Typically called when a share has been removed.
1080  */
1081 static void
1082 smb_server_disconnect_share(smb_llist_t *ll, const char *sharename)
1083 {

1084         smb_session_t   *session;
1085 

1086         smb_llist_enter(ll, RW_READER);
1087 
1088         session = smb_llist_head(ll);
1089         while (session) {
1090                 SMB_SESSION_VALID(session);
1091                 smb_rwx_rwenter(&session->s_lock, RW_READER);
1092                 switch (session->s_state) {
1093                 case SMB_SESSION_STATE_NEGOTIATED:

1094                         smb_session_disconnect_share(session, sharename);
1095                         break;
1096                 default:

1097                         break;
1098                 }
1099                 smb_rwx_rwexit(&session->s_lock);
1100                 session = smb_llist_next(ll, session);
1101         }
1102 
1103         smb_llist_exit(ll);
1104 }
1105 
1106 /*
1107  * *****************************************************************************
1108  * **************** Functions called from the internal layers ******************
1109  * *****************************************************************************
1110  *
1111  * These functions are provided the relevant smb server by the caller.
1112  */
1113 
1114 void
1115 smb_server_get_cfg(smb_server_t *sv, smb_kmod_cfg_t *cfg)
1116 {
1117         rw_enter(&sv->sv_cfg_lock, RW_READER);
1118         bcopy(&sv->sv_cfg, cfg, sizeof (*cfg));
1119         rw_exit(&sv->sv_cfg_lock);


1224 smb_server_inc_req(smb_server_t *sv)
1225 {
1226         SMB_SERVER_VALID(sv);
1227         atomic_inc_64(&sv->sv_nreq);
1228 }
1229 
1230 /*
1231  * *****************************************************************************
1232  * *************************** Static Functions ********************************
1233  * *****************************************************************************
1234  */
1235 
1236 static void
1237 smb_server_timers(smb_thread_t *thread, void *arg)
1238 {
1239         smb_server_t    *sv = (smb_server_t *)arg;
1240 
1241         ASSERT(sv != NULL);
1242 
1243         /*
1244          * This just kills old inactive sessions.  No urgency.
1245          * The session code expects one call per minute.
1246          */
1247         while (smb_thread_continue_timedwait(thread, 60 /* Seconds */)) {
1248                 smb_session_timers(&sv->sv_nbt_daemon.ld_session_list);
1249                 smb_session_timers(&sv->sv_tcp_daemon.ld_session_list);

1250         }
1251 }
1252 
1253 /*
1254  * smb_server_kstat_init
1255  */
1256 static void
1257 smb_server_kstat_init(smb_server_t *sv)
1258 {
1259 
1260         sv->sv_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, 0,
1261             SMBSRV_KSTAT_STATISTICS, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_RAW,
1262             sizeof (smbsrv_kstats_t), 0, sv->sv_zid);
1263 
1264         if (sv->sv_ksp != NULL) {
1265                 sv->sv_ksp->ks_update = smb_server_kstat_update;
1266                 sv->sv_ksp->ks_private = sv;
1267                 ((smbsrv_kstats_t *)sv->sv_ksp->ks_data)->ks_start_time =
1268                     sv->sv_start_time;
1269                 smb_dispatch_stats_init(sv);


1306  * smb_server_kstat_fini
1307  */
1308 static void
1309 smb_server_kstat_fini(smb_server_t *sv)
1310 {
1311         if (sv->sv_legacy_ksp != NULL) {
1312                 kstat_delete(sv->sv_legacy_ksp);
1313                 mutex_destroy(&sv->sv_legacy_ksmtx);
1314                 sv->sv_legacy_ksp = NULL;
1315         }
1316 
1317         if (sv->sv_ksp != NULL) {
1318                 kstat_delete(sv->sv_ksp);
1319                 sv->sv_ksp = NULL;
1320                 smb_dispatch_stats_fini(sv);
1321                 smb2_dispatch_stats_fini(sv);
1322         }
1323 }
1324 
1325 /*






1326  * smb_server_kstat_update
1327  */
1328 static int
1329 smb_server_kstat_update(kstat_t *ksp, int rw)
1330 {
1331         smb_server_t    *sv;
1332         smbsrv_kstats_t *ksd;
1333 
1334         if (rw == KSTAT_READ) {
1335                 sv = ksp->ks_private;
1336                 SMB_SERVER_VALID(sv);
1337                 ksd = (smbsrv_kstats_t *)ksp->ks_data;
1338                 /*
1339                  * Counters
1340                  */
1341                 ksd->ks_nbt_sess = sv->sv_nbt_sess;
1342                 ksd->ks_tcp_sess = sv->sv_tcp_sess;
1343                 ksd->ks_users = sv->sv_users;
1344                 ksd->ks_trees = sv->sv_trees;
1345                 ksd->ks_files = sv->sv_files;


1390                         ksd->ls_users.value.ui32 = sv->sv_users;
1391                         smb_server_release(sv);
1392                         rc = 0;
1393                         break;
1394                 }
1395                 _NOTE(FALLTHRU)
1396         default:
1397                 rc = EIO;
1398                 break;
1399         }
1400         return (rc);
1401 
1402 }
1403 
1404 /*
1405  * smb_server_shutdown
1406  */
1407 static void
1408 smb_server_shutdown(smb_server_t *sv)
1409 {




1410         SMB_SERVER_VALID(sv);
1411 
1412         /*
1413          * Stop the listeners first, so we don't get any more
1414          * new work while we're trying to shut down.
1415          */
1416         smb_server_listener_stop(&sv->sv_nbt_daemon);
1417         smb_server_listener_stop(&sv->sv_tcp_daemon);
1418         smb_thread_stop(&sv->si_thread_timers);
1419 









1420         /*
1421          * Wake up any threads we might have blocked.
1422          * Must precede kdoor_close etc. because those will
1423          * wait for such threads to get out.
1424          */
1425         smb_event_cancel(sv, 0);
1426         smb_threshold_wake_all(&sv->sv_ssetup_ct);
1427         smb_threshold_wake_all(&sv->sv_tcon_ct);
1428         smb_threshold_wake_all(&sv->sv_opipe_ct);
1429 

































1430         smb_kdoor_close(sv);
1431 #ifdef  _KERNEL
1432         smb_kshare_door_fini(sv->sv_lmshrd);
1433 #endif  /* _KERNEL */
1434         sv->sv_lmshrd = NULL;
1435 
1436         smb_export_stop(sv);

1437 
1438         if (sv->sv_session != NULL) {
1439                 /*
1440                  * smb_kshare_export may have a request on here.
1441                  * Normal sessions do this in smb_session_cancel()
1442                  * but this is a "fake" session used only for the
1443                  * requests used by the kshare thread(s).



1444                  */






1445                 smb_slist_wait_for_empty(&sv->sv_session->s_req_list);
1446 



1447                 smb_session_delete(sv->sv_session);
1448                 sv->sv_session = NULL;
1449         }
1450 
1451         if (sv->sv_receiver_pool != NULL) {
1452                 taskq_destroy(sv->sv_receiver_pool);
1453                 sv->sv_receiver_pool = NULL;
1454         }
1455 
1456         if (sv->sv_worker_pool != NULL) {
1457                 taskq_destroy(sv->sv_worker_pool);
1458                 sv->sv_worker_pool = NULL;
1459         }
1460 
1461         smb_kshare_stop(sv);
1462         smb_server_fsop_stop(sv);
1463 }
1464 
1465 /*
1466  * smb_server_listener_init
1467  *
1468  * Initializes listener contexts.
1469  */
1470 static void
1471 smb_server_listener_init(
1472     smb_server_t                *sv,
1473     smb_listener_daemon_t       *ld,
1474     char                        *name,
1475     in_port_t                   port,
1476     int                         family)
1477 {
1478         ASSERT(ld->ld_magic != SMB_LISTENER_MAGIC);
1479 
1480         bzero(ld, sizeof (*ld));
1481 
1482         ld->ld_sv = sv;
1483         ld->ld_family = family;
1484         ld->ld_port = port;
1485 
1486         if (family == AF_INET) {
1487                 ld->ld_sin.sin_family = (uint32_t)family;
1488                 ld->ld_sin.sin_port = htons(port);
1489                 ld->ld_sin.sin_addr.s_addr = htonl(INADDR_ANY);
1490         } else {
1491                 ld->ld_sin6.sin6_family = (uint32_t)family;
1492                 ld->ld_sin6.sin6_port = htons(port);
1493                 (void) memset(&ld->ld_sin6.sin6_addr.s6_addr, 0,
1494                     sizeof (ld->ld_sin6.sin6_addr.s6_addr));
1495         }
1496 
1497         smb_llist_constructor(&ld->ld_session_list, sizeof (smb_session_t),
1498             offsetof(smb_session_t, s_lnd));
1499         smb_thread_init(&ld->ld_thread, name, smb_server_listener, ld,
1500             smbsrv_listen_pri);
1501         ld->ld_magic = SMB_LISTENER_MAGIC;
1502 }
1503 
1504 /*
1505  * smb_server_listener_destroy
1506  *
1507  * Destroyes listener contexts.
1508  */
1509 static void
1510 smb_server_listener_destroy(smb_listener_daemon_t *ld)
1511 {
1512         /*
1513          * Note that if startup fails early, we can legitimately
1514          * get here with an all-zeros object.
1515          */
1516         if (ld->ld_magic == 0)
1517                 return;
1518 
1519         SMB_LISTENER_VALID(ld);
1520         ASSERT(ld->ld_so == NULL);
1521         smb_thread_destroy(&ld->ld_thread);
1522         smb_llist_destructor(&ld->ld_session_list);
1523         ld->ld_magic = 0;
1524 }
1525 
1526 /*
1527  * smb_server_listener_start
1528  *
1529  * Starts the listener associated with the context passed in.
1530  *
1531  * Return:      0       Success
1532  *              not 0   Failure
1533  */
1534 static int
1535 smb_server_listener_start(smb_listener_daemon_t *ld)
1536 {
1537         int             rc;
1538         uint32_t        on;
1539         uint32_t        off;
1540 
1541         SMB_LISTENER_VALID(ld);
1542 


1600         SMB_LISTENER_VALID(ld);
1601 
1602         if (ld->ld_so != NULL) {
1603                 smb_soshutdown(ld->ld_so);
1604                 smb_sodestroy(ld->ld_so);
1605                 smb_thread_stop(&ld->ld_thread);
1606                 ld->ld_so = NULL;
1607         }
1608 }
1609 
1610 /*
1611  * smb_server_listener
1612  *
1613  * Entry point of the listeners.
1614  */
1615 static void
1616 smb_server_listener(smb_thread_t *thread, void *arg)
1617 {
1618         _NOTE(ARGUNUSED(thread))
1619         smb_listener_daemon_t   *ld;
1620         smb_session_t           *session;
1621         ksocket_t               s_so;
1622         int                     on;
1623         int                     txbuf_size;
1624 
1625         ld = (smb_listener_daemon_t *)arg;
1626 
1627         SMB_LISTENER_VALID(ld);
1628 
1629         DTRACE_PROBE1(so__wait__accept, struct sonode *, ld->ld_so);
1630 
1631         while (ksocket_accept(ld->ld_so, NULL, NULL, &s_so, CRED())
1632             == 0) {
















1633                 DTRACE_PROBE1(so__accept, struct sonode *, s_so);
1634 
1635                 on = 1;
1636                 (void) ksocket_setsockopt(s_so, IPPROTO_TCP, TCP_NODELAY,
1637                     &on, sizeof (on), CRED());
1638 
1639                 on = 1;
1640                 (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_KEEPALIVE,
1641                     &on, sizeof (on), CRED());
1642 
1643                 txbuf_size = 128*1024;
1644                 (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_SNDBUF,
1645                     (const void *)&txbuf_size, sizeof (txbuf_size), CRED());
1646 
1647                 /*
1648                  * Create a session for this connection.
1649                  */
1650                 smb_server_create_session(ld, s_so);
1651         }
1652         /* Disconnect all the sessions this listener created. */
1653         smb_llist_enter(&ld->ld_session_list, RW_READER);
1654         session = smb_llist_head(&ld->ld_session_list);
1655         while (session != NULL) {
1656                 smb_session_disconnect(session);
1657                 session = smb_llist_next(&ld->ld_session_list, session);
1658         }
1659         smb_llist_exit(&ld->ld_session_list);
1660         ksocket_rele(ld->ld_so);
1661 }
1662 
1663 /*
1664  * smb_server_receiver
1665  *
1666  * Entry point of the receiver threads.

1667  */
1668 static void
1669 smb_server_receiver(void *arg)
1670 {
1671         smb_listener_daemon_t   *ld;
1672         smb_session_t           *session;
1673 
1674         ld = ((smb_receiver_arg_t *)arg)->ra_listener;
1675         session = ((smb_receiver_arg_t *)arg)->ra_session;
1676         smb_mem_free(arg);
1677         smb_session_receiver(session);
1678         smb_server_destroy_session(ld, session);


1679 }
1680 
1681 /*
1682  * smb_server_lookup
1683  *
1684  * This function finds the server associated with the zone of the
1685  * caller.  Note: requires a fix in the dynamic taskq code:
1686  * 1501 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0
1687  */
1688 int
1689 smb_server_lookup(smb_server_t **psv)
1690 {
1691         zoneid_t        zid;
1692         smb_server_t    *sv;
1693 
1694         zid = getzoneid();
1695 
1696         smb_llist_enter(&smb_servers, RW_READER);
1697         sv = smb_llist_head(&smb_servers);
1698         while (sv) {


1721  * This function decrements the reference count of the server and signals its
1722  * condition variable if the state of the server is SMB_SERVER_STATE_DELETING.
1723  */
1724 void
1725 smb_server_release(smb_server_t *sv)
1726 {
1727         SMB_SERVER_VALID(sv);
1728 
1729         mutex_enter(&sv->sv_mutex);
1730         ASSERT(sv->sv_refcnt);
1731         sv->sv_refcnt--;
1732         if ((sv->sv_refcnt == 0) && (sv->sv_state == SMB_SERVER_STATE_DELETING))
1733                 cv_signal(&sv->sv_cv);
1734         mutex_exit(&sv->sv_mutex);
1735 }
1736 
1737 /*
1738  * Enumerate the users associated with a session list.
1739  */
1740 static void
1741 smb_server_enum_users(smb_llist_t *ll, smb_svcenum_t *svcenum)
1742 {

1743         smb_session_t   *sn;
1744         smb_llist_t     *ulist;
1745         smb_user_t      *user;
1746         int             rc = 0;
1747 
1748         smb_llist_enter(ll, RW_READER);
1749         sn = smb_llist_head(ll);
1750 
1751         while (sn != NULL) {
1752                 SMB_SESSION_VALID(sn);
1753                 ulist = &sn->s_user_list;
1754                 smb_llist_enter(ulist, RW_READER);
1755                 user = smb_llist_head(ulist);
1756 
1757                 while (user != NULL) {
1758                         if (smb_user_hold(user)) {
1759                                 rc = smb_user_enum(user, svcenum);
1760                                 smb_user_release(user);
1761                                 if (rc != 0)
1762                                         break;
1763                         }
1764 
1765                         user = smb_llist_next(ulist, user);
1766                 }
1767 
1768                 smb_llist_exit(ulist);
1769 
1770                 if (rc != 0)
1771                         break;
1772 
1773                 sn = smb_llist_next(ll, sn);
1774         }
1775 
1776         smb_llist_exit(ll);
1777 }
1778 
1779 /*
1780  * Enumerate the trees/files associated with a session list.
1781  */
1782 static void
1783 smb_server_enum_trees(smb_llist_t *ll, smb_svcenum_t *svcenum)
1784 {

1785         smb_session_t   *sn;
1786         smb_llist_t     *tlist;
1787         smb_tree_t      *tree;
1788         int             rc = 0;
1789 
1790         smb_llist_enter(ll, RW_READER);
1791         sn = smb_llist_head(ll);
1792 
1793         while (sn != NULL) {
1794                 SMB_SESSION_VALID(sn);
1795                 tlist = &sn->s_tree_list;
1796                 smb_llist_enter(tlist, RW_READER);
1797                 tree = smb_llist_head(tlist);
1798 
1799                 while (tree != NULL) {
1800                         if (smb_tree_hold(tree)) {
1801                                 rc = smb_tree_enum(tree, svcenum);
1802                                 smb_tree_release(tree);
1803                                 if (rc != 0)
1804                                         break;


1806 
1807                         tree = smb_llist_next(tlist, tree);
1808                 }
1809 
1810                 smb_llist_exit(tlist);
1811 
1812                 if (rc != 0)
1813                         break;
1814 
1815                 sn = smb_llist_next(ll, sn);
1816         }
1817 
1818         smb_llist_exit(ll);
1819 }
1820 
1821 /*
1822  * Disconnect sessions associated with the specified client and username.
1823  * Empty strings are treated as wildcards.
1824  */
1825 static int
1826 smb_server_session_disconnect(smb_llist_t *ll,
1827     const char *client, const char *name)
1828 {

1829         smb_session_t   *sn;
1830         smb_llist_t     *ulist;
1831         smb_user_t      *user;
1832         boolean_t       match;
1833         int             count = 0;
1834 
1835         smb_llist_enter(ll, RW_READER);
1836         sn = smb_llist_head(ll);
1837 
1838         while (sn != NULL) {


1839                 SMB_SESSION_VALID(sn);
1840 
1841                 if ((*client != '\0') && (!smb_session_isclient(sn, client))) {
1842                         sn = smb_llist_next(ll, sn);
1843                         continue;
1844                 }
1845 
1846                 ulist = &sn->s_user_list;
1847                 smb_llist_enter(ulist, RW_READER);
1848                 user = smb_llist_head(ulist);
1849 
1850                 while (user != NULL) {
1851                         if (smb_user_hold(user)) {
1852                                 match = (*name == '\0');
1853                                 if (!match)
1854                                         match = smb_user_namecmp(user, name);
1855 
1856                                 if (match) {
1857                                         smb_llist_exit(ulist);
1858                                         smb_user_logoff(user);
1859                                         ++count;
1860                                         smb_user_release(user);
1861                                         smb_llist_enter(ulist, RW_READER);
1862                                         user = smb_llist_head(ulist);
1863                                         continue;
1864                                 }
1865 


1866                                 smb_user_release(user);

1867                         }
1868 
1869                         user = smb_llist_next(ulist, user);
1870                 }
1871 
1872                 smb_llist_exit(ulist);
1873                 sn = smb_llist_next(ll, sn);
1874         }
1875 
1876         smb_llist_exit(ll);
1877         return (count);
1878 }
1879 
1880 /*
1881  * Close a file by its unique id.
1882  */
1883 static int
1884 smb_server_fclose(smb_llist_t *ll, uint32_t uniqid)
1885 {

1886         smb_session_t   *sn;
1887         smb_llist_t     *tlist;
1888         smb_tree_t      *tree;
1889         int             rc = ENOENT;
1890 

1891         smb_llist_enter(ll, RW_READER);
1892         sn = smb_llist_head(ll);
1893 
1894         while ((sn != NULL) && (rc == ENOENT)) {
1895                 SMB_SESSION_VALID(sn);
1896                 tlist = &sn->s_tree_list;
1897                 smb_llist_enter(tlist, RW_READER);
1898                 tree = smb_llist_head(tlist);
1899 
1900                 while ((tree != NULL) && (rc == ENOENT)) {
1901                         if (smb_tree_hold(tree)) {
1902                                 rc = smb_tree_fclose(tree, uniqid);
1903                                 smb_tree_release(tree);
1904                         }
1905 
1906                         tree = smb_llist_next(tlist, tree);
1907                 }
1908 
1909                 smb_llist_exit(tlist);
1910                 sn = smb_llist_next(ll, sn);
1911         }
1912 
1913         smb_llist_exit(ll);
1914         return (rc);
1915 }
1916 


























































1917 /* See also: libsmb smb_kmod_setcfg */
1918 static void
1919 smb_server_store_cfg(smb_server_t *sv, smb_ioc_cfg_t *ioc)
1920 {
1921         if (ioc->maxconnections == 0)
1922                 ioc->maxconnections = 0xFFFFFFFF;
1923 
1924         smb_session_correct_keep_alive_values(
1925             &sv->sv_nbt_daemon.ld_session_list, ioc->keepalive);
1926         smb_session_correct_keep_alive_values(
1927             &sv->sv_tcp_daemon.ld_session_list, ioc->keepalive);


1928 
1929         sv->sv_cfg.skc_maxworkers = ioc->maxworkers;
1930         sv->sv_cfg.skc_maxconnections = ioc->maxconnections;
1931         sv->sv_cfg.skc_keepalive = ioc->keepalive;
1932         sv->sv_cfg.skc_restrict_anon = ioc->restrict_anon;
1933         sv->sv_cfg.skc_signing_enable = ioc->signing_enable;
1934         sv->sv_cfg.skc_signing_required = ioc->signing_required;
1935         sv->sv_cfg.skc_oplock_enable = ioc->oplock_enable;
1936         sv->sv_cfg.skc_sync_enable = ioc->sync_enable;
1937         sv->sv_cfg.skc_secmode = ioc->secmode;
1938         sv->sv_cfg.skc_netbios_enable = ioc->netbios_enable;
1939         sv->sv_cfg.skc_ipv6_enable = ioc->ipv6_enable;
1940         sv->sv_cfg.skc_print_enable = ioc->print_enable;
1941         sv->sv_cfg.skc_traverse_mounts = ioc->traverse_mounts;
1942         sv->sv_cfg.skc_max_protocol = ioc->max_protocol;


1943         sv->sv_cfg.skc_execflags = ioc->exec_flags;
1944         sv->sv_cfg.skc_negtok_len = ioc->negtok_len;
1945         sv->sv_cfg.skc_version = ioc->version;
1946         sv->sv_cfg.skc_initial_credits = ioc->initial_credits;
1947         sv->sv_cfg.skc_maximum_credits = ioc->maximum_credits;
1948 
1949         (void) memcpy(sv->sv_cfg.skc_machine_uuid, ioc->machine_uuid,
1950             sizeof (uuid_t));
1951         (void) memcpy(sv->sv_cfg.skc_negtok, ioc->negtok,
1952             sizeof (sv->sv_cfg.skc_negtok));
1953         (void) memcpy(sv->sv_cfg.skc_native_os, ioc->native_os,
1954             sizeof (sv->sv_cfg.skc_native_os));
1955         (void) memcpy(sv->sv_cfg.skc_native_lm, ioc->native_lm,
1956             sizeof (sv->sv_cfg.skc_native_lm));
1957 
1958         (void) strlcpy(sv->sv_cfg.skc_nbdomain, ioc->nbdomain,
1959             sizeof (sv->sv_cfg.skc_nbdomain));
1960         (void) strlcpy(sv->sv_cfg.skc_fqdn, ioc->fqdn,
1961             sizeof (sv->sv_cfg.skc_fqdn));
1962         (void) strlcpy(sv->sv_cfg.skc_hostname, ioc->hostname,


2306         smb_llist_t     *splist;
2307         smb_server_t    *sv = tree->t_server;
2308         int rc = 0;
2309 
2310         splist = &sv->sp_info.sp_list;
2311         smb_llist_enter(splist, RW_WRITER);
2312         sp->sd_spool_num = atomic_inc_32_nv(&sv->sp_info.sp_cnt);
2313         smb_llist_insert_tail(splist, sp);
2314         smb_llist_exit(splist);
2315 
2316         return (rc);
2317 }
2318 
2319 /*
2320  * smb_server_create_session
2321  */
2322 static void
2323 smb_server_create_session(smb_listener_daemon_t *ld, ksocket_t s_so)
2324 {
2325         smb_session_t           *session;
2326         smb_receiver_arg_t      *rarg;
2327         taskqid_t               tqid;


2328 
2329         session = smb_session_create(s_so, ld->ld_port, ld->ld_sv,
2330             ld->ld_family);
2331 
2332         if (session == NULL) {
2333                 smb_soshutdown(s_so);
2334                 smb_sodestroy(s_so);
2335                 cmn_err(CE_WARN, "SMB Session: alloc failed");
2336                 return;
2337         }
2338 
2339         smb_llist_enter(&ld->ld_session_list, RW_WRITER);
2340         smb_llist_insert_tail(&ld->ld_session_list, session);
2341         smb_llist_exit(&ld->ld_session_list);

2342 
2343         rarg = (smb_receiver_arg_t *)smb_mem_alloc(
2344             sizeof (smb_receiver_arg_t));
2345         rarg->ra_listener = ld;
2346         rarg->ra_session = session;
2347 
2348         /*
2349          * These taskq entries must run independently of one another,
2350          * so TQ_NOQUEUE.  TQ_SLEEP (==0) just for clarity.
2351          */
2352         tqid = taskq_dispatch(ld->ld_sv->sv_receiver_pool,
2353             smb_server_receiver, rarg, TQ_NOQUEUE | TQ_SLEEP);
2354         if (tqid == 0) {
2355                 smb_mem_free(rarg);
2356                 smb_session_disconnect(session);
2357                 smb_server_destroy_session(ld, session);
2358                 cmn_err(CE_WARN, "SMB Session: taskq_dispatch failed");
2359                 return;
2360         }
2361         /* handy for debugging */
2362         session->s_receiver_tqid = tqid;
2363 }
2364 
2365 static void
2366 smb_server_destroy_session(smb_listener_daemon_t *ld, smb_session_t *session)
2367 {
2368         smb_llist_enter(&ld->ld_session_list, RW_WRITER);
2369         smb_llist_remove(&ld->ld_session_list, session);
2370         smb_llist_exit(&ld->ld_session_list);



























2371         smb_session_delete(session);




2372 }


   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 (c) 2017 by Delphix. All rights reserved.
  24  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  25  */
  26 
  27 /*
  28  * General Structures Layout
  29  * -------------------------
  30  *
  31  * This is a simplified diagram showing the relationship between most of the
  32  * main structures.
  33  *
  34  * +-------------------+
  35  * |     SMB_SERVER    |
  36  * +-------------------+
  37  *          |
  38  *          |
  39  *          v
  40  * +-------------------+       +-------------------+      +-------------------+
  41  * |     SESSION       |<----->|     SESSION       |......|      SESSION      |
  42  * +-------------------+       +-------------------+      +-------------------+
  43  *          |
  44  *          |


 202  * enforced in user space.
 203  */
 204 
 205 #include <sys/cmn_err.h>
 206 #include <sys/priv.h>
 207 #include <sys/zone.h>
 208 #include <netinet/in.h>
 209 #include <netinet/in_systm.h>
 210 #include <netinet/ip.h>
 211 #include <netinet/ip_icmp.h>
 212 #include <netinet/ip_var.h>
 213 #include <netinet/tcp.h>
 214 #include <smbsrv/smb2_kproto.h>
 215 #include <smbsrv/string.h>
 216 #include <smbsrv/netbios.h>
 217 #include <smbsrv/smb_fsops.h>
 218 #include <smbsrv/smb_share.h>
 219 #include <smbsrv/smb_door.h>
 220 #include <smbsrv/smb_kstat.h>
 221 







 222 static void smb_server_kstat_init(smb_server_t *);
 223 static void smb_server_kstat_fini(smb_server_t *);
 224 static void smb_server_timers(smb_thread_t *, void *);
 225 static void smb_server_store_cfg(smb_server_t *, smb_ioc_cfg_t *);
 226 static void smb_server_shutdown(smb_server_t *);
 227 static int smb_server_fsop_start(smb_server_t *);
 228 static void smb_server_fsop_stop(smb_server_t *);
 229 static void smb_event_cancel(smb_server_t *, uint32_t);
 230 static uint32_t smb_event_alloc_txid(void);
 231 
 232 static void smb_server_disconnect_share(smb_server_t *, const char *);
 233 static void smb_server_enum_users(smb_server_t *, smb_svcenum_t *);
 234 static void smb_server_enum_trees(smb_server_t *, smb_svcenum_t *);
 235 static int smb_server_session_disconnect(smb_server_t *, const char *,
 236     const char *);
 237 static int smb_server_fclose(smb_server_t *, uint32_t);
 238 static int smb_server_kstat_update(kstat_t *, int);
 239 static int smb_server_legacy_kstat_update(kstat_t *, int);
 240 static void smb_server_listener_init(smb_server_t *, smb_listener_daemon_t *,
 241     char *, in_port_t, int);
 242 static void smb_server_listener_destroy(smb_listener_daemon_t *);
 243 static int smb_server_listener_start(smb_listener_daemon_t *);
 244 static void smb_server_listener_stop(smb_listener_daemon_t *);
 245 static void smb_server_listener(smb_thread_t *, void *);
 246 static void smb_server_receiver(void *);
 247 static void smb_server_create_session(smb_listener_daemon_t *, ksocket_t);
 248 static void smb_server_destroy_session(smb_session_t *);

 249 static uint16_t smb_spool_get_fid(smb_server_t *);
 250 static boolean_t smb_spool_lookup_doc_byfid(smb_server_t *, uint16_t,
 251     smb_kspooldoc_t *);
 252 
 253 /*
 254  * How many "buckets" should our hash tables use?  On a "real" server,
 255  * make them much larger than the number of CPUs we're likely to have.
 256  * On "fksmbd" make it smaller so dtrace logs are shorter.
 257  * These must be powers of two.
 258  */
 259 #ifdef  _KERNEL
 260 #define DEFAULT_HASH_NBUCKETS   256     /* real server */
 261 #else
 262 #define DEFAULT_HASH_NBUCKETS   16      /* for "fksmbd" */
 263 #endif
 264 uint32_t SMB_OFILE_HASH_NBUCKETS = DEFAULT_HASH_NBUCKETS;
 265 uint32_t SMB_LEASE_HASH_NBUCKETS = DEFAULT_HASH_NBUCKETS;
 266 
 267 int smb_event_debug = 0;
 268 
 269 static smb_llist_t      smb_servers;
 270 
 271 kmem_cache_t            *smb_cache_request;
 272 kmem_cache_t            *smb_cache_session;
 273 kmem_cache_t            *smb_cache_user;
 274 kmem_cache_t            *smb_cache_tree;
 275 kmem_cache_t            *smb_cache_ofile;
 276 kmem_cache_t            *smb_cache_odir;
 277 kmem_cache_t            *smb_cache_opipe;
 278 kmem_cache_t            *smb_cache_event;
 279 kmem_cache_t            *smb_cache_lock;
 280 
 281 /*
 282  * *****************************************************************************
 283  * **************** Functions called from the device interface *****************
 284  * *****************************************************************************
 285  *
 286  * These functions typically have to determine the relevant smb server
 287  * to which the call applies.
 288  */
 289 
 290 /*
 291  * How many zones have an SMB server active?
 292  */
 293 int
 294 smb_server_get_count(void)
 295 {
 296         return (smb_llist_get_count(&smb_servers));
 297 }
 298 
 299 /*
 300  * smb_server_g_init
 301  *
 302  * This function must be called from smb_drv_attach().
 303  */
 304 int
 305 smb_server_g_init(void)
 306 {
 307         int rc;
 308 
 309         if ((rc = smb_vop_init()) != 0)
 310                 goto errout;
 311         if ((rc = smb_fem_init()) != 0)
 312                 goto errout;
 313 
 314         smb_kshare_g_init();
 315         smb_codepage_init();
 316         smb_mbc_init();         /* smb_mbc_cache */
 317         smb_node_init();        /* smb_node_cache, lists */
 318         smb2_lease_init();
 319 
 320         smb_cache_request = kmem_cache_create("smb_request_cache",
 321             sizeof (smb_request_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 322         smb_cache_session = kmem_cache_create("smb_session_cache",
 323             sizeof (smb_session_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 324         smb_cache_user = kmem_cache_create("smb_user_cache",
 325             sizeof (smb_user_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 326         smb_cache_tree = kmem_cache_create("smb_tree_cache",
 327             sizeof (smb_tree_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 328         smb_cache_ofile = kmem_cache_create("smb_ofile_cache",
 329             sizeof (smb_ofile_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 330         smb_cache_odir = kmem_cache_create("smb_odir_cache",
 331             sizeof (smb_odir_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 332         smb_cache_opipe = kmem_cache_create("smb_opipe_cache",
 333             sizeof (smb_opipe_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 334         smb_cache_event = kmem_cache_create("smb_event_cache",
 335             sizeof (smb_event_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 336         smb_cache_lock = kmem_cache_create("smb_lock_cache",
 337             sizeof (smb_lock_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 338 
 339         smb_llist_init();
 340         smb_llist_constructor(&smb_servers, sizeof (smb_server_t),
 341             offsetof(smb_server_t, sv_lnd));
 342 
 343         return (0);
 344 
 345 errout:
 346         smb_fem_fini();
 347         smb_vop_fini();
 348         return (rc);
 349 }
 350 
 351 /*
 352  * smb_server_g_fini
 353  *
 354  * This function must called from smb_drv_detach(). It will fail if servers
 355  * still exist.
 356  */
 357 void
 358 smb_server_g_fini(void)
 359 {
 360 
 361         ASSERT(smb_llist_get_count(&smb_servers) == 0);
 362 
 363         smb_llist_fini();
 364 
 365         kmem_cache_destroy(smb_cache_request);
 366         kmem_cache_destroy(smb_cache_session);
 367         kmem_cache_destroy(smb_cache_user);
 368         kmem_cache_destroy(smb_cache_tree);
 369         kmem_cache_destroy(smb_cache_ofile);
 370         kmem_cache_destroy(smb_cache_odir);
 371         kmem_cache_destroy(smb_cache_opipe);
 372         kmem_cache_destroy(smb_cache_event);
 373         kmem_cache_destroy(smb_cache_lock);
 374 
 375         smb2_lease_fini();
 376         smb_node_fini();
 377         smb_mbc_fini();
 378         smb_codepage_fini();
 379         smb_kshare_g_fini();
 380 
 381         smb_fem_fini();
 382         smb_vop_fini();
 383 
 384         smb_llist_destructor(&smb_servers);
 385 }
 386 
 387 /*
 388  * smb_server_create
 389  *
 390  * This function will fail if there's already a server associated with the
 391  * caller's zone.
 392  */
 393 int
 394 smb_server_create(void)
 395 {


 403         while (sv) {
 404                 SMB_SERVER_VALID(sv);
 405                 if (sv->sv_zid == zid) {
 406                         smb_llist_exit(&smb_servers);
 407                         return (EPERM);
 408                 }
 409                 sv = smb_llist_next(&smb_servers, sv);
 410         }
 411 
 412         sv = kmem_zalloc(sizeof (smb_server_t), KM_SLEEP);
 413 
 414         sv->sv_magic = SMB_SERVER_MAGIC;
 415         sv->sv_state = SMB_SERVER_STATE_CREATED;
 416         sv->sv_zid = zid;
 417         sv->sv_pid = ddi_get_pid();
 418 
 419         mutex_init(&sv->sv_mutex, NULL, MUTEX_DEFAULT, NULL);
 420         cv_init(&sv->sv_cv, NULL, CV_DEFAULT, NULL);
 421         cv_init(&sv->sp_info.sp_cv, NULL, CV_DEFAULT, NULL);
 422 
 423         sv->sv_persistid_ht = smb_hash_create(sizeof (smb_ofile_t),
 424             offsetof(smb_ofile_t, f_dh_lnd), SMB_OFILE_HASH_NBUCKETS);
 425 
 426         sv->sv_lease_ht = smb_hash_create(sizeof (smb_lease_t),
 427             offsetof(smb_lease_t, ls_lnd), SMB_LEASE_HASH_NBUCKETS);
 428 
 429         smb_llist_constructor(&sv->sv_session_list, sizeof (smb_session_t),
 430             offsetof(smb_session_t, s_lnd));
 431 
 432         smb_llist_constructor(&sv->sv_event_list, sizeof (smb_event_t),
 433             offsetof(smb_event_t, se_lnd));
 434 
 435         smb_llist_constructor(&sv->sp_info.sp_list, sizeof (smb_kspooldoc_t),
 436             offsetof(smb_kspooldoc_t, sd_lnd));
 437 
 438         smb_llist_constructor(&sv->sp_info.sp_fidlist,
 439             sizeof (smb_spoolfid_t), offsetof(smb_spoolfid_t, sf_lnd));
 440 
 441         sv->sv_disp_stats1 = kmem_zalloc(SMB_COM_NUM *
 442             sizeof (smb_disp_stats_t), KM_SLEEP);
 443 
 444         sv->sv_disp_stats2 = kmem_zalloc(SMB2__NCMDS *
 445             sizeof (smb_disp_stats_t), KM_SLEEP);
 446 
 447         smb_thread_init(&sv->si_thread_timers, "smb_timers",
 448             smb_server_timers, sv, smbsrv_timer_pri);
 449 
 450         smb_srqueue_init(&sv->sv_srqueue);
 451 


 456         smb_threshold_init(&sv->sv_ssetup_ct, SMB_SSETUP_CMD,
 457             smb_ssetup_threshold, smb_ssetup_timeout);
 458         smb_threshold_init(&sv->sv_tcon_ct, SMB_TCON_CMD,
 459             smb_tcon_threshold, smb_tcon_timeout);
 460         smb_threshold_init(&sv->sv_opipe_ct, SMB_OPIPE_CMD,
 461             smb_opipe_threshold, smb_opipe_timeout);
 462 
 463         smb_llist_insert_tail(&smb_servers, sv);
 464         smb_llist_exit(&smb_servers);
 465 
 466         return (0);
 467 }
 468 
 469 /*
 470  * smb_server_delete
 471  *
 472  * This function will delete the server passed in. It will make sure that all
 473  * activity associated that server has ceased before destroying it.
 474  */
 475 int
 476 smb_server_delete(smb_server_t  *sv)
 477 {


 478 




 479         mutex_enter(&sv->sv_mutex);
 480         switch (sv->sv_state) {
 481         case SMB_SERVER_STATE_RUNNING:
 482                 sv->sv_state = SMB_SERVER_STATE_STOPPING;
 483                 mutex_exit(&sv->sv_mutex);
 484                 smb_server_shutdown(sv);
 485                 mutex_enter(&sv->sv_mutex);
 486                 cv_broadcast(&sv->sp_info.sp_cv);
 487                 sv->sv_state = SMB_SERVER_STATE_DELETING;
 488                 break;
 489         case SMB_SERVER_STATE_STOPPING:
 490                 sv->sv_state = SMB_SERVER_STATE_DELETING;
 491                 break;
 492         case SMB_SERVER_STATE_CONFIGURED:
 493         case SMB_SERVER_STATE_CREATED:
 494                 sv->sv_state = SMB_SERVER_STATE_DELETING;
 495                 break;
 496         default:
 497                 SMB_SERVER_STATE_VALID(sv->sv_state);
 498                 mutex_exit(&sv->sv_mutex);


 506         while (sv->sv_refcnt)
 507                 cv_wait(&sv->sv_cv, &sv->sv_mutex);
 508 
 509         mutex_exit(&sv->sv_mutex);
 510 
 511         smb_llist_enter(&smb_servers, RW_WRITER);
 512         smb_llist_remove(&smb_servers, sv);
 513         smb_llist_exit(&smb_servers);
 514 
 515         smb_threshold_fini(&sv->sv_ssetup_ct);
 516         smb_threshold_fini(&sv->sv_tcon_ct);
 517         smb_threshold_fini(&sv->sv_opipe_ct);
 518 
 519         smb_server_listener_destroy(&sv->sv_nbt_daemon);
 520         smb_server_listener_destroy(&sv->sv_tcp_daemon);
 521         rw_destroy(&sv->sv_cfg_lock);
 522         smb_server_kstat_fini(sv);
 523         smb_kshare_fini(sv);
 524         smb_kdoor_fini(sv);
 525         smb_llist_destructor(&sv->sv_event_list);
 526         smb_llist_destructor(&sv->sv_session_list);
 527 
 528         kmem_free(sv->sv_disp_stats1,
 529             SMB_COM_NUM * sizeof (smb_disp_stats_t));
 530 
 531         kmem_free(sv->sv_disp_stats2,
 532             SMB2__NCMDS * sizeof (smb_disp_stats_t));
 533 
 534         smb_srqueue_destroy(&sv->sv_srqueue);
 535         smb_thread_destroy(&sv->si_thread_timers);
 536 
 537         mutex_destroy(&sv->sv_mutex);
 538         smb_hash_destroy(sv->sv_lease_ht);
 539         smb_hash_destroy(sv->sv_persistid_ht);
 540         cv_destroy(&sv->sv_cv);
 541         sv->sv_magic = 0;
 542         kmem_free(sv, sizeof (smb_server_t));
 543 
 544         return (0);
 545 }
 546 
 547 /*
 548  * smb_server_configure
 549  */
 550 int
 551 smb_server_configure(smb_ioc_cfg_t *ioc)
 552 {
 553         int             rc = 0;
 554         smb_server_t    *sv;
 555 
 556         /*
 557          * Reality check negotiation token length vs. #define'd maximum.
 558          */
 559         if (ioc->negtok_len > SMB_PI_MAX_NEGTOK)


 585                 SMB_SERVER_STATE_VALID(sv->sv_state);
 586                 rc = EFAULT;
 587                 break;
 588         }
 589         mutex_exit(&sv->sv_mutex);
 590 
 591         smb_server_release(sv);
 592 
 593         return (rc);
 594 }
 595 
 596 /*
 597  * smb_server_start
 598  */
 599 int
 600 smb_server_start(smb_ioc_start_t *ioc)
 601 {
 602         int             rc = 0;
 603         int             family;
 604         smb_server_t    *sv;
 605         cred_t          *ucr;
 606 
 607         rc = smb_server_lookup(&sv);
 608         if (rc)
 609                 return (rc);
 610 
 611         mutex_enter(&sv->sv_mutex);
 612         switch (sv->sv_state) {
 613         case SMB_SERVER_STATE_CONFIGURED:
 614 
 615                 if ((rc = smb_server_fsop_start(sv)) != 0)
 616                         break;
 617 
 618                 /*
 619                  * Note: smb_kshare_start needs sv_session.
 620                  */
 621                 sv->sv_session = smb_session_create(NULL, 0, sv, 0);
 622                 if (sv->sv_session == NULL) {
 623                         rc = ENOMEM;
 624                         break;
 625                 }
 626 
 627                 /*
 628                  * Create a logon on the server session,
 629                  * used when importing CA shares.
 630                  */
 631                 sv->sv_rootuser = smb_user_new(sv->sv_session);
 632                 ucr = smb_kcred_create();
 633                 rc = smb_user_logon(sv->sv_rootuser, ucr, "", "root",
 634                     SMB_USER_FLAG_ADMIN, 0, 0);
 635                 crfree(ucr);
 636                 ucr = NULL;
 637                 if (rc != 0) {
 638                         cmn_err(CE_NOTE, "smb_server_start: "
 639                             "failed to create root user");
 640                         break;
 641                 }
 642 
 643                 if ((rc = smb_kshare_start(sv)) != 0)
 644                         break;
 645 
 646                 /*
 647                  * NB: the proc passed here has to be a "system" one.
 648                  * Normally that's p0, or the NGZ eqivalent.
 649                  */
 650                 sv->sv_worker_pool = taskq_create_proc("smb_workers",
 651                     sv->sv_cfg.skc_maxworkers, smbsrv_worker_pri,
 652                     sv->sv_cfg.skc_maxworkers, INT_MAX,
 653                     curzone->zone_zsched, TASKQ_DYNAMIC);
 654 
 655                 sv->sv_receiver_pool = taskq_create_proc("smb_receivers",
 656                     sv->sv_cfg.skc_maxconnections, smbsrv_receive_pri,
 657                     sv->sv_cfg.skc_maxconnections, INT_MAX,
 658                     curzone->zone_zsched, TASKQ_DYNAMIC);
 659 
 660                 if (sv->sv_worker_pool == NULL ||
 661                     sv->sv_receiver_pool == NULL) {

 662                         rc = ENOMEM;
 663                         break;
 664                 }
 665 
 666 #ifdef  _KERNEL
 667                 ASSERT(sv->sv_lmshrd == NULL);
 668                 sv->sv_lmshrd = smb_kshare_door_init(ioc->lmshrd);
 669                 if (sv->sv_lmshrd == NULL)
 670                         break;
 671                 if ((rc = smb_kdoor_open(sv, ioc->udoor)) != 0) {
 672                         cmn_err(CE_WARN, "Cannot open smbd door");
 673                         break;
 674                 }
 675 #else   /* _KERNEL */
 676                 /* Fake kernel does not use the kshare_door */
 677                 fksmb_kdoor_open(sv, ioc->udoor_func);
 678 #endif  /* _KERNEL */
 679 
 680                 if ((rc = smb_thread_start(&sv->si_thread_timers)) != 0)
 681                         break;
 682 
 683                 family = AF_INET;
 684                 smb_server_listener_init(sv, &sv->sv_nbt_daemon,
 685                     "smb_nbt_listener", IPPORT_NETBIOS_SSN, family);
 686                 if (sv->sv_cfg.skc_ipv6_enable)
 687                         family = AF_INET6;
 688                 smb_server_listener_init(sv, &sv->sv_tcp_daemon,
 689                     "smb_tcp_listener", IPPORT_SMB, family);
 690                 rc = smb_server_listener_start(&sv->sv_tcp_daemon);
 691                 if (rc != 0)
 692                         break;
 693                 if (sv->sv_cfg.skc_netbios_enable)
 694                         (void) smb_server_listener_start(&sv->sv_nbt_daemon);
 695 
 696                 sv->sv_state = SMB_SERVER_STATE_RUNNING;
 697                 sv->sv_start_time = gethrtime();
 698                 mutex_exit(&sv->sv_mutex);
 699                 smb_server_release(sv);
 700                 smb_export_start(sv);


 890         smb_svcenum_t   *svcenum = &ioc->svcenum;
 891         smb_server_t    *sv;
 892         int             rc;
 893 
 894         /*
 895          * Reality check that the buffer-length insize the enum doesn't
 896          * overrun the ioctl's total length.
 897          */
 898         if (svcenum->se_buflen + sizeof (*ioc) > ioc->hdr.len)
 899                 return (EINVAL);
 900 
 901         if ((rc = smb_server_lookup(&sv)) != 0)
 902                 return (rc);
 903 
 904         svcenum->se_bavail = svcenum->se_buflen;
 905         svcenum->se_bused = 0;
 906         svcenum->se_nitems = 0;
 907 
 908         switch (svcenum->se_type) {
 909         case SMB_SVCENUM_TYPE_USER:
 910                 smb_server_enum_users(sv, svcenum);



 911                 break;
 912         case SMB_SVCENUM_TYPE_TREE:
 913         case SMB_SVCENUM_TYPE_FILE:
 914                 smb_server_enum_trees(sv, svcenum);



 915                 break;
 916         default:
 917                 rc = EINVAL;
 918         }
 919 
 920         smb_server_release(sv);
 921         return (rc);
 922 }
 923 
 924 /*
 925  * Look for sessions to disconnect by client and user name.
 926  */
 927 int
 928 smb_server_session_close(smb_ioc_session_t *ioc)
 929 {

 930         smb_server_t    *sv;
 931         int             cnt;

 932         int             rc;
 933 
 934         if ((rc = smb_server_lookup(&sv)) != 0)
 935                 return (rc);
 936 
 937         cnt = smb_server_session_disconnect(sv, ioc->client, ioc->username);

 938 



 939         smb_server_release(sv);
 940 
 941         if (cnt == 0)
 942                 return (ENOENT);
 943         return (0);
 944 }
 945 
 946 /*
 947  * Close a file by uniqid.
 948  */
 949 int
 950 smb_server_file_close(smb_ioc_fileid_t *ioc)
 951 {
 952         uint32_t        uniqid = ioc->uniqid;

 953         smb_server_t    *sv;
 954         int             rc;
 955 
 956         if ((rc = smb_server_lookup(&sv)) != 0)
 957                 return (rc);
 958 
 959         rc = smb_server_fclose(sv, uniqid);

 960 





 961         smb_server_release(sv);
 962         return (rc);
 963 }
 964 
 965 /*
 966  * These functions determine the relevant smb server to which the call apply.
 967  */
 968 
 969 uint32_t
 970 smb_server_get_session_count(smb_server_t *sv)
 971 {
 972         uint32_t        counter = 0;
 973 
 974         counter = smb_llist_get_count(&sv->sv_session_list);

 975 
 976         return (counter);
 977 }
 978 
 979 /*
 980  * Gets the smb_node of the specified share path.
 981  * Node is returned held (caller must rele.)


 982  */
 983 int
 984 smb_server_share_lookup(smb_server_t *sv, const char *shr_path,
 985     smb_node_t **nodepp)
 986 {
 987         smb_request_t   *sr;
 988         smb_node_t      *fnode = NULL;
 989         smb_node_t      *dnode = NULL;
 990         char            last_comp[MAXNAMELEN];
 991         int             rc = 0;
 992 
 993         ASSERT(shr_path);
 994 
 995         mutex_enter(&sv->sv_mutex);
 996         switch (sv->sv_state) {
 997         case SMB_SERVER_STATE_RUNNING:
 998                 break;
 999         default:
1000                 mutex_exit(&sv->sv_mutex);
1001                 return (ENOTACTIVE);
1002         }
1003         mutex_exit(&sv->sv_mutex);
1004 
1005         if ((sr = smb_request_alloc(sv->sv_session, 0)) == NULL) {
1006                 return (ENOTCONN);
1007         }
1008         sr->user_cr = zone_kcred();
1009 
1010         rc = smb_pathname_reduce(sr, sr->user_cr, shr_path,
1011             NULL, NULL, &dnode, last_comp);
1012 
1013         if (rc == 0) {
1014                 rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
1015                     sv->si_root_smb_node, dnode, last_comp, &fnode);
1016                 smb_node_release(dnode);
1017         }
1018 
1019         smb_request_free(sr);
1020 
1021         if (rc != 0)
1022                 return (rc);
1023 
1024         ASSERT(fnode->vp && fnode->vp->v_vfsp);
1025 
1026         *nodepp = fnode;

1027 


1028         return (0);
1029 }
1030 
1031 #ifdef  _KERNEL
1032 /*
1033  * This is a special interface that will be utilized by ZFS to cause a share to
1034  * be added/removed.
1035  *
1036  * arg is either a lmshare_info_t or share_name from userspace.
1037  * It will need to be copied into the kernel.   It is lmshare_info_t
1038  * for add operations and share_name for delete operations.
1039  */
1040 int
1041 smb_server_share(void *arg, boolean_t add_share)
1042 {
1043         smb_server_t    *sv;
1044         int             rc;
1045 
1046         if ((rc = smb_server_lookup(&sv)) == 0) {
1047                 mutex_enter(&sv->sv_mutex);
1048                 switch (sv->sv_state) {
1049                 case SMB_SERVER_STATE_RUNNING:
1050                         mutex_exit(&sv->sv_mutex);
1051                         (void) smb_kshare_upcall(sv->sv_lmshrd, arg, add_share);
1052                         break;
1053                 default:
1054                         mutex_exit(&sv->sv_mutex);
1055                         break;
1056                 }
1057                 smb_server_release(sv);
1058         }
1059 
1060         return (rc);
1061 }
1062 #endif  /* _KERNEL */
1063 
1064 int
1065 smb_server_unshare(const char *sharename)
1066 {
1067         smb_server_t    *sv;

1068         int             rc;
1069 
1070         if ((rc = smb_server_lookup(&sv)))
1071                 return (rc);
1072 
1073         mutex_enter(&sv->sv_mutex);
1074         switch (sv->sv_state) {
1075         case SMB_SERVER_STATE_RUNNING:
1076         case SMB_SERVER_STATE_STOPPING:
1077                 break;
1078         default:
1079                 mutex_exit(&sv->sv_mutex);
1080                 smb_server_release(sv);
1081                 return (ENOTACTIVE);
1082         }
1083         mutex_exit(&sv->sv_mutex);
1084 
1085         smb_server_disconnect_share(sv, sharename);

1086 



1087         smb_server_release(sv);
1088         return (0);
1089 }
1090 
1091 /*
1092  * Disconnect the specified share.
1093  * Typically called when a share has been removed.
1094  */
1095 static void
1096 smb_server_disconnect_share(smb_server_t *sv, const char *sharename)
1097 {
1098         smb_llist_t     *ll;
1099         smb_session_t   *session;
1100 
1101         ll = &sv->sv_session_list;
1102         smb_llist_enter(ll, RW_READER);
1103 
1104         session = smb_llist_head(ll);
1105         while (session) {
1106                 SMB_SESSION_VALID(session);
1107                 smb_rwx_rwenter(&session->s_lock, RW_READER);
1108                 switch (session->s_state) {
1109                 case SMB_SESSION_STATE_NEGOTIATED:
1110                         smb_rwx_rwexit(&session->s_lock);
1111                         smb_session_disconnect_share(session, sharename);
1112                         break;
1113                 default:
1114                         smb_rwx_rwexit(&session->s_lock);
1115                         break;
1116                 }

1117                 session = smb_llist_next(ll, session);
1118         }
1119 
1120         smb_llist_exit(ll);
1121 }
1122 
1123 /*
1124  * *****************************************************************************
1125  * **************** Functions called from the internal layers ******************
1126  * *****************************************************************************
1127  *
1128  * These functions are provided the relevant smb server by the caller.
1129  */
1130 
1131 void
1132 smb_server_get_cfg(smb_server_t *sv, smb_kmod_cfg_t *cfg)
1133 {
1134         rw_enter(&sv->sv_cfg_lock, RW_READER);
1135         bcopy(&sv->sv_cfg, cfg, sizeof (*cfg));
1136         rw_exit(&sv->sv_cfg_lock);


1241 smb_server_inc_req(smb_server_t *sv)
1242 {
1243         SMB_SERVER_VALID(sv);
1244         atomic_inc_64(&sv->sv_nreq);
1245 }
1246 
1247 /*
1248  * *****************************************************************************
1249  * *************************** Static Functions ********************************
1250  * *****************************************************************************
1251  */
1252 
1253 static void
1254 smb_server_timers(smb_thread_t *thread, void *arg)
1255 {
1256         smb_server_t    *sv = (smb_server_t *)arg;
1257 
1258         ASSERT(sv != NULL);
1259 
1260         /*
1261          * This kills old inactive sessions and expired durable
1262          * handles. The session code expects one call per minute.
1263          */
1264         while (smb_thread_continue_timedwait(thread, 60 /* Seconds */)) {
1265                 if (sv->sv_cfg.skc_keepalive != 0)
1266                         smb_session_timers(sv);
1267                 smb2_durable_timers(sv);
1268         }
1269 }
1270 
1271 /*
1272  * smb_server_kstat_init
1273  */
1274 static void
1275 smb_server_kstat_init(smb_server_t *sv)
1276 {
1277 
1278         sv->sv_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, 0,
1279             SMBSRV_KSTAT_STATISTICS, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_RAW,
1280             sizeof (smbsrv_kstats_t), 0, sv->sv_zid);
1281 
1282         if (sv->sv_ksp != NULL) {
1283                 sv->sv_ksp->ks_update = smb_server_kstat_update;
1284                 sv->sv_ksp->ks_private = sv;
1285                 ((smbsrv_kstats_t *)sv->sv_ksp->ks_data)->ks_start_time =
1286                     sv->sv_start_time;
1287                 smb_dispatch_stats_init(sv);


1324  * smb_server_kstat_fini
1325  */
1326 static void
1327 smb_server_kstat_fini(smb_server_t *sv)
1328 {
1329         if (sv->sv_legacy_ksp != NULL) {
1330                 kstat_delete(sv->sv_legacy_ksp);
1331                 mutex_destroy(&sv->sv_legacy_ksmtx);
1332                 sv->sv_legacy_ksp = NULL;
1333         }
1334 
1335         if (sv->sv_ksp != NULL) {
1336                 kstat_delete(sv->sv_ksp);
1337                 sv->sv_ksp = NULL;
1338                 smb_dispatch_stats_fini(sv);
1339                 smb2_dispatch_stats_fini(sv);
1340         }
1341 }
1342 
1343 /*
1344  * Verify the defines in smb_kstat.h used by ks_reqs1 ks_reqs2
1345  */
1346 CTASSERT(SMBSRV_KS_NREQS1 == SMB_COM_NUM);
1347 CTASSERT(SMBSRV_KS_NREQS2 == SMB2__NCMDS);
1348 
1349 /*
1350  * smb_server_kstat_update
1351  */
1352 static int
1353 smb_server_kstat_update(kstat_t *ksp, int rw)
1354 {
1355         smb_server_t    *sv;
1356         smbsrv_kstats_t *ksd;
1357 
1358         if (rw == KSTAT_READ) {
1359                 sv = ksp->ks_private;
1360                 SMB_SERVER_VALID(sv);
1361                 ksd = (smbsrv_kstats_t *)ksp->ks_data;
1362                 /*
1363                  * Counters
1364                  */
1365                 ksd->ks_nbt_sess = sv->sv_nbt_sess;
1366                 ksd->ks_tcp_sess = sv->sv_tcp_sess;
1367                 ksd->ks_users = sv->sv_users;
1368                 ksd->ks_trees = sv->sv_trees;
1369                 ksd->ks_files = sv->sv_files;


1414                         ksd->ls_users.value.ui32 = sv->sv_users;
1415                         smb_server_release(sv);
1416                         rc = 0;
1417                         break;
1418                 }
1419                 _NOTE(FALLTHRU)
1420         default:
1421                 rc = EIO;
1422                 break;
1423         }
1424         return (rc);
1425 
1426 }
1427 
1428 /*
1429  * smb_server_shutdown
1430  */
1431 static void
1432 smb_server_shutdown(smb_server_t *sv)
1433 {
1434         smb_llist_t *sl = &sv->sv_session_list;
1435         smb_session_t *session;
1436         clock_t time;
1437 
1438         SMB_SERVER_VALID(sv);
1439 
1440         /*
1441          * Stop the listeners first, so we don't get any more
1442          * new work while we're trying to shut down.
1443          */
1444         smb_server_listener_stop(&sv->sv_nbt_daemon);
1445         smb_server_listener_stop(&sv->sv_tcp_daemon);
1446         smb_thread_stop(&sv->si_thread_timers);
1447 
1448         /* Disconnect all of the sessions */
1449         smb_llist_enter(sl, RW_READER);
1450         session = smb_llist_head(sl);
1451         while (session != NULL) {
1452                 smb_session_disconnect(session);
1453                 session = smb_llist_next(sl, session);
1454         }
1455         smb_llist_exit(sl);
1456 
1457         /*
1458          * Wake up any threads we might have blocked.
1459          * Must precede kdoor_close etc. because those will
1460          * wait for such threads to get out.
1461          */
1462         smb_event_cancel(sv, 0);
1463         smb_threshold_wake_all(&sv->sv_ssetup_ct);
1464         smb_threshold_wake_all(&sv->sv_tcon_ct);
1465         smb_threshold_wake_all(&sv->sv_opipe_ct);
1466 
1467         /*
1468          * Wait for the session list to empty.
1469          * (cv_signal in smb_server_destroy_session)
1470          *
1471          * This should not take long, but if there are any leaked
1472          * references to ofiles, trees, or users, there could be a
1473          * session hanging around.  If that happens, the ll_count
1474          * never gets to zero and we'll never get the sv_signal.
1475          * Defend against that problem using timed wait, then
1476          * complain if we find sessions left over and continue
1477          * with shutdown in spite of any leaked sessions.
1478          * That's better than a server that won't reboot.
1479          */
1480         time = SEC_TO_TICK(10) + ddi_get_lbolt();
1481         mutex_enter(&sv->sv_mutex);
1482         while (sv->sv_session_list.ll_count != 0) {
1483                 if (cv_timedwait(&sv->sv_cv, &sv->sv_mutex, time) < 0)
1484                         break;
1485         }
1486         mutex_exit(&sv->sv_mutex);
1487 #ifdef  DEBUG
1488         if (sv->sv_session_list.ll_count != 0) {
1489                 cmn_err(CE_NOTE, "shutdown leaked sessions");
1490                 debug_enter("shutdown leaked sessions");
1491         }
1492 #endif
1493 
1494         /*
1495          * Clean out any durable handles.  After this we should
1496          * have no ofiles remaining (and no more oplock breaks).
1497          */
1498         smb2_dh_shutdown(sv);
1499 
1500         smb_kdoor_close(sv);
1501 #ifdef  _KERNEL
1502         smb_kshare_door_fini(sv->sv_lmshrd);
1503 #endif  /* _KERNEL */
1504         sv->sv_lmshrd = NULL;
1505 
1506         smb_export_stop(sv);
1507         smb_kshare_stop(sv);
1508 

1509         /*
1510          * Both kshare and the oplock break sub-systems may have
1511          * taskq jobs on the spcial "server" session, until we've
1512          * closed all ofiles and stopped the kshare exporter.
1513          * Now it's safe to destroy the server session, but first
1514          * wait for any requests on it to finish.  Note that for
1515          * normal sessions, this happens in smb_session_cancel,
1516          * but that's not called for the server session.
1517          */
1518         if (sv->sv_rootuser != NULL) {
1519                 smb_user_logoff(sv->sv_rootuser);
1520                 smb_user_release(sv->sv_rootuser);
1521                 sv->sv_rootuser = NULL;
1522         }
1523         if (sv->sv_session != NULL) {
1524                 smb_slist_wait_for_empty(&sv->sv_session->s_req_list);
1525 
1526                 /* Just in case import left users and trees */
1527                 smb_session_logoff(sv->sv_session);
1528 
1529                 smb_session_delete(sv->sv_session);
1530                 sv->sv_session = NULL;
1531         }
1532 
1533         if (sv->sv_receiver_pool != NULL) {
1534                 taskq_destroy(sv->sv_receiver_pool);
1535                 sv->sv_receiver_pool = NULL;
1536         }
1537 
1538         if (sv->sv_worker_pool != NULL) {
1539                 taskq_destroy(sv->sv_worker_pool);
1540                 sv->sv_worker_pool = NULL;
1541         }
1542 

1543         smb_server_fsop_stop(sv);
1544 }
1545 
1546 /*
1547  * smb_server_listener_init
1548  *
1549  * Initializes listener contexts.
1550  */
1551 static void
1552 smb_server_listener_init(
1553     smb_server_t                *sv,
1554     smb_listener_daemon_t       *ld,
1555     char                        *name,
1556     in_port_t                   port,
1557     int                         family)
1558 {
1559         ASSERT(ld->ld_magic != SMB_LISTENER_MAGIC);
1560 
1561         bzero(ld, sizeof (*ld));
1562 
1563         ld->ld_sv = sv;
1564         ld->ld_family = family;
1565         ld->ld_port = port;
1566 
1567         if (family == AF_INET) {
1568                 ld->ld_sin.sin_family = (uint32_t)family;
1569                 ld->ld_sin.sin_port = htons(port);
1570                 ld->ld_sin.sin_addr.s_addr = htonl(INADDR_ANY);
1571         } else {
1572                 ld->ld_sin6.sin6_family = (uint32_t)family;
1573                 ld->ld_sin6.sin6_port = htons(port);
1574                 (void) memset(&ld->ld_sin6.sin6_addr.s6_addr, 0,
1575                     sizeof (ld->ld_sin6.sin6_addr.s6_addr));
1576         }
1577 


1578         smb_thread_init(&ld->ld_thread, name, smb_server_listener, ld,
1579             smbsrv_listen_pri);
1580         ld->ld_magic = SMB_LISTENER_MAGIC;
1581 }
1582 
1583 /*
1584  * smb_server_listener_destroy
1585  *
1586  * Destroyes listener contexts.
1587  */
1588 static void
1589 smb_server_listener_destroy(smb_listener_daemon_t *ld)
1590 {
1591         /*
1592          * Note that if startup fails early, we can legitimately
1593          * get here with an all-zeros object.
1594          */
1595         if (ld->ld_magic == 0)
1596                 return;
1597 
1598         SMB_LISTENER_VALID(ld);
1599         ASSERT(ld->ld_so == NULL);
1600         smb_thread_destroy(&ld->ld_thread);

1601         ld->ld_magic = 0;
1602 }
1603 
1604 /*
1605  * smb_server_listener_start
1606  *
1607  * Starts the listener associated with the context passed in.
1608  *
1609  * Return:      0       Success
1610  *              not 0   Failure
1611  */
1612 static int
1613 smb_server_listener_start(smb_listener_daemon_t *ld)
1614 {
1615         int             rc;
1616         uint32_t        on;
1617         uint32_t        off;
1618 
1619         SMB_LISTENER_VALID(ld);
1620 


1678         SMB_LISTENER_VALID(ld);
1679 
1680         if (ld->ld_so != NULL) {
1681                 smb_soshutdown(ld->ld_so);
1682                 smb_sodestroy(ld->ld_so);
1683                 smb_thread_stop(&ld->ld_thread);
1684                 ld->ld_so = NULL;
1685         }
1686 }
1687 
1688 /*
1689  * smb_server_listener
1690  *
1691  * Entry point of the listeners.
1692  */
1693 static void
1694 smb_server_listener(smb_thread_t *thread, void *arg)
1695 {
1696         _NOTE(ARGUNUSED(thread))
1697         smb_listener_daemon_t   *ld;

1698         ksocket_t               s_so;
1699         int                     on;
1700         int                     txbuf_size;
1701 
1702         ld = (smb_listener_daemon_t *)arg;
1703 
1704         SMB_LISTENER_VALID(ld);
1705 
1706         DTRACE_PROBE1(so__wait__accept, struct sonode *, ld->ld_so);
1707 
1708         for (;;) {
1709                 int ret = ksocket_accept(ld->ld_so, NULL, NULL, &s_so, CRED());
1710 
1711                 switch (ret) {
1712                 case 0:
1713                         break;
1714                 case ECONNABORTED:
1715                         continue;
1716                 case EINTR:
1717                 case EBADF:     /* libfakekernel */
1718                         goto out;
1719                 default:
1720                         cmn_err(CE_WARN,
1721                             "smb_server_listener: ksocket_accept(%d)",
1722                             ret);
1723                         goto out;
1724                 }
1725 
1726                 DTRACE_PROBE1(so__accept, struct sonode *, s_so);
1727 
1728                 on = 1;
1729                 (void) ksocket_setsockopt(s_so, IPPROTO_TCP, TCP_NODELAY,
1730                     &on, sizeof (on), CRED());
1731 
1732                 on = 1;
1733                 (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_KEEPALIVE,
1734                     &on, sizeof (on), CRED());
1735 
1736                 txbuf_size = 128*1024;
1737                 (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_SNDBUF,
1738                     (const void *)&txbuf_size, sizeof (txbuf_size), CRED());
1739 
1740                 /*
1741                  * Create a session for this connection.
1742                  */
1743                 smb_server_create_session(ld, s_so);
1744         }
1745 out:







1746         ksocket_rele(ld->ld_so);
1747 }
1748 
1749 /*
1750  * smb_server_receiver
1751  *
1752  * Entry point of the receiver threads.
1753  * Also does cleanup when socket disconnected.
1754  */
1755 static void
1756 smb_server_receiver(void *arg)
1757 {

1758         smb_session_t   *session;
1759 
1760         session = (smb_session_t *)arg;
1761 
1762         /* We stay in here until socket disconnect. */
1763         smb_session_receiver(session);
1764 
1765         ASSERT(session->s_state == SMB_SESSION_STATE_SHUTDOWN);
1766         smb_server_destroy_session(session);
1767 }
1768 
1769 /*
1770  * smb_server_lookup
1771  *
1772  * This function finds the server associated with the zone of the
1773  * caller.  Note: requires a fix in the dynamic taskq code:
1774  * 1501 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0
1775  */
1776 int
1777 smb_server_lookup(smb_server_t **psv)
1778 {
1779         zoneid_t        zid;
1780         smb_server_t    *sv;
1781 
1782         zid = getzoneid();
1783 
1784         smb_llist_enter(&smb_servers, RW_READER);
1785         sv = smb_llist_head(&smb_servers);
1786         while (sv) {


1809  * This function decrements the reference count of the server and signals its
1810  * condition variable if the state of the server is SMB_SERVER_STATE_DELETING.
1811  */
1812 void
1813 smb_server_release(smb_server_t *sv)
1814 {
1815         SMB_SERVER_VALID(sv);
1816 
1817         mutex_enter(&sv->sv_mutex);
1818         ASSERT(sv->sv_refcnt);
1819         sv->sv_refcnt--;
1820         if ((sv->sv_refcnt == 0) && (sv->sv_state == SMB_SERVER_STATE_DELETING))
1821                 cv_signal(&sv->sv_cv);
1822         mutex_exit(&sv->sv_mutex);
1823 }
1824 
1825 /*
1826  * Enumerate the users associated with a session list.
1827  */
1828 static void
1829 smb_server_enum_users(smb_server_t *sv, smb_svcenum_t *svcenum)
1830 {
1831         smb_llist_t     *ll = &sv->sv_session_list;
1832         smb_session_t   *sn;
1833         smb_llist_t     *ulist;
1834         smb_user_t      *user;
1835         int             rc = 0;
1836 
1837         smb_llist_enter(ll, RW_READER);
1838         sn = smb_llist_head(ll);
1839 
1840         while (sn != NULL) {
1841                 SMB_SESSION_VALID(sn);
1842                 ulist = &sn->s_user_list;
1843                 smb_llist_enter(ulist, RW_READER);
1844                 user = smb_llist_head(ulist);
1845 
1846                 while (user != NULL) {
1847                         if (smb_user_hold(user)) {
1848                                 rc = smb_user_enum(user, svcenum);
1849                                 smb_user_release(user);
1850                                 if (rc != 0)
1851                                         break;
1852                         }
1853 
1854                         user = smb_llist_next(ulist, user);
1855                 }
1856 
1857                 smb_llist_exit(ulist);
1858 
1859                 if (rc != 0)
1860                         break;
1861 
1862                 sn = smb_llist_next(ll, sn);
1863         }
1864 
1865         smb_llist_exit(ll);
1866 }
1867 
1868 /*
1869  * Enumerate the trees/files associated with a session list.
1870  */
1871 static void
1872 smb_server_enum_trees(smb_server_t *sv, smb_svcenum_t *svcenum)
1873 {
1874         smb_llist_t     *ll = &sv->sv_session_list;
1875         smb_session_t   *sn;
1876         smb_llist_t     *tlist;
1877         smb_tree_t      *tree;
1878         int             rc = 0;
1879 
1880         smb_llist_enter(ll, RW_READER);
1881         sn = smb_llist_head(ll);
1882 
1883         while (sn != NULL) {
1884                 SMB_SESSION_VALID(sn);
1885                 tlist = &sn->s_tree_list;
1886                 smb_llist_enter(tlist, RW_READER);
1887                 tree = smb_llist_head(tlist);
1888 
1889                 while (tree != NULL) {
1890                         if (smb_tree_hold(tree)) {
1891                                 rc = smb_tree_enum(tree, svcenum);
1892                                 smb_tree_release(tree);
1893                                 if (rc != 0)
1894                                         break;


1896 
1897                         tree = smb_llist_next(tlist, tree);
1898                 }
1899 
1900                 smb_llist_exit(tlist);
1901 
1902                 if (rc != 0)
1903                         break;
1904 
1905                 sn = smb_llist_next(ll, sn);
1906         }
1907 
1908         smb_llist_exit(ll);
1909 }
1910 
1911 /*
1912  * Disconnect sessions associated with the specified client and username.
1913  * Empty strings are treated as wildcards.
1914  */
1915 static int
1916 smb_server_session_disconnect(smb_server_t *sv,
1917     const char *client, const char *name)
1918 {
1919         smb_llist_t     *ll = &sv->sv_session_list;
1920         smb_session_t   *sn;
1921         smb_llist_t     *ulist;
1922         smb_user_t      *user;

1923         int             count = 0;
1924 
1925         smb_llist_enter(ll, RW_READER);

1926 
1927         for (sn = smb_llist_head(ll);
1928             sn != NULL;
1929             sn = smb_llist_next(ll, sn)) {
1930                 SMB_SESSION_VALID(sn);
1931 
1932                 if (*client != '\0' && !smb_session_isclient(sn, client))

1933                         continue;

1934 
1935                 ulist = &sn->s_user_list;
1936                 smb_llist_enter(ulist, RW_READER);

1937 
1938                 for (user = smb_llist_head(ulist);
1939                     user != NULL;
1940                     user = smb_llist_next(ulist, user)) {
1941                         SMB_USER_VALID(user);

1942 
1943                         if (*name != '\0' && !smb_user_namecmp(user, name))






1944                                 continue;

1945 
1946                         if (smb_user_hold(user)) {
1947                                 smb_user_logoff(user);
1948                                 smb_user_release(user);
1949                                 count++;
1950                         }


1951                 }
1952 
1953                 smb_llist_exit(ulist);

1954         }
1955 
1956         smb_llist_exit(ll);
1957         return (count);
1958 }
1959 
1960 /*
1961  * Close a file by its unique id.
1962  */
1963 static int
1964 smb_server_fclose(smb_server_t *sv, uint32_t uniqid)
1965 {
1966         smb_llist_t     *ll;
1967         smb_session_t   *sn;
1968         smb_llist_t     *tlist;
1969         smb_tree_t      *tree;
1970         int             rc = ENOENT;
1971 
1972         ll = &sv->sv_session_list;
1973         smb_llist_enter(ll, RW_READER);
1974         sn = smb_llist_head(ll);
1975 
1976         while ((sn != NULL) && (rc == ENOENT)) {
1977                 SMB_SESSION_VALID(sn);
1978                 tlist = &sn->s_tree_list;
1979                 smb_llist_enter(tlist, RW_READER);
1980                 tree = smb_llist_head(tlist);
1981 
1982                 while ((tree != NULL) && (rc == ENOENT)) {
1983                         if (smb_tree_hold(tree)) {
1984                                 rc = smb_tree_fclose(tree, uniqid);
1985                                 smb_tree_release(tree);
1986                         }
1987 
1988                         tree = smb_llist_next(tlist, tree);
1989                 }
1990 
1991                 smb_llist_exit(tlist);
1992                 sn = smb_llist_next(ll, sn);
1993         }
1994 
1995         smb_llist_exit(ll);
1996         return (rc);
1997 }
1998 
1999 /*
2000  * This is used by SMB2 session setup to find a previous session,
2001  * so it can force a logoff that we haven't noticed yet.
2002  * This is not called frequently, so we just walk the list of
2003  * connections searching for the user.
2004  */
2005 smb_user_t *
2006 smb_server_lookup_ssnid(smb_server_t *sv, uint64_t ssnid)
2007 {
2008         smb_llist_t *sl;
2009         smb_session_t *sess;
2010         smb_user_t *user = NULL;
2011 
2012         sl = &sv->sv_session_list;
2013         smb_llist_enter(sl, RW_READER);
2014 
2015         for (sess = smb_llist_head(sl);
2016             sess != NULL;
2017             sess = smb_llist_next(sl, sess)) {
2018 
2019                 SMB_SESSION_VALID(sess);
2020 
2021                 if (sess->dialect < SMB_VERS_2_BASE)
2022                         continue;
2023 
2024                 /*
2025                  * Only look in sessions that are still active.
2026                  * Avoid doing an smb_rwx_rwenter sess->s_lock
2027                  * on every session here, but re-check below
2028                  * with s_lock held.
2029                  */
2030                 if (sess->s_state != SMB_SESSION_STATE_NEGOTIATED)
2031                         continue;
2032 
2033                 user = smb_session_lookup_ssnid(sess, ssnid);
2034                 if (user != NULL) {
2035                         break;
2036                 }
2037         }
2038 
2039         smb_llist_exit(sl);
2040 
2041         /* The sess check is warning avoidance. */
2042         if (user != NULL && sess != NULL) {
2043                 /*
2044                  * Re-check the state with s_lock held.
2045                  */
2046                 smb_rwx_rwenter(&sess->s_lock, RW_READER);
2047                 if (sess->s_state != SMB_SESSION_STATE_NEGOTIATED) {
2048                         smb_user_release(user);
2049                         user = NULL;
2050                 }
2051                 smb_rwx_rwexit(&sess->s_lock);
2052         }
2053 
2054         return (user);
2055 }
2056 
2057 /* See also: libsmb smb_kmod_setcfg */
2058 static void
2059 smb_server_store_cfg(smb_server_t *sv, smb_ioc_cfg_t *ioc)
2060 {
2061         if (ioc->maxconnections == 0)
2062                 ioc->maxconnections = 0xFFFFFFFF;
2063 
2064         if (ioc->encrypt == SMB_CONFIG_REQUIRED &&
2065             ioc->max_protocol < SMB_VERS_3_0) {
2066                 cmn_err(CE_WARN, "Server set to require encryption; "
2067                     "forcing max_protocol to 3.0");
2068                 ioc->max_protocol = SMB_VERS_3_0;
2069         }
2070 
2071         sv->sv_cfg.skc_maxworkers = ioc->maxworkers;
2072         sv->sv_cfg.skc_maxconnections = ioc->maxconnections;
2073         sv->sv_cfg.skc_keepalive = ioc->keepalive;
2074         sv->sv_cfg.skc_restrict_anon = ioc->restrict_anon;
2075         sv->sv_cfg.skc_signing_enable = ioc->signing_enable;
2076         sv->sv_cfg.skc_signing_required = ioc->signing_required;
2077         sv->sv_cfg.skc_oplock_enable = ioc->oplock_enable;
2078         sv->sv_cfg.skc_sync_enable = ioc->sync_enable;
2079         sv->sv_cfg.skc_secmode = ioc->secmode;
2080         sv->sv_cfg.skc_netbios_enable = ioc->netbios_enable;
2081         sv->sv_cfg.skc_ipv6_enable = ioc->ipv6_enable;
2082         sv->sv_cfg.skc_print_enable = ioc->print_enable;
2083         sv->sv_cfg.skc_traverse_mounts = ioc->traverse_mounts;
2084         sv->sv_cfg.skc_max_protocol = ioc->max_protocol;
2085         sv->sv_cfg.skc_min_protocol = ioc->min_protocol;
2086         sv->sv_cfg.skc_encrypt = ioc->encrypt;
2087         sv->sv_cfg.skc_execflags = ioc->exec_flags;
2088         sv->sv_cfg.skc_negtok_len = ioc->negtok_len;
2089         sv->sv_cfg.skc_version = ioc->version;
2090         sv->sv_cfg.skc_initial_credits = ioc->initial_credits;
2091         sv->sv_cfg.skc_maximum_credits = ioc->maximum_credits;
2092 
2093         (void) memcpy(sv->sv_cfg.skc_machine_uuid, ioc->machine_uuid,
2094             sizeof (uuid_t));
2095         (void) memcpy(sv->sv_cfg.skc_negtok, ioc->negtok,
2096             sizeof (sv->sv_cfg.skc_negtok));
2097         (void) memcpy(sv->sv_cfg.skc_native_os, ioc->native_os,
2098             sizeof (sv->sv_cfg.skc_native_os));
2099         (void) memcpy(sv->sv_cfg.skc_native_lm, ioc->native_lm,
2100             sizeof (sv->sv_cfg.skc_native_lm));
2101 
2102         (void) strlcpy(sv->sv_cfg.skc_nbdomain, ioc->nbdomain,
2103             sizeof (sv->sv_cfg.skc_nbdomain));
2104         (void) strlcpy(sv->sv_cfg.skc_fqdn, ioc->fqdn,
2105             sizeof (sv->sv_cfg.skc_fqdn));
2106         (void) strlcpy(sv->sv_cfg.skc_hostname, ioc->hostname,


2450         smb_llist_t     *splist;
2451         smb_server_t    *sv = tree->t_server;
2452         int rc = 0;
2453 
2454         splist = &sv->sp_info.sp_list;
2455         smb_llist_enter(splist, RW_WRITER);
2456         sp->sd_spool_num = atomic_inc_32_nv(&sv->sp_info.sp_cnt);
2457         smb_llist_insert_tail(splist, sp);
2458         smb_llist_exit(splist);
2459 
2460         return (rc);
2461 }
2462 
2463 /*
2464  * smb_server_create_session
2465  */
2466 static void
2467 smb_server_create_session(smb_listener_daemon_t *ld, ksocket_t s_so)
2468 {
2469         smb_session_t           *session;

2470         taskqid_t               tqid;
2471         smb_llist_t             *sl;
2472         smb_server_t            *sv = ld->ld_sv;
2473 
2474         session = smb_session_create(s_so, ld->ld_port, sv,
2475             ld->ld_family);
2476 
2477         if (session == NULL) {
2478                 smb_soshutdown(s_so);
2479                 smb_sodestroy(s_so);
2480                 cmn_err(CE_WARN, "SMB Session: alloc failed");
2481                 return;
2482         }
2483 
2484         sl = &sv->sv_session_list;
2485         smb_llist_enter(sl, RW_WRITER);
2486         smb_llist_insert_tail(sl, session);
2487         smb_llist_exit(sl);
2488 





2489         /*
2490          * These taskq entries must run independently of one another,
2491          * so TQ_NOQUEUE.  TQ_SLEEP (==0) just for clarity.
2492          */
2493         tqid = taskq_dispatch(sv->sv_receiver_pool,
2494             smb_server_receiver, session, TQ_NOQUEUE | TQ_SLEEP);
2495         if (tqid == 0) {

2496                 smb_session_disconnect(session);
2497                 smb_server_destroy_session(session);
2498                 cmn_err(CE_WARN, "SMB Session: taskq_dispatch failed");
2499                 return;
2500         }
2501         /* handy for debugging */
2502         session->s_receiver_tqid = tqid;
2503 }
2504 
2505 static void
2506 smb_server_destroy_session(smb_session_t *session)
2507 {
2508         smb_server_t *sv;
2509         smb_llist_t *ll;
2510         uint32_t count;
2511 
2512         ASSERT(session->s_server != NULL);
2513         sv = session->s_server;
2514         ll = &sv->sv_session_list;
2515 
2516         smb_llist_flush(&session->s_tree_list);
2517         smb_llist_flush(&session->s_user_list);
2518 
2519         /*
2520          * The user and tree lists should be empty now.
2521          */
2522 #ifdef DEBUG
2523         if (session->s_user_list.ll_count != 0) {
2524                 cmn_err(CE_WARN, "user list not empty?");
2525                 debug_enter("s_user_list");
2526         }
2527         if (session->s_tree_list.ll_count != 0) {
2528                 cmn_err(CE_WARN, "tree list not empty?");
2529                 debug_enter("s_tree_list");
2530         }
2531 #endif
2532 
2533         smb_llist_enter(ll, RW_WRITER);
2534         smb_llist_remove(ll, session);
2535         count = ll->ll_count;
2536         smb_llist_exit(ll);
2537 
2538         smb_session_delete(session);
2539         if (count == 0) {
2540                 /* See smb_server_shutdown */
2541                 cv_signal(&sv->sv_cv);
2542         }
2543 }