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
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
|
↓ 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)
69 70 return (SDRC_ERROR);
70 71 if (skip > 0)
71 72 (void) smb_mbc_decodef(&sr->smb_data, "#.", skip);
72 73
73 74 /*
|
↓ 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,
142 208 * but in case they don't request enough to raise s_cur_credits
143 209 * up to the configured initial_credits, increase the requested
144 210 * credits of this SR sufficiently to make that happen. The actual
145 211 * increase happens in the dispatch code after we return.
146 212 */
147 213 static void
148 214 smb2_ss_adjust_credits(smb_request_t *sr)
149 215 {
150 216 smb_session_t *s = sr->session;
151 217
152 218 mutex_enter(&s->s_credits_mutex);
153 219 s->s_max_credits = s->s_cfg.skc_maximum_credits;
154 220
155 221 if (s->s_cur_credits < s->s_cfg.skc_initial_credits) {
156 222 uint16_t grant;
157 223
158 224 /* How many credits we want to grant with this SR. */
159 225 grant = s->s_cfg.skc_initial_credits - s->s_cur_credits;
160 226
161 227 /*
162 228 * Do we need to increase the smb2_credit_request?
163 229 * One might prefer to read this expression as:
164 230 * ((credit_request - credit_charge) < grant)
165 231 * but we know credit_charge == 1 and would rather not
166 232 * deal with a possibly negative value on the left,
167 233 * so adding credit_charge to both sides...
168 234 */
169 235 if (sr->smb2_credit_request < (grant + 1)) {
170 236 sr->smb2_credit_request = (grant + 1);
171 237 }
172 238 }
173 239
174 240 mutex_exit(&s->s_credits_mutex);
175 241 }
|
↓ open down ↓ |
34 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX