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

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/smbsrv/smb_server.c
          +++ new/usr/src/uts/common/fs/smbsrv/smb_server.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  23      - * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  24   23   * Copyright (c) 2017 by Delphix. All rights reserved.
       24 + * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  25   25   */
  26   26  
  27   27  /*
  28   28   * General Structures Layout
  29   29   * -------------------------
  30   30   *
  31   31   * This is a simplified diagram showing the relationship between most of the
  32   32   * main structures.
  33   33   *
  34   34   * +-------------------+
↓ open down ↓ 177 lines elided ↑ open up ↑
 212  212  #include <netinet/ip_var.h>
 213  213  #include <netinet/tcp.h>
 214  214  #include <smbsrv/smb2_kproto.h>
 215  215  #include <smbsrv/string.h>
 216  216  #include <smbsrv/netbios.h>
 217  217  #include <smbsrv/smb_fsops.h>
 218  218  #include <smbsrv/smb_share.h>
 219  219  #include <smbsrv/smb_door.h>
 220  220  #include <smbsrv/smb_kstat.h>
 221  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  222  static void smb_server_kstat_init(smb_server_t *);
 230  223  static void smb_server_kstat_fini(smb_server_t *);
 231  224  static void smb_server_timers(smb_thread_t *, void *);
 232  225  static void smb_server_store_cfg(smb_server_t *, smb_ioc_cfg_t *);
 233  226  static void smb_server_shutdown(smb_server_t *);
 234  227  static int smb_server_fsop_start(smb_server_t *);
 235  228  static void smb_server_fsop_stop(smb_server_t *);
 236  229  static void smb_event_cancel(smb_server_t *, uint32_t);
 237  230  static uint32_t smb_event_alloc_txid(void);
 238  231  
 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 *,
      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 *,
 243  236      const char *);
 244      -static int smb_server_fclose(smb_llist_t *, uint32_t);
      237 +static int smb_server_fclose(smb_server_t *, uint32_t);
 245  238  static int smb_server_kstat_update(kstat_t *, int);
 246  239  static int smb_server_legacy_kstat_update(kstat_t *, int);
 247  240  static void smb_server_listener_init(smb_server_t *, smb_listener_daemon_t *,
 248  241      char *, in_port_t, int);
 249  242  static void smb_server_listener_destroy(smb_listener_daemon_t *);
 250  243  static int smb_server_listener_start(smb_listener_daemon_t *);
 251  244  static void smb_server_listener_stop(smb_listener_daemon_t *);
 252  245  static void smb_server_listener(smb_thread_t *, void *);
 253  246  static void smb_server_receiver(void *);
 254  247  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 *);
      248 +static void smb_server_destroy_session(smb_session_t *);
 257  249  static uint16_t smb_spool_get_fid(smb_server_t *);
 258  250  static boolean_t smb_spool_lookup_doc_byfid(smb_server_t *, uint16_t,
 259  251      smb_kspooldoc_t *);
 260  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 +
 261  267  int smb_event_debug = 0;
 262  268  
 263  269  static smb_llist_t      smb_servers;
 264  270  
 265  271  kmem_cache_t            *smb_cache_request;
 266  272  kmem_cache_t            *smb_cache_session;
 267  273  kmem_cache_t            *smb_cache_user;
 268  274  kmem_cache_t            *smb_cache_tree;
 269  275  kmem_cache_t            *smb_cache_ofile;
 270  276  kmem_cache_t            *smb_cache_odir;
 271  277  kmem_cache_t            *smb_cache_opipe;
 272  278  kmem_cache_t            *smb_cache_event;
      279 +kmem_cache_t            *smb_cache_lock;
 273  280  
 274  281  /*
 275  282   * *****************************************************************************
 276  283   * **************** Functions called from the device interface *****************
 277  284   * *****************************************************************************
 278  285   *
 279  286   * These functions typically have to determine the relevant smb server
 280  287   * to which the call applies.
 281  288   */
 282  289  
↓ open down ↓ 18 lines elided ↑ open up ↑
 301  308  
 302  309          if ((rc = smb_vop_init()) != 0)
 303  310                  goto errout;
 304  311          if ((rc = smb_fem_init()) != 0)
 305  312                  goto errout;
 306  313  
 307  314          smb_kshare_g_init();
 308  315          smb_codepage_init();
 309  316          smb_mbc_init();         /* smb_mbc_cache */
 310  317          smb_node_init();        /* smb_node_cache, lists */
      318 +        smb2_lease_init();
 311  319  
 312  320          smb_cache_request = kmem_cache_create("smb_request_cache",
 313  321              sizeof (smb_request_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 314  322          smb_cache_session = kmem_cache_create("smb_session_cache",
 315  323              sizeof (smb_session_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 316  324          smb_cache_user = kmem_cache_create("smb_user_cache",
 317  325              sizeof (smb_user_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 318  326          smb_cache_tree = kmem_cache_create("smb_tree_cache",
 319  327              sizeof (smb_tree_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 320  328          smb_cache_ofile = kmem_cache_create("smb_ofile_cache",
 321  329              sizeof (smb_ofile_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 322  330          smb_cache_odir = kmem_cache_create("smb_odir_cache",
 323  331              sizeof (smb_odir_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 324  332          smb_cache_opipe = kmem_cache_create("smb_opipe_cache",
 325  333              sizeof (smb_opipe_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
 326  334          smb_cache_event = kmem_cache_create("smb_event_cache",
 327  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);
 328  338  
 329  339          smb_llist_init();
 330  340          smb_llist_constructor(&smb_servers, sizeof (smb_server_t),
 331  341              offsetof(smb_server_t, sv_lnd));
 332  342  
 333  343          return (0);
 334  344  
 335  345  errout:
 336  346          smb_fem_fini();
 337  347          smb_vop_fini();
↓ open down ↓ 15 lines elided ↑ open up ↑
 353  363          smb_llist_fini();
 354  364  
 355  365          kmem_cache_destroy(smb_cache_request);
 356  366          kmem_cache_destroy(smb_cache_session);
 357  367          kmem_cache_destroy(smb_cache_user);
 358  368          kmem_cache_destroy(smb_cache_tree);
 359  369          kmem_cache_destroy(smb_cache_ofile);
 360  370          kmem_cache_destroy(smb_cache_odir);
 361  371          kmem_cache_destroy(smb_cache_opipe);
 362  372          kmem_cache_destroy(smb_cache_event);
      373 +        kmem_cache_destroy(smb_cache_lock);
 363  374  
      375 +        smb2_lease_fini();
 364  376          smb_node_fini();
 365  377          smb_mbc_fini();
 366  378          smb_codepage_fini();
 367  379          smb_kshare_g_fini();
 368  380  
 369  381          smb_fem_fini();
 370  382          smb_vop_fini();
 371  383  
 372  384          smb_llist_destructor(&smb_servers);
 373  385  }
↓ open down ↓ 27 lines elided ↑ open up ↑
 401  413  
 402  414          sv->sv_magic = SMB_SERVER_MAGIC;
 403  415          sv->sv_state = SMB_SERVER_STATE_CREATED;
 404  416          sv->sv_zid = zid;
 405  417          sv->sv_pid = ddi_get_pid();
 406  418  
 407  419          mutex_init(&sv->sv_mutex, NULL, MUTEX_DEFAULT, NULL);
 408  420          cv_init(&sv->sv_cv, NULL, CV_DEFAULT, NULL);
 409  421          cv_init(&sv->sp_info.sp_cv, NULL, CV_DEFAULT, NULL);
 410  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 +
 411  432          smb_llist_constructor(&sv->sv_event_list, sizeof (smb_event_t),
 412  433              offsetof(smb_event_t, se_lnd));
 413  434  
 414  435          smb_llist_constructor(&sv->sp_info.sp_list, sizeof (smb_kspooldoc_t),
 415  436              offsetof(smb_kspooldoc_t, sd_lnd));
 416  437  
 417  438          smb_llist_constructor(&sv->sp_info.sp_fidlist,
 418  439              sizeof (smb_spoolfid_t), offsetof(smb_spoolfid_t, sf_lnd));
 419  440  
 420  441          sv->sv_disp_stats1 = kmem_zalloc(SMB_COM_NUM *
↓ open down ↓ 24 lines elided ↑ open up ↑
 445  466          return (0);
 446  467  }
 447  468  
 448  469  /*
 449  470   * smb_server_delete
 450  471   *
 451  472   * This function will delete the server passed in. It will make sure that all
 452  473   * activity associated that server has ceased before destroying it.
 453  474   */
 454  475  int
 455      -smb_server_delete(void)
      476 +smb_server_delete(smb_server_t  *sv)
 456  477  {
 457      -        smb_server_t    *sv;
 458      -        int             rc;
 459  478  
 460      -        rc = smb_server_lookup(&sv);
 461      -        if (rc != 0)
 462      -                return (rc);
 463      -
 464  479          mutex_enter(&sv->sv_mutex);
 465  480          switch (sv->sv_state) {
 466  481          case SMB_SERVER_STATE_RUNNING:
 467  482                  sv->sv_state = SMB_SERVER_STATE_STOPPING;
 468  483                  mutex_exit(&sv->sv_mutex);
 469  484                  smb_server_shutdown(sv);
 470  485                  mutex_enter(&sv->sv_mutex);
 471  486                  cv_broadcast(&sv->sp_info.sp_cv);
 472  487                  sv->sv_state = SMB_SERVER_STATE_DELETING;
 473  488                  break;
↓ open down ↓ 27 lines elided ↑ open up ↑
 501  516          smb_threshold_fini(&sv->sv_tcon_ct);
 502  517          smb_threshold_fini(&sv->sv_opipe_ct);
 503  518  
 504  519          smb_server_listener_destroy(&sv->sv_nbt_daemon);
 505  520          smb_server_listener_destroy(&sv->sv_tcp_daemon);
 506  521          rw_destroy(&sv->sv_cfg_lock);
 507  522          smb_server_kstat_fini(sv);
 508  523          smb_kshare_fini(sv);
 509  524          smb_kdoor_fini(sv);
 510  525          smb_llist_destructor(&sv->sv_event_list);
      526 +        smb_llist_destructor(&sv->sv_session_list);
 511  527  
 512  528          kmem_free(sv->sv_disp_stats1,
 513  529              SMB_COM_NUM * sizeof (smb_disp_stats_t));
 514  530  
 515  531          kmem_free(sv->sv_disp_stats2,
 516  532              SMB2__NCMDS * sizeof (smb_disp_stats_t));
 517  533  
 518  534          smb_srqueue_destroy(&sv->sv_srqueue);
 519  535          smb_thread_destroy(&sv->si_thread_timers);
 520  536  
 521  537          mutex_destroy(&sv->sv_mutex);
      538 +        smb_hash_destroy(sv->sv_lease_ht);
      539 +        smb_hash_destroy(sv->sv_persistid_ht);
 522  540          cv_destroy(&sv->sv_cv);
 523  541          sv->sv_magic = 0;
 524  542          kmem_free(sv, sizeof (smb_server_t));
 525  543  
 526  544          return (0);
 527  545  }
 528  546  
 529  547  /*
 530  548   * smb_server_configure
 531  549   */
↓ open down ↓ 45 lines elided ↑ open up ↑
 577  595  
 578  596  /*
 579  597   * smb_server_start
 580  598   */
 581  599  int
 582  600  smb_server_start(smb_ioc_start_t *ioc)
 583  601  {
 584  602          int             rc = 0;
 585  603          int             family;
 586  604          smb_server_t    *sv;
      605 +        cred_t          *ucr;
 587  606  
 588  607          rc = smb_server_lookup(&sv);
 589  608          if (rc)
 590  609                  return (rc);
 591  610  
 592  611          mutex_enter(&sv->sv_mutex);
 593  612          switch (sv->sv_state) {
 594  613          case SMB_SERVER_STATE_CONFIGURED:
 595  614  
 596  615                  if ((rc = smb_server_fsop_start(sv)) != 0)
 597  616                          break;
 598  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 +
 599  643                  if ((rc = smb_kshare_start(sv)) != 0)
 600  644                          break;
 601  645  
 602  646                  /*
 603  647                   * NB: the proc passed here has to be a "system" one.
 604  648                   * Normally that's p0, or the NGZ eqivalent.
 605  649                   */
 606  650                  sv->sv_worker_pool = taskq_create_proc("smb_workers",
 607  651                      sv->sv_cfg.skc_maxworkers, smbsrv_worker_pri,
 608  652                      sv->sv_cfg.skc_maxworkers, INT_MAX,
 609  653                      curzone->zone_zsched, TASKQ_DYNAMIC);
 610  654  
 611  655                  sv->sv_receiver_pool = taskq_create_proc("smb_receivers",
 612  656                      sv->sv_cfg.skc_maxconnections, smbsrv_receive_pri,
 613  657                      sv->sv_cfg.skc_maxconnections, INT_MAX,
 614  658                      curzone->zone_zsched, TASKQ_DYNAMIC);
 615  659  
 616      -                sv->sv_session = smb_session_create(NULL, 0, sv, 0);
 617      -
 618      -                if (sv->sv_worker_pool == NULL || sv->sv_session == NULL) {
      660 +                if (sv->sv_worker_pool == NULL ||
      661 +                    sv->sv_receiver_pool == NULL) {
 619  662                          rc = ENOMEM;
 620  663                          break;
 621  664                  }
 622  665  
 623  666  #ifdef  _KERNEL
 624  667                  ASSERT(sv->sv_lmshrd == NULL);
 625  668                  sv->sv_lmshrd = smb_kshare_door_init(ioc->lmshrd);
 626  669                  if (sv->sv_lmshrd == NULL)
 627  670                          break;
 628      -                if (rc = smb_kdoor_open(sv, ioc->udoor)) {
      671 +                if ((rc = smb_kdoor_open(sv, ioc->udoor)) != 0) {
 629  672                          cmn_err(CE_WARN, "Cannot open smbd door");
 630  673                          break;
 631  674                  }
 632  675  #else   /* _KERNEL */
 633  676                  /* Fake kernel does not use the kshare_door */
 634  677                  fksmb_kdoor_open(sv, ioc->udoor_func);
 635  678  #endif  /* _KERNEL */
 636  679  
 637      -                if (rc = smb_thread_start(&sv->si_thread_timers))
      680 +                if ((rc = smb_thread_start(&sv->si_thread_timers)) != 0)
 638  681                          break;
 639  682  
 640  683                  family = AF_INET;
 641  684                  smb_server_listener_init(sv, &sv->sv_nbt_daemon,
 642  685                      "smb_nbt_listener", IPPORT_NETBIOS_SSN, family);
 643  686                  if (sv->sv_cfg.skc_ipv6_enable)
 644  687                          family = AF_INET6;
 645  688                  smb_server_listener_init(sv, &sv->sv_tcp_daemon,
 646  689                      "smb_tcp_listener", IPPORT_SMB, family);
 647  690                  rc = smb_server_listener_start(&sv->sv_tcp_daemon);
↓ open down ↓ 209 lines elided ↑ open up ↑
 857  900  
 858  901          if ((rc = smb_server_lookup(&sv)) != 0)
 859  902                  return (rc);
 860  903  
 861  904          svcenum->se_bavail = svcenum->se_buflen;
 862  905          svcenum->se_bused = 0;
 863  906          svcenum->se_nitems = 0;
 864  907  
 865  908          switch (svcenum->se_type) {
 866  909          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);
      910 +                smb_server_enum_users(sv, svcenum);
 871  911                  break;
 872  912          case SMB_SVCENUM_TYPE_TREE:
 873  913          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);
      914 +                smb_server_enum_trees(sv, svcenum);
 878  915                  break;
 879  916          default:
 880  917                  rc = EINVAL;
 881  918          }
 882  919  
 883  920          smb_server_release(sv);
 884  921          return (rc);
 885  922  }
 886  923  
 887  924  /*
 888  925   * Look for sessions to disconnect by client and user name.
 889  926   */
 890  927  int
 891  928  smb_server_session_close(smb_ioc_session_t *ioc)
 892  929  {
 893      -        smb_llist_t     *ll;
 894  930          smb_server_t    *sv;
 895      -        int             nbt_cnt;
 896      -        int             tcp_cnt;
      931 +        int             cnt;
 897  932          int             rc;
 898  933  
 899  934          if ((rc = smb_server_lookup(&sv)) != 0)
 900  935                  return (rc);
 901  936  
 902      -        ll = &sv->sv_nbt_daemon.ld_session_list;
 903      -        nbt_cnt = smb_server_session_disconnect(ll, ioc->client, ioc->username);
      937 +        cnt = smb_server_session_disconnect(sv, ioc->client, ioc->username);
 904  938  
 905      -        ll = &sv->sv_tcp_daemon.ld_session_list;
 906      -        tcp_cnt = smb_server_session_disconnect(ll, ioc->client, ioc->username);
 907      -
 908  939          smb_server_release(sv);
 909  940  
 910      -        if ((nbt_cnt == 0) && (tcp_cnt == 0))
      941 +        if (cnt == 0)
 911  942                  return (ENOENT);
 912  943          return (0);
 913  944  }
 914  945  
 915  946  /*
 916  947   * Close a file by uniqid.
 917  948   */
 918  949  int
 919  950  smb_server_file_close(smb_ioc_fileid_t *ioc)
 920  951  {
 921  952          uint32_t        uniqid = ioc->uniqid;
 922      -        smb_llist_t     *ll;
 923  953          smb_server_t    *sv;
 924  954          int             rc;
 925  955  
 926  956          if ((rc = smb_server_lookup(&sv)) != 0)
 927  957                  return (rc);
 928  958  
 929      -        ll = &sv->sv_nbt_daemon.ld_session_list;
 930      -        rc = smb_server_fclose(ll, uniqid);
      959 +        rc = smb_server_fclose(sv, uniqid);
 931  960  
 932      -        if (rc == ENOENT) {
 933      -                ll = &sv->sv_tcp_daemon.ld_session_list;
 934      -                rc = smb_server_fclose(ll, uniqid);
 935      -        }
 936      -
 937  961          smb_server_release(sv);
 938  962          return (rc);
 939  963  }
 940  964  
 941  965  /*
 942  966   * These functions determine the relevant smb server to which the call apply.
 943  967   */
 944  968  
 945  969  uint32_t
 946  970  smb_server_get_session_count(smb_server_t *sv)
 947  971  {
 948  972          uint32_t        counter = 0;
 949  973  
 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);
      974 +        counter = smb_llist_get_count(&sv->sv_session_list);
 952  975  
 953  976          return (counter);
 954  977  }
 955  978  
 956  979  /*
 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.
      980 + * Gets the smb_node of the specified share path.
      981 + * Node is returned held (caller must rele.)
 961  982   */
 962  983  int
 963      -smb_server_sharevp(smb_server_t *sv, const char *shr_path, vnode_t **vp)
      984 +smb_server_share_lookup(smb_server_t *sv, const char *shr_path,
      985 +    smb_node_t **nodepp)
 964  986  {
 965  987          smb_request_t   *sr;
 966  988          smb_node_t      *fnode = NULL;
 967      -        smb_node_t      *dnode;
      989 +        smb_node_t      *dnode = NULL;
 968  990          char            last_comp[MAXNAMELEN];
 969  991          int             rc = 0;
 970  992  
 971  993          ASSERT(shr_path);
 972  994  
 973  995          mutex_enter(&sv->sv_mutex);
 974  996          switch (sv->sv_state) {
 975  997          case SMB_SERVER_STATE_RUNNING:
 976  998                  break;
 977  999          default:
 978 1000                  mutex_exit(&sv->sv_mutex);
 979 1001                  return (ENOTACTIVE);
 980 1002          }
 981 1003          mutex_exit(&sv->sv_mutex);
 982 1004  
 983 1005          if ((sr = smb_request_alloc(sv->sv_session, 0)) == NULL) {
 984      -                return (ENOMEM);
     1006 +                return (ENOTCONN);
 985 1007          }
 986 1008          sr->user_cr = zone_kcred();
 987 1009  
 988 1010          rc = smb_pathname_reduce(sr, sr->user_cr, shr_path,
 989 1011              NULL, NULL, &dnode, last_comp);
 990 1012  
 991 1013          if (rc == 0) {
 992 1014                  rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
 993 1015                      sv->si_root_smb_node, dnode, last_comp, &fnode);
 994 1016                  smb_node_release(dnode);
 995 1017          }
 996 1018  
 997 1019          smb_request_free(sr);
 998 1020  
 999 1021          if (rc != 0)
1000 1022                  return (rc);
1001 1023  
1002 1024          ASSERT(fnode->vp && fnode->vp->v_vfsp);
1003 1025  
1004      -        VN_HOLD(fnode->vp);
1005      -        *vp = fnode->vp;
     1026 +        *nodepp = fnode;
1006 1027  
1007      -        smb_node_release(fnode);
1008      -
1009 1028          return (0);
1010 1029  }
1011 1030  
1012 1031  #ifdef  _KERNEL
1013 1032  /*
1014 1033   * This is a special interface that will be utilized by ZFS to cause a share to
1015 1034   * be added/removed.
1016 1035   *
1017 1036   * arg is either a lmshare_info_t or share_name from userspace.
1018 1037   * It will need to be copied into the kernel.   It is lmshare_info_t
↓ open down ↓ 20 lines elided ↑ open up ↑
1039 1058          }
1040 1059  
1041 1060          return (rc);
1042 1061  }
1043 1062  #endif  /* _KERNEL */
1044 1063  
1045 1064  int
1046 1065  smb_server_unshare(const char *sharename)
1047 1066  {
1048 1067          smb_server_t    *sv;
1049      -        smb_llist_t     *ll;
1050 1068          int             rc;
1051 1069  
1052 1070          if ((rc = smb_server_lookup(&sv)))
1053 1071                  return (rc);
1054 1072  
1055 1073          mutex_enter(&sv->sv_mutex);
1056 1074          switch (sv->sv_state) {
1057 1075          case SMB_SERVER_STATE_RUNNING:
1058 1076          case SMB_SERVER_STATE_STOPPING:
1059 1077                  break;
1060 1078          default:
1061 1079                  mutex_exit(&sv->sv_mutex);
1062 1080                  smb_server_release(sv);
1063 1081                  return (ENOTACTIVE);
1064 1082          }
1065 1083          mutex_exit(&sv->sv_mutex);
1066 1084  
1067      -        ll = &sv->sv_nbt_daemon.ld_session_list;
1068      -        smb_server_disconnect_share(ll, sharename);
     1085 +        smb_server_disconnect_share(sv, sharename);
1069 1086  
1070      -        ll = &sv->sv_tcp_daemon.ld_session_list;
1071      -        smb_server_disconnect_share(ll, sharename);
1072      -
1073 1087          smb_server_release(sv);
1074 1088          return (0);
1075 1089  }
1076 1090  
1077 1091  /*
1078 1092   * Disconnect the specified share.
1079 1093   * Typically called when a share has been removed.
1080 1094   */
1081 1095  static void
1082      -smb_server_disconnect_share(smb_llist_t *ll, const char *sharename)
     1096 +smb_server_disconnect_share(smb_server_t *sv, const char *sharename)
1083 1097  {
     1098 +        smb_llist_t     *ll;
1084 1099          smb_session_t   *session;
1085 1100  
     1101 +        ll = &sv->sv_session_list;
1086 1102          smb_llist_enter(ll, RW_READER);
1087 1103  
1088 1104          session = smb_llist_head(ll);
1089 1105          while (session) {
1090 1106                  SMB_SESSION_VALID(session);
1091 1107                  smb_rwx_rwenter(&session->s_lock, RW_READER);
1092 1108                  switch (session->s_state) {
1093 1109                  case SMB_SESSION_STATE_NEGOTIATED:
     1110 +                        smb_rwx_rwexit(&session->s_lock);
1094 1111                          smb_session_disconnect_share(session, sharename);
1095 1112                          break;
1096 1113                  default:
     1114 +                        smb_rwx_rwexit(&session->s_lock);
1097 1115                          break;
1098 1116                  }
1099      -                smb_rwx_rwexit(&session->s_lock);
1100 1117                  session = smb_llist_next(ll, session);
1101 1118          }
1102 1119  
1103 1120          smb_llist_exit(ll);
1104 1121  }
1105 1122  
1106 1123  /*
1107 1124   * *****************************************************************************
1108 1125   * **************** Functions called from the internal layers ******************
1109 1126   * *****************************************************************************
↓ open down ↓ 124 lines elided ↑ open up ↑
1234 1251   */
1235 1252  
1236 1253  static void
1237 1254  smb_server_timers(smb_thread_t *thread, void *arg)
1238 1255  {
1239 1256          smb_server_t    *sv = (smb_server_t *)arg;
1240 1257  
1241 1258          ASSERT(sv != NULL);
1242 1259  
1243 1260          /*
1244      -         * This just kills old inactive sessions.  No urgency.
1245      -         * The session code expects one call per minute.
     1261 +         * This kills old inactive sessions and expired durable
     1262 +         * handles. The session code expects one call per minute.
1246 1263           */
1247 1264          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);
     1265 +                if (sv->sv_cfg.skc_keepalive != 0)
     1266 +                        smb_session_timers(sv);
     1267 +                smb2_durable_timers(sv);
1250 1268          }
1251 1269  }
1252 1270  
1253 1271  /*
1254 1272   * smb_server_kstat_init
1255 1273   */
1256 1274  static void
1257 1275  smb_server_kstat_init(smb_server_t *sv)
1258 1276  {
1259 1277  
↓ open down ↓ 56 lines elided ↑ open up ↑
1316 1334  
1317 1335          if (sv->sv_ksp != NULL) {
1318 1336                  kstat_delete(sv->sv_ksp);
1319 1337                  sv->sv_ksp = NULL;
1320 1338                  smb_dispatch_stats_fini(sv);
1321 1339                  smb2_dispatch_stats_fini(sv);
1322 1340          }
1323 1341  }
1324 1342  
1325 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 +/*
1326 1350   * smb_server_kstat_update
1327 1351   */
1328 1352  static int
1329 1353  smb_server_kstat_update(kstat_t *ksp, int rw)
1330 1354  {
1331 1355          smb_server_t    *sv;
1332 1356          smbsrv_kstats_t *ksd;
1333 1357  
1334 1358          if (rw == KSTAT_READ) {
1335 1359                  sv = ksp->ks_private;
↓ open down ↓ 64 lines elided ↑ open up ↑
1400 1424          return (rc);
1401 1425  
1402 1426  }
1403 1427  
1404 1428  /*
1405 1429   * smb_server_shutdown
1406 1430   */
1407 1431  static void
1408 1432  smb_server_shutdown(smb_server_t *sv)
1409 1433  {
     1434 +        smb_llist_t *sl = &sv->sv_session_list;
     1435 +        smb_session_t *session;
     1436 +        clock_t time;
     1437 +
1410 1438          SMB_SERVER_VALID(sv);
1411 1439  
1412 1440          /*
1413 1441           * Stop the listeners first, so we don't get any more
1414 1442           * new work while we're trying to shut down.
1415 1443           */
1416 1444          smb_server_listener_stop(&sv->sv_nbt_daemon);
1417 1445          smb_server_listener_stop(&sv->sv_tcp_daemon);
1418 1446          smb_thread_stop(&sv->si_thread_timers);
1419 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 +
1420 1457          /*
1421 1458           * Wake up any threads we might have blocked.
1422 1459           * Must precede kdoor_close etc. because those will
1423 1460           * wait for such threads to get out.
1424 1461           */
1425 1462          smb_event_cancel(sv, 0);
1426 1463          smb_threshold_wake_all(&sv->sv_ssetup_ct);
1427 1464          smb_threshold_wake_all(&sv->sv_tcon_ct);
1428 1465          smb_threshold_wake_all(&sv->sv_opipe_ct);
1429 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 +
1430 1500          smb_kdoor_close(sv);
1431 1501  #ifdef  _KERNEL
1432 1502          smb_kshare_door_fini(sv->sv_lmshrd);
1433 1503  #endif  /* _KERNEL */
1434 1504          sv->sv_lmshrd = NULL;
1435 1505  
1436 1506          smb_export_stop(sv);
     1507 +        smb_kshare_stop(sv);
1437 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 +        }
1438 1523          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 1524                  smb_slist_wait_for_empty(&sv->sv_session->s_req_list);
1446 1525  
     1526 +                /* Just in case import left users and trees */
     1527 +                smb_session_logoff(sv->sv_session);
     1528 +
1447 1529                  smb_session_delete(sv->sv_session);
1448 1530                  sv->sv_session = NULL;
1449 1531          }
1450 1532  
1451 1533          if (sv->sv_receiver_pool != NULL) {
1452 1534                  taskq_destroy(sv->sv_receiver_pool);
1453 1535                  sv->sv_receiver_pool = NULL;
1454 1536          }
1455 1537  
1456 1538          if (sv->sv_worker_pool != NULL) {
1457 1539                  taskq_destroy(sv->sv_worker_pool);
1458 1540                  sv->sv_worker_pool = NULL;
1459 1541          }
1460 1542  
1461      -        smb_kshare_stop(sv);
1462 1543          smb_server_fsop_stop(sv);
1463 1544  }
1464 1545  
1465 1546  /*
1466 1547   * smb_server_listener_init
1467 1548   *
1468 1549   * Initializes listener contexts.
1469 1550   */
1470 1551  static void
1471 1552  smb_server_listener_init(
↓ open down ↓ 15 lines elided ↑ open up ↑
1487 1568                  ld->ld_sin.sin_family = (uint32_t)family;
1488 1569                  ld->ld_sin.sin_port = htons(port);
1489 1570                  ld->ld_sin.sin_addr.s_addr = htonl(INADDR_ANY);
1490 1571          } else {
1491 1572                  ld->ld_sin6.sin6_family = (uint32_t)family;
1492 1573                  ld->ld_sin6.sin6_port = htons(port);
1493 1574                  (void) memset(&ld->ld_sin6.sin6_addr.s6_addr, 0,
1494 1575                      sizeof (ld->ld_sin6.sin6_addr.s6_addr));
1495 1576          }
1496 1577  
1497      -        smb_llist_constructor(&ld->ld_session_list, sizeof (smb_session_t),
1498      -            offsetof(smb_session_t, s_lnd));
1499 1578          smb_thread_init(&ld->ld_thread, name, smb_server_listener, ld,
1500 1579              smbsrv_listen_pri);
1501 1580          ld->ld_magic = SMB_LISTENER_MAGIC;
1502 1581  }
1503 1582  
1504 1583  /*
1505 1584   * smb_server_listener_destroy
1506 1585   *
1507 1586   * Destroyes listener contexts.
1508 1587   */
↓ open down ↓ 3 lines elided ↑ open up ↑
1512 1591          /*
1513 1592           * Note that if startup fails early, we can legitimately
1514 1593           * get here with an all-zeros object.
1515 1594           */
1516 1595          if (ld->ld_magic == 0)
1517 1596                  return;
1518 1597  
1519 1598          SMB_LISTENER_VALID(ld);
1520 1599          ASSERT(ld->ld_so == NULL);
1521 1600          smb_thread_destroy(&ld->ld_thread);
1522      -        smb_llist_destructor(&ld->ld_session_list);
1523 1601          ld->ld_magic = 0;
1524 1602  }
1525 1603  
1526 1604  /*
1527 1605   * smb_server_listener_start
1528 1606   *
1529 1607   * Starts the listener associated with the context passed in.
1530 1608   *
1531 1609   * Return:      0       Success
1532 1610   *              not 0   Failure
↓ open down ↓ 77 lines elided ↑ open up ↑
1610 1688  /*
1611 1689   * smb_server_listener
1612 1690   *
1613 1691   * Entry point of the listeners.
1614 1692   */
1615 1693  static void
1616 1694  smb_server_listener(smb_thread_t *thread, void *arg)
1617 1695  {
1618 1696          _NOTE(ARGUNUSED(thread))
1619 1697          smb_listener_daemon_t   *ld;
1620      -        smb_session_t           *session;
1621 1698          ksocket_t               s_so;
1622 1699          int                     on;
1623 1700          int                     txbuf_size;
1624 1701  
1625 1702          ld = (smb_listener_daemon_t *)arg;
1626 1703  
1627 1704          SMB_LISTENER_VALID(ld);
1628 1705  
1629 1706          DTRACE_PROBE1(so__wait__accept, struct sonode *, ld->ld_so);
1630 1707  
1631      -        while (ksocket_accept(ld->ld_so, NULL, NULL, &s_so, CRED())
1632      -            == 0) {
     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 +
1633 1726                  DTRACE_PROBE1(so__accept, struct sonode *, s_so);
1634 1727  
1635 1728                  on = 1;
1636 1729                  (void) ksocket_setsockopt(s_so, IPPROTO_TCP, TCP_NODELAY,
1637 1730                      &on, sizeof (on), CRED());
1638 1731  
1639 1732                  on = 1;
1640 1733                  (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_KEEPALIVE,
1641 1734                      &on, sizeof (on), CRED());
1642 1735  
1643 1736                  txbuf_size = 128*1024;
1644 1737                  (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_SNDBUF,
1645 1738                      (const void *)&txbuf_size, sizeof (txbuf_size), CRED());
1646 1739  
1647 1740                  /*
1648 1741                   * Create a session for this connection.
1649 1742                   */
1650 1743                  smb_server_create_session(ld, s_so);
1651 1744          }
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);
     1745 +out:
1660 1746          ksocket_rele(ld->ld_so);
1661 1747  }
1662 1748  
1663 1749  /*
1664 1750   * smb_server_receiver
1665 1751   *
1666 1752   * Entry point of the receiver threads.
     1753 + * Also does cleanup when socket disconnected.
1667 1754   */
1668 1755  static void
1669 1756  smb_server_receiver(void *arg)
1670 1757  {
1671      -        smb_listener_daemon_t   *ld;
1672      -        smb_session_t           *session;
     1758 +        smb_session_t   *session;
1673 1759  
1674      -        ld = ((smb_receiver_arg_t *)arg)->ra_listener;
1675      -        session = ((smb_receiver_arg_t *)arg)->ra_session;
1676      -        smb_mem_free(arg);
     1760 +        session = (smb_session_t *)arg;
     1761 +
     1762 +        /* We stay in here until socket disconnect. */
1677 1763          smb_session_receiver(session);
1678      -        smb_server_destroy_session(ld, session);
     1764 +
     1765 +        ASSERT(session->s_state == SMB_SESSION_STATE_SHUTDOWN);
     1766 +        smb_server_destroy_session(session);
1679 1767  }
1680 1768  
1681 1769  /*
1682 1770   * smb_server_lookup
1683 1771   *
1684 1772   * This function finds the server associated with the zone of the
1685 1773   * caller.  Note: requires a fix in the dynamic taskq code:
1686 1774   * 1501 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0
1687 1775   */
1688 1776  int
↓ open down ↓ 42 lines elided ↑ open up ↑
1731 1819          sv->sv_refcnt--;
1732 1820          if ((sv->sv_refcnt == 0) && (sv->sv_state == SMB_SERVER_STATE_DELETING))
1733 1821                  cv_signal(&sv->sv_cv);
1734 1822          mutex_exit(&sv->sv_mutex);
1735 1823  }
1736 1824  
1737 1825  /*
1738 1826   * Enumerate the users associated with a session list.
1739 1827   */
1740 1828  static void
1741      -smb_server_enum_users(smb_llist_t *ll, smb_svcenum_t *svcenum)
     1829 +smb_server_enum_users(smb_server_t *sv, smb_svcenum_t *svcenum)
1742 1830  {
     1831 +        smb_llist_t     *ll = &sv->sv_session_list;
1743 1832          smb_session_t   *sn;
1744 1833          smb_llist_t     *ulist;
1745 1834          smb_user_t      *user;
1746 1835          int             rc = 0;
1747 1836  
1748 1837          smb_llist_enter(ll, RW_READER);
1749 1838          sn = smb_llist_head(ll);
1750 1839  
1751 1840          while (sn != NULL) {
1752 1841                  SMB_SESSION_VALID(sn);
↓ open down ↓ 20 lines elided ↑ open up ↑
1773 1862                  sn = smb_llist_next(ll, sn);
1774 1863          }
1775 1864  
1776 1865          smb_llist_exit(ll);
1777 1866  }
1778 1867  
1779 1868  /*
1780 1869   * Enumerate the trees/files associated with a session list.
1781 1870   */
1782 1871  static void
1783      -smb_server_enum_trees(smb_llist_t *ll, smb_svcenum_t *svcenum)
     1872 +smb_server_enum_trees(smb_server_t *sv, smb_svcenum_t *svcenum)
1784 1873  {
     1874 +        smb_llist_t     *ll = &sv->sv_session_list;
1785 1875          smb_session_t   *sn;
1786 1876          smb_llist_t     *tlist;
1787 1877          smb_tree_t      *tree;
1788 1878          int             rc = 0;
1789 1879  
1790 1880          smb_llist_enter(ll, RW_READER);
1791 1881          sn = smb_llist_head(ll);
1792 1882  
1793 1883          while (sn != NULL) {
1794 1884                  SMB_SESSION_VALID(sn);
↓ open down ↓ 21 lines elided ↑ open up ↑
1816 1906          }
1817 1907  
1818 1908          smb_llist_exit(ll);
1819 1909  }
1820 1910  
1821 1911  /*
1822 1912   * Disconnect sessions associated with the specified client and username.
1823 1913   * Empty strings are treated as wildcards.
1824 1914   */
1825 1915  static int
1826      -smb_server_session_disconnect(smb_llist_t *ll,
     1916 +smb_server_session_disconnect(smb_server_t *sv,
1827 1917      const char *client, const char *name)
1828 1918  {
     1919 +        smb_llist_t     *ll = &sv->sv_session_list;
1829 1920          smb_session_t   *sn;
1830 1921          smb_llist_t     *ulist;
1831 1922          smb_user_t      *user;
1832      -        boolean_t       match;
1833 1923          int             count = 0;
1834 1924  
1835 1925          smb_llist_enter(ll, RW_READER);
1836      -        sn = smb_llist_head(ll);
1837 1926  
1838      -        while (sn != NULL) {
     1927 +        for (sn = smb_llist_head(ll);
     1928 +            sn != NULL;
     1929 +            sn = smb_llist_next(ll, sn)) {
1839 1930                  SMB_SESSION_VALID(sn);
1840 1931  
1841      -                if ((*client != '\0') && (!smb_session_isclient(sn, client))) {
1842      -                        sn = smb_llist_next(ll, sn);
     1932 +                if (*client != '\0' && !smb_session_isclient(sn, client))
1843 1933                          continue;
1844      -                }
1845 1934  
1846 1935                  ulist = &sn->s_user_list;
1847 1936                  smb_llist_enter(ulist, RW_READER);
1848      -                user = smb_llist_head(ulist);
1849 1937  
1850      -                while (user != NULL) {
1851      -                        if (smb_user_hold(user)) {
1852      -                                match = (*name == '\0');
1853      -                                if (!match)
1854      -                                        match = smb_user_namecmp(user, name);
     1938 +                for (user = smb_llist_head(ulist);
     1939 +                    user != NULL;
     1940 +                    user = smb_llist_next(ulist, user)) {
     1941 +                        SMB_USER_VALID(user);
1855 1942  
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      -                                }
     1943 +                        if (*name != '\0' && !smb_user_namecmp(user, name))
     1944 +                                continue;
1865 1945  
     1946 +                        if (smb_user_hold(user)) {
     1947 +                                smb_user_logoff(user);
1866 1948                                  smb_user_release(user);
     1949 +                                count++;
1867 1950                          }
1868      -
1869      -                        user = smb_llist_next(ulist, user);
1870 1951                  }
1871 1952  
1872 1953                  smb_llist_exit(ulist);
1873      -                sn = smb_llist_next(ll, sn);
1874 1954          }
1875 1955  
1876 1956          smb_llist_exit(ll);
1877 1957          return (count);
1878 1958  }
1879 1959  
1880 1960  /*
1881 1961   * Close a file by its unique id.
1882 1962   */
1883 1963  static int
1884      -smb_server_fclose(smb_llist_t *ll, uint32_t uniqid)
     1964 +smb_server_fclose(smb_server_t *sv, uint32_t uniqid)
1885 1965  {
     1966 +        smb_llist_t     *ll;
1886 1967          smb_session_t   *sn;
1887 1968          smb_llist_t     *tlist;
1888 1969          smb_tree_t      *tree;
1889 1970          int             rc = ENOENT;
1890 1971  
     1972 +        ll = &sv->sv_session_list;
1891 1973          smb_llist_enter(ll, RW_READER);
1892 1974          sn = smb_llist_head(ll);
1893 1975  
1894 1976          while ((sn != NULL) && (rc == ENOENT)) {
1895 1977                  SMB_SESSION_VALID(sn);
1896 1978                  tlist = &sn->s_tree_list;
1897 1979                  smb_llist_enter(tlist, RW_READER);
1898 1980                  tree = smb_llist_head(tlist);
1899 1981  
1900 1982                  while ((tree != NULL) && (rc == ENOENT)) {
↓ open down ↓ 6 lines elided ↑ open up ↑
1907 1989                  }
1908 1990  
1909 1991                  smb_llist_exit(tlist);
1910 1992                  sn = smb_llist_next(ll, sn);
1911 1993          }
1912 1994  
1913 1995          smb_llist_exit(ll);
1914 1996          return (rc);
1915 1997  }
1916 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 +
1917 2057  /* See also: libsmb smb_kmod_setcfg */
1918 2058  static void
1919 2059  smb_server_store_cfg(smb_server_t *sv, smb_ioc_cfg_t *ioc)
1920 2060  {
1921 2061          if (ioc->maxconnections == 0)
1922 2062                  ioc->maxconnections = 0xFFFFFFFF;
1923 2063  
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);
     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 +        }
1928 2070  
1929 2071          sv->sv_cfg.skc_maxworkers = ioc->maxworkers;
1930 2072          sv->sv_cfg.skc_maxconnections = ioc->maxconnections;
1931 2073          sv->sv_cfg.skc_keepalive = ioc->keepalive;
1932 2074          sv->sv_cfg.skc_restrict_anon = ioc->restrict_anon;
1933 2075          sv->sv_cfg.skc_signing_enable = ioc->signing_enable;
1934 2076          sv->sv_cfg.skc_signing_required = ioc->signing_required;
1935 2077          sv->sv_cfg.skc_oplock_enable = ioc->oplock_enable;
1936 2078          sv->sv_cfg.skc_sync_enable = ioc->sync_enable;
1937 2079          sv->sv_cfg.skc_secmode = ioc->secmode;
1938 2080          sv->sv_cfg.skc_netbios_enable = ioc->netbios_enable;
1939 2081          sv->sv_cfg.skc_ipv6_enable = ioc->ipv6_enable;
1940 2082          sv->sv_cfg.skc_print_enable = ioc->print_enable;
1941 2083          sv->sv_cfg.skc_traverse_mounts = ioc->traverse_mounts;
1942 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;
1943 2087          sv->sv_cfg.skc_execflags = ioc->exec_flags;
1944 2088          sv->sv_cfg.skc_negtok_len = ioc->negtok_len;
1945 2089          sv->sv_cfg.skc_version = ioc->version;
1946 2090          sv->sv_cfg.skc_initial_credits = ioc->initial_credits;
1947 2091          sv->sv_cfg.skc_maximum_credits = ioc->maximum_credits;
1948 2092  
1949 2093          (void) memcpy(sv->sv_cfg.skc_machine_uuid, ioc->machine_uuid,
1950 2094              sizeof (uuid_t));
1951 2095          (void) memcpy(sv->sv_cfg.skc_negtok, ioc->negtok,
1952 2096              sizeof (sv->sv_cfg.skc_negtok));
↓ open down ↓ 363 lines elided ↑ open up ↑
2316 2460          return (rc);
2317 2461  }
2318 2462  
2319 2463  /*
2320 2464   * smb_server_create_session
2321 2465   */
2322 2466  static void
2323 2467  smb_server_create_session(smb_listener_daemon_t *ld, ksocket_t s_so)
2324 2468  {
2325 2469          smb_session_t           *session;
2326      -        smb_receiver_arg_t      *rarg;
2327 2470          taskqid_t               tqid;
     2471 +        smb_llist_t             *sl;
     2472 +        smb_server_t            *sv = ld->ld_sv;
2328 2473  
2329      -        session = smb_session_create(s_so, ld->ld_port, ld->ld_sv,
     2474 +        session = smb_session_create(s_so, ld->ld_port, sv,
2330 2475              ld->ld_family);
2331 2476  
2332 2477          if (session == NULL) {
2333 2478                  smb_soshutdown(s_so);
2334 2479                  smb_sodestroy(s_so);
2335 2480                  cmn_err(CE_WARN, "SMB Session: alloc failed");
2336 2481                  return;
2337 2482          }
2338 2483  
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);
     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);
2342 2488  
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 2489          /*
2349 2490           * These taskq entries must run independently of one another,
2350 2491           * so TQ_NOQUEUE.  TQ_SLEEP (==0) just for clarity.
2351 2492           */
2352      -        tqid = taskq_dispatch(ld->ld_sv->sv_receiver_pool,
2353      -            smb_server_receiver, rarg, TQ_NOQUEUE | TQ_SLEEP);
     2493 +        tqid = taskq_dispatch(sv->sv_receiver_pool,
     2494 +            smb_server_receiver, session, TQ_NOQUEUE | TQ_SLEEP);
2354 2495          if (tqid == 0) {
2355      -                smb_mem_free(rarg);
2356 2496                  smb_session_disconnect(session);
2357      -                smb_server_destroy_session(ld, session);
     2497 +                smb_server_destroy_session(session);
2358 2498                  cmn_err(CE_WARN, "SMB Session: taskq_dispatch failed");
2359 2499                  return;
2360 2500          }
2361 2501          /* handy for debugging */
2362 2502          session->s_receiver_tqid = tqid;
2363 2503  }
2364 2504  
2365 2505  static void
2366      -smb_server_destroy_session(smb_listener_daemon_t *ld, smb_session_t *session)
     2506 +smb_server_destroy_session(smb_session_t *session)
2367 2507  {
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);
     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 +
2371 2538          smb_session_delete(session);
     2539 +        if (count == 0) {
     2540 +                /* See smb_server_shutdown */
     2541 +                cv_signal(&sv->sv_cv);
     2542 +        }
2372 2543  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX