Print this page
NEX-15578 SMB2 durable handle redesign
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15555 SMB2 async redesign
NEX-15061 smtorture smb2.lock.cancel.cancel is failed
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Also follow-up change to:
 NEX-1643 dtrace provider for smbsrv (remove "done2" probes,
 which don't make sense with the new async design)
NEX-15578 SMB2 durable handle redesign
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15555 SMB2 async redesign
NEX-15061 smtorture smb2.lock.cancel.cancel is failed
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Also follow-up change to:
 NEX-1643 dtrace provider for smbsrv (remove "done2" probes,
 which don't make sense with the new async design)
NEX-1643 dtrace provider for smbsrv
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@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-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-4598 SMB2 credit shortage with Mac client
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-3610 CLONE NEX-3591 SMB3 signing
Reviewed by: Gordon Ross <gwr@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
NEX-2781 SMB2 credit handling needs work
SMB-55 SMB2 signing
SMB-96 Codenomicon: SMB2 TC: 141500 - Panic in smb2_decode_create_ctx
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)

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/smbsrv/smb2_session_setup.c
          +++ new/usr/src/uts/common/fs/smbsrv/smb2_session_setup.c
↓ open down ↓ 2 lines elided ↑ open up ↑
   3    3   * Common Development and Distribution License ("CDDL"), version 1.0.
   4    4   * You may only use this file in accordance with the terms of version
   5    5   * 1.0 of the CDDL.
   6    6   *
   7    7   * A full copy of the text of the CDDL should have accompanied this
   8    8   * source.  A copy of the CDDL is also available via the Internet at
   9    9   * http://www.illumos.org/license/CDDL.
  10   10   */
  11   11  
  12   12  /*
  13      - * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
       13 + * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  14   14   */
  15   15  
  16   16  /*
  17   17   * Dispatch function for SMB2_SESSION_SETUP
  18   18   *
  19   19   * Note that the Capabilities supplied in this request are an inferior
  20   20   * subset of those given to us previously in the SMB2 Negotiate request.
  21   21   * We need to remember the full set of capabilities from SMB2 Negotiate,
  22   22   * and therefore ignore the subset of capabilities supplied here.
  23   23   */
  24   24  
  25   25  #include <smbsrv/smb2_kproto.h>
  26   26  
  27   27  static void smb2_ss_adjust_credits(smb_request_t *);
  28   28  
  29   29  smb_sdrc_t
  30   30  smb2_session_setup(smb_request_t *sr)
  31   31  {
  32   32          smb_arg_sessionsetup_t  *sinfo;
       33 +        smb_user_t *prev_user;
  33   34          uint16_t StructureSize;
  34   35          uint8_t  Flags;
  35   36          uint8_t  SecurityMode;
  36   37          uint32_t Capabilities;  /* ignored - see above */
  37   38          uint32_t Channel;
  38   39          uint16_t SecBufOffset;
  39   40          uint16_t SecBufLength;
  40      -        uint64_t PrevSessionId;
       41 +        uint64_t PrevSsnId;
  41   42          uint16_t SessionFlags;
  42   43          uint32_t status;
  43   44          int skip;
  44   45          int rc = 0;
  45   46  
  46   47          sinfo = smb_srm_zalloc(sr, sizeof (smb_arg_sessionsetup_t));
  47   48          sr->sr_ssetup = sinfo;
  48   49  
  49   50          rc = smb_mbc_decodef(
  50   51              &sr->smb_data, "wbbllwwq",
  51   52              &StructureSize,     /* w */
  52   53              &Flags,             /* b */
  53   54              &SecurityMode,      /* b */
  54   55              &Capabilities,      /* l */
  55   56              &Channel,           /* l */
  56   57              &SecBufOffset,      /* w */
  57   58              &SecBufLength,      /* w */
  58      -            &PrevSessionId);    /* q */
       59 +            &PrevSsnId);        /* q */
  59   60          if (rc)
  60   61                  return (SDRC_ERROR);
  61   62  
  62   63          /*
  63   64           * We're normally positioned at the security buffer now,
  64   65           * but there could be some padding before it.
  65   66           */
  66   67          skip = (SecBufOffset + sr->smb2_cmd_hdr) -
  67   68              sr->smb_data.chain_offset;
  68   69          if (skip < 0)
↓ open down ↓ 5 lines elided ↑ open up ↑
  74   75           * Get the security buffer
  75   76           */
  76   77          sinfo->ssi_iseclen = SecBufLength;
  77   78          sinfo->ssi_isecblob = smb_srm_zalloc(sr, sinfo->ssi_iseclen);
  78   79          rc = smb_mbc_decodef(&sr->smb_data, "#c",
  79   80              sinfo->ssi_iseclen, sinfo->ssi_isecblob);
  80   81          if (rc)
  81   82                  return (SDRC_ERROR);
  82   83  
  83   84          /*
       85 +         * Decoded everything.  Dtrace probe,
       86 +         * then no more early returns.
       87 +         */
       88 +        DTRACE_SMB2_START(op__SessionSetup, smb_request_t *, sr);
       89 +
       90 +        /*
       91 +         * [MS-SMB2] 3.3.5.5 Receiving an SMB2 SESSION_SETUP Request
       92 +         *
       93 +         * If we support 3.x, RejectUnencryptedAccess is TRUE,
       94 +         * global EncryptData is TRUE, but we're not talking
       95 +         * 3.x or the client doesn't support encryption,
       96 +         * return ACCESS_DENIED.
       97 +         *
       98 +         * If RejectUnencryptedAccess is TRUE, we force max_protocol
       99 +         * to at least 3.0.
      100 +         */
      101 +        if (sr->sr_server->sv_cfg.skc_encrypt == SMB_CONFIG_REQUIRED &&
      102 +            (sr->session->dialect < SMB_VERS_3_0 ||
      103 +            !SMB3_CLIENT_ENCRYPTS(sr))) {
      104 +                status = NT_STATUS_ACCESS_DENIED;
      105 +                goto errout;
      106 +        }
      107 +
      108 +        /*
      109 +         * SMB3 multi-channel features are not supported.
      110 +         * Once they are, this will check the dialect and
      111 +         * whether multi-channel was negotiated, i.e.
      112 +         *      if (sr->session->dialect < SMB_VERS_3_0 ||
      113 +         *          s->IsMultiChannelCapable == False)
      114 +         *              return (error...)
      115 +         */
      116 +        if (Flags & SMB2_SESSION_FLAG_BINDING) {
      117 +                status = NT_STATUS_REQUEST_NOT_ACCEPTED;
      118 +                goto errout;
      119 +        }
      120 +
      121 +        /*
  84  122           * The real auth. work happens in here.
  85  123           */
  86  124          status = smb_authenticate_ext(sr);
  87  125  
  88  126          SecBufOffset = SMB2_HDR_SIZE + 8;
  89  127          SecBufLength = sinfo->ssi_oseclen;
  90  128          SessionFlags = 0;
  91  129  
  92  130          switch (status) {
  93  131  
  94  132          case NT_STATUS_SUCCESS: /* Authenticated */
  95      -                if (sr->uid_user->u_flags & SMB_USER_FLAG_GUEST)
      133 +                if ((sr->uid_user->u_flags & SMB_USER_FLAG_GUEST) != 0)
  96  134                          SessionFlags |= SMB2_SESSION_FLAG_IS_GUEST;
  97      -                if (sr->uid_user->u_flags & SMB_USER_FLAG_ANON)
      135 +                if ((sr->uid_user->u_flags & SMB_USER_FLAG_ANON) != 0)
  98  136                          SessionFlags |= SMB2_SESSION_FLAG_IS_NULL;
      137 +                if (sr->uid_user->u_encrypt != SMB_CONFIG_DISABLED)
      138 +                        SessionFlags |= SMB2_SESSION_FLAG_ENCRYPT_DATA;
  99  139                  smb2_ss_adjust_credits(sr);
      140 +
      141 +                /*
      142 +                 * PrevSsnId is a session that the client is reporting as
      143 +                 * having gone away, and for which we might not yet have seen
      144 +                 * a disconnect. Find the session and log it off as if we had
      145 +                 * received a disconnect.  Note that the client is allowed to
      146 +                 * set PrevSsnID to the _current_ SessionID, so skip the lookup
      147 +                 * in that case. Only allow this session logoff if we owned it.
      148 +                 */
      149 +                if (PrevSsnId == 0 ||
      150 +                    PrevSsnId == sr->smb2_ssnid)
      151 +                        break;
      152 +                prev_user = smb_server_lookup_ssnid(sr->sr_server, PrevSsnId);
      153 +                if (prev_user != NULL) {
      154 +                        if (smb_is_same_user(prev_user->u_cred, sr->user_cr)) {
      155 +                                /* Treat this as if we lost the connection */
      156 +                                prev_user->preserve_opens =
      157 +                                    SMB2_DH_PRESERVE_SOME;
      158 +                                smb_user_logoff(prev_user);
      159 +                        }
      160 +                        smb_user_release(prev_user); /* from lookup */
      161 +                }
 100  162                  break;
 101  163  
 102  164          /*
 103  165           * This is not really an error, but tells the client
 104  166           * it should send another session setup request.
 105  167           * Not smb2_put_error because we send a payload.
 106  168           */
 107  169          case NT_STATUS_MORE_PROCESSING_REQUIRED:
 108  170                  sr->smb2_status = status;
 109  171                  break;
 110  172  
 111  173          default:
      174 +errout:
 112  175                  SecBufLength = 0;
 113  176                  sr->smb2_status = status;
 114  177                  break;
 115  178          }
 116  179  
      180 +        /* sr->smb2_status set above */
      181 +        DTRACE_SMB2_DONE(op__SessionSetup, smb_request_t *, sr);
      182 +
 117  183          /*
 118  184           * SMB2 Session Setup reply
 119  185           */
 120  186  
 121  187          rc = smb_mbc_encodef(
 122  188              &sr->reply,
 123  189              "wwww#c",
 124  190              9,  /* StructSize */        /* w */
 125  191              SessionFlags,               /* w */
 126  192              SecBufOffset,               /* w */
 127  193              SecBufLength,               /* w */
 128  194              SecBufLength,               /* # */
 129  195              sinfo->ssi_osecblob);       /* c */
 130  196          if (rc)
 131      -                return (SDRC_ERROR);
      197 +                sr->smb2_status = NT_STATUS_INTERNAL_ERROR;
 132  198  
 133  199          return (SDRC_SUCCESS);
 134  200  }
 135  201  
 136  202  /*
 137  203   * After a successful authentication, raise s_max_credits up to the
 138  204   * normal maximum that clients are allowed to request.  Also, if we
 139  205   * haven't yet given them their initial credits, do that now.
 140  206   *
 141  207   * Normally, clients will request some credits with session setup,
↓ open down ↓ 34 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX