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)
   1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
  14  */
  15 
  16 /*
  17  * Dispatch function for SMB2_SESSION_SETUP
  18  *
  19  * Note that the Capabilities supplied in this request are an inferior
  20  * subset of those given to us previously in the SMB2 Negotiate request.
  21  * We need to remember the full set of capabilities from SMB2 Negotiate,
  22  * and therefore ignore the subset of capabilities supplied here.
  23  */
  24 
  25 #include <smbsrv/smb2_kproto.h>
  26 
  27 static void smb2_ss_adjust_credits(smb_request_t *);
  28 
  29 smb_sdrc_t
  30 smb2_session_setup(smb_request_t *sr)
  31 {
  32         smb_arg_sessionsetup_t  *sinfo;

  33         uint16_t StructureSize;
  34         uint8_t  Flags;
  35         uint8_t  SecurityMode;
  36         uint32_t Capabilities;  /* ignored - see above */
  37         uint32_t Channel;
  38         uint16_t SecBufOffset;
  39         uint16_t SecBufLength;
  40         uint64_t PrevSessionId;
  41         uint16_t SessionFlags;
  42         uint32_t status;
  43         int skip;
  44         int rc = 0;
  45 
  46         sinfo = smb_srm_zalloc(sr, sizeof (smb_arg_sessionsetup_t));
  47         sr->sr_ssetup = sinfo;
  48 
  49         rc = smb_mbc_decodef(
  50             &sr->smb_data, "wbbllwwq",
  51             &StructureSize, /* w */
  52             &Flags,         /* b */
  53             &SecurityMode,  /* b */
  54             &Capabilities,  /* l */
  55             &Channel,               /* l */
  56             &SecBufOffset,  /* w */
  57             &SecBufLength,  /* w */
  58             &PrevSessionId);        /* q */
  59         if (rc)
  60                 return (SDRC_ERROR);
  61 
  62         /*
  63          * We're normally positioned at the security buffer now,
  64          * but there could be some padding before it.
  65          */
  66         skip = (SecBufOffset + sr->smb2_cmd_hdr) -
  67             sr->smb_data.chain_offset;
  68         if (skip < 0)
  69                 return (SDRC_ERROR);
  70         if (skip > 0)
  71                 (void) smb_mbc_decodef(&sr->smb_data, "#.", skip);
  72 
  73         /*
  74          * Get the security buffer
  75          */
  76         sinfo->ssi_iseclen = SecBufLength;
  77         sinfo->ssi_isecblob = smb_srm_zalloc(sr, sinfo->ssi_iseclen);
  78         rc = smb_mbc_decodef(&sr->smb_data, "#c",
  79             sinfo->ssi_iseclen, sinfo->ssi_isecblob);
  80         if (rc)
  81                 return (SDRC_ERROR);
  82 
  83         /*





































  84          * The real auth. work happens in here.
  85          */
  86         status = smb_authenticate_ext(sr);
  87 
  88         SecBufOffset = SMB2_HDR_SIZE + 8;
  89         SecBufLength = sinfo->ssi_oseclen;
  90         SessionFlags = 0;
  91 
  92         switch (status) {
  93 
  94         case NT_STATUS_SUCCESS: /* Authenticated */
  95                 if (sr->uid_user->u_flags & SMB_USER_FLAG_GUEST)
  96                         SessionFlags |= SMB2_SESSION_FLAG_IS_GUEST;
  97                 if (sr->uid_user->u_flags & SMB_USER_FLAG_ANON)
  98                         SessionFlags |= SMB2_SESSION_FLAG_IS_NULL;


  99                 smb2_ss_adjust_credits(sr);











 100                 break;











 101 
 102         /*
 103          * This is not really an error, but tells the client
 104          * it should send another session setup request.
 105          * Not smb2_put_error because we send a payload.
 106          */
 107         case NT_STATUS_MORE_PROCESSING_REQUIRED:
 108                 sr->smb2_status = status;
 109                 break;
 110 
 111         default:

 112                 SecBufLength = 0;
 113                 sr->smb2_status = status;
 114                 break;
 115         }
 116 



 117         /*
 118          * SMB2 Session Setup reply
 119          */
 120 
 121         rc = smb_mbc_encodef(
 122             &sr->reply,
 123             "wwww#c",
 124             9,  /* StructSize */        /* w */
 125             SessionFlags,               /* w */
 126             SecBufOffset,               /* w */
 127             SecBufLength,               /* w */
 128             SecBufLength,               /* # */
 129             sinfo->ssi_osecblob);    /* c */
 130         if (rc)
 131                 return (SDRC_ERROR);
 132 
 133         return (SDRC_SUCCESS);
 134 }
 135 
 136 /*
 137  * After a successful authentication, raise s_max_credits up to the
 138  * normal maximum that clients are allowed to request.  Also, if we
 139  * haven't yet given them their initial credits, do that now.
 140  *
 141  * Normally, clients will request some credits with session setup,
 142  * but in case they don't request enough to raise s_cur_credits
 143  * up to the configured initial_credits, increase the requested
 144  * credits of this SR sufficiently to make that happen.  The actual
 145  * increase happens in the dispatch code after we return.
 146  */
 147 static void
 148 smb2_ss_adjust_credits(smb_request_t *sr)
 149 {
 150         smb_session_t *s = sr->session;
 151 


   1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  14  */
  15 
  16 /*
  17  * Dispatch function for SMB2_SESSION_SETUP
  18  *
  19  * Note that the Capabilities supplied in this request are an inferior
  20  * subset of those given to us previously in the SMB2 Negotiate request.
  21  * We need to remember the full set of capabilities from SMB2 Negotiate,
  22  * and therefore ignore the subset of capabilities supplied here.
  23  */
  24 
  25 #include <smbsrv/smb2_kproto.h>
  26 
  27 static void smb2_ss_adjust_credits(smb_request_t *);
  28 
  29 smb_sdrc_t
  30 smb2_session_setup(smb_request_t *sr)
  31 {
  32         smb_arg_sessionsetup_t  *sinfo;
  33         smb_user_t *prev_user;
  34         uint16_t StructureSize;
  35         uint8_t  Flags;
  36         uint8_t  SecurityMode;
  37         uint32_t Capabilities;  /* ignored - see above */
  38         uint32_t Channel;
  39         uint16_t SecBufOffset;
  40         uint16_t SecBufLength;
  41         uint64_t PrevSsnId;
  42         uint16_t SessionFlags;
  43         uint32_t status;
  44         int skip;
  45         int rc = 0;
  46 
  47         sinfo = smb_srm_zalloc(sr, sizeof (smb_arg_sessionsetup_t));
  48         sr->sr_ssetup = sinfo;
  49 
  50         rc = smb_mbc_decodef(
  51             &sr->smb_data, "wbbllwwq",
  52             &StructureSize, /* w */
  53             &Flags,         /* b */
  54             &SecurityMode,  /* b */
  55             &Capabilities,  /* l */
  56             &Channel,               /* l */
  57             &SecBufOffset,  /* w */
  58             &SecBufLength,  /* w */
  59             &PrevSsnId);    /* q */
  60         if (rc)
  61                 return (SDRC_ERROR);
  62 
  63         /*
  64          * We're normally positioned at the security buffer now,
  65          * but there could be some padding before it.
  66          */
  67         skip = (SecBufOffset + sr->smb2_cmd_hdr) -
  68             sr->smb_data.chain_offset;
  69         if (skip < 0)
  70                 return (SDRC_ERROR);
  71         if (skip > 0)
  72                 (void) smb_mbc_decodef(&sr->smb_data, "#.", skip);
  73 
  74         /*
  75          * Get the security buffer
  76          */
  77         sinfo->ssi_iseclen = SecBufLength;
  78         sinfo->ssi_isecblob = smb_srm_zalloc(sr, sinfo->ssi_iseclen);
  79         rc = smb_mbc_decodef(&sr->smb_data, "#c",
  80             sinfo->ssi_iseclen, sinfo->ssi_isecblob);
  81         if (rc)
  82                 return (SDRC_ERROR);
  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         /*
 122          * The real auth. work happens in here.
 123          */
 124         status = smb_authenticate_ext(sr);
 125 
 126         SecBufOffset = SMB2_HDR_SIZE + 8;
 127         SecBufLength = sinfo->ssi_oseclen;
 128         SessionFlags = 0;
 129 
 130         switch (status) {
 131 
 132         case NT_STATUS_SUCCESS: /* Authenticated */
 133                 if ((sr->uid_user->u_flags & SMB_USER_FLAG_GUEST) != 0)
 134                         SessionFlags |= SMB2_SESSION_FLAG_IS_GUEST;
 135                 if ((sr->uid_user->u_flags & SMB_USER_FLAG_ANON) != 0)
 136                         SessionFlags |= SMB2_SESSION_FLAG_IS_NULL;
 137                 if (sr->uid_user->u_encrypt != SMB_CONFIG_DISABLED)
 138                         SessionFlags |= SMB2_SESSION_FLAG_ENCRYPT_DATA;
 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                 }
 162                 break;
 163 
 164         /*
 165          * This is not really an error, but tells the client
 166          * it should send another session setup request.
 167          * Not smb2_put_error because we send a payload.
 168          */
 169         case NT_STATUS_MORE_PROCESSING_REQUIRED:
 170                 sr->smb2_status = status;
 171                 break;
 172 
 173         default:
 174 errout:
 175                 SecBufLength = 0;
 176                 sr->smb2_status = status;
 177                 break;
 178         }
 179 
 180         /* sr->smb2_status set above */
 181         DTRACE_SMB2_DONE(op__SessionSetup, smb_request_t *, sr);
 182 
 183         /*
 184          * SMB2 Session Setup reply
 185          */
 186 
 187         rc = smb_mbc_encodef(
 188             &sr->reply,
 189             "wwww#c",
 190             9,  /* StructSize */        /* w */
 191             SessionFlags,               /* w */
 192             SecBufOffset,               /* w */
 193             SecBufLength,               /* w */
 194             SecBufLength,               /* # */
 195             sinfo->ssi_osecblob);    /* c */
 196         if (rc)
 197                 sr->smb2_status = NT_STATUS_INTERNAL_ERROR;
 198 
 199         return (SDRC_SUCCESS);
 200 }
 201 
 202 /*
 203  * After a successful authentication, raise s_max_credits up to the
 204  * normal maximum that clients are allowed to request.  Also, if we
 205  * haven't yet given them their initial credits, do that now.
 206  *
 207  * Normally, clients will request some credits with session setup,
 208  * but in case they don't request enough to raise s_cur_credits
 209  * up to the configured initial_credits, increase the requested
 210  * credits of this SR sufficiently to make that happen.  The actual
 211  * increase happens in the dispatch code after we return.
 212  */
 213 static void
 214 smb2_ss_adjust_credits(smb_request_t *sr)
 215 {
 216         smb_session_t *s = sr->session;
 217