Print this page
NEX-15580 SMB tree connect leaks memory
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15580 SMB tree connect leaks memory
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-1643 dtrace provider for smbsrv
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@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-4473 SMB1 tree connect missing some features
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
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-63 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0
re #11974 CIFS Share - Tree connect fails from Windows 7 Clients
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/fs/smbsrv/smb_tree_connect.c
+++ new/usr/src/uts/common/fs/smbsrv/smb_tree_connect.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
|
↓ 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) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 - * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
23 + * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
24 24 */
25 25
26 26 #include <smbsrv/smb_kproto.h>
27 27 #include <smbsrv/smb_share.h>
28 28
29 29 static void
30 30 smb_tcon_puterror(smb_request_t *sr, uint32_t status)
31 31 {
32 32
33 33 switch (status) {
34 34
35 35 case NT_STATUS_BAD_NETWORK_NAME:
36 36 /* Intentional status=0 */
37 37 smbsr_error(sr, 0, ERRSRV, ERRinvnetname);
38 38 break;
39 39
40 40 case NT_STATUS_ACCESS_DENIED:
41 41 smbsr_error(sr, status, ERRSRV, ERRaccess);
42 42 break;
43 43
44 44 case NT_STATUS_BAD_DEVICE_TYPE:
45 45 smbsr_error(sr, status, ERRDOS, ERROR_BAD_DEV_TYPE);
46 46 break;
47 47
48 48 default:
49 49 case NT_STATUS_INTERNAL_ERROR:
50 50 /* Intentional status=0 */
51 51 smbsr_error(sr, 0, ERRSRV, ERRsrverror);
52 52 break;
53 53 }
54 54 }
55 55
56 56 /*
57 57 * SmbTreeConnect: Map a share to a tree and obtain a tree-id (TID).
58 58 *
59 59 * Client Request Description
60 60 * ================================== =================================
61 61 *
62 62 * UCHAR WordCount; Count of parameter words = 0
63 63 * USHORT ByteCount; Count of data bytes; min = 4
64 64 * UCHAR BufferFormat1; 0x04
65 65 * STRING Path[]; Server name and share name
66 66 * UCHAR BufferFormat2; 0x04
67 67 * STRING Password[]; Password
68 68 * UCHAR BufferFormat3; 0x04
69 69 * STRING Service[]; Service name
70 70 *
71 71 * The CIFS server responds with:
72 72 *
73 73 * Server Response Description
74 74 * ================================ =================================
75 75 *
76 76 * UCHAR WordCount; Count of parameter words = 2
77 77 * USHORT MaxBufferSize; Max size message the server handles
78 78 * USHORT Tid; Tree ID
79 79 * USHORT ByteCount; Count of data bytes = 0
80 80 *
81 81 * If the negotiated dialect is MICROSOFT NETWORKS 1.03 or earlier,
82 82 * MaxBufferSize in the response message indicates the maximum size
83 83 * message that the server can handle. The client should not generate
84 84 * messages, nor expect to receive responses, larger than this. This
85 85 * must be constant for a given server. For newer dialects, this field
86 86 * is ignored.
87 87 */
88 88 smb_sdrc_t
89 89 smb_pre_tree_connect(smb_request_t *sr)
90 90 {
91 91 smb_arg_tcon_t *tcon = &sr->sr_tcon;
92 92 int rc;
|
↓ open down ↓ |
59 lines elided |
↑ open up ↑ |
93 93
94 94 /*
95 95 * Perhaps this should be "%A.sA" now that unicode is enabled.
96 96 */
97 97 rc = smbsr_decode_data(sr, "%AAA", sr, &tcon->path,
98 98 &tcon->password, &tcon->service);
99 99
100 100 tcon->flags = 0;
101 101 tcon->optional_support = 0;
102 102
103 - DTRACE_SMB_2(op__TreeConnect__start, smb_request_t *, sr,
104 - smb_arg_tcon_t *, tcon);
103 + DTRACE_SMB_START(op__TreeConnect, smb_request_t *, sr);
105 104
106 105 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
107 106 }
108 107
109 108 void
110 109 smb_post_tree_connect(smb_request_t *sr)
111 110 {
112 - DTRACE_SMB_1(op__TreeConnect__done, smb_request_t *, sr);
111 + DTRACE_SMB_DONE(op__TreeConnect, smb_request_t *, sr);
113 112 }
114 113
115 114 smb_sdrc_t
116 115 smb_com_tree_connect(smb_request_t *sr)
117 116 {
118 117 uint32_t status;
119 118 int rc;
120 119
121 120 status = smb_tree_connect(sr);
122 121 if (status) {
123 122 smb_tcon_puterror(sr, status);
124 123 return (SDRC_ERROR);
125 124 }
126 125
127 126 rc = smbsr_encode_result(sr, 2, 0, "bwww",
128 127 2, /* wct */
129 128 (WORD)smb_maxbufsize, /* MaxBufferSize */
130 129 sr->smb_tid, /* TID */
131 130 0); /* bcc */
132 131
133 132 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
134 133 }
135 134
136 135 /*
137 136 * SmbTreeConnectX: Map a share to a tree and obtain a tree-id (TID).
138 137 *
139 138 * Client Request Description
140 139 * ================================= =================================
141 140 *
142 141 * UCHAR WordCount; Count of parameter words = 4
143 142 * UCHAR AndXCommand; Secondary (X) command; 0xFF = none
144 143 * UCHAR AndXReserved; Reserved (must be 0)
145 144 * USHORT AndXOffset; Offset to next command WordCount
146 145 * USHORT Flags; Additional information
147 146 * bit 0 set = disconnect Tid
148 147 * USHORT PasswordLength; Length of Password[]
149 148 * USHORT ByteCount; Count of data bytes; min = 3
150 149 * UCHAR Password[]; Password
151 150 * STRING Path[]; Server name and share name
152 151 * STRING Service[]; Service name
153 152 *
154 153 * If the negotiated dialect is LANMAN1.0 or later, then it is a protocol
155 154 * violation for the client to send this message prior to a successful
156 155 * SMB_COM_SESSION_SETUP_ANDX, and the server ignores Password.
157 156 *
158 157 * If the negotiated dialect is prior to LANMAN1.0 and the client has not
159 158 * sent a successful SMB_COM_SESSION_SETUP_ANDX request when the tree
160 159 * connect arrives, a user level security mode server must nevertheless
161 160 * validate the client's credentials.
162 161 *
163 162 * Flags (prefix with TREE_CONNECT_ANDX_):
164 163 * ========================== ========================================
165 164 * 0x0001 DISCONECT_TID The tree specified by TID in the SMB header
166 165 * should be disconnected - disconnect errors
167 166 * should be ignored.
168 167 *
169 168 * 0x0004 EXTENDED_SIGNATURES Client request for signing key protection.
170 169 *
171 170 * 0x0008 EXTENDED_RESPONSE Client request for extended information.
172 171 *
173 172 * Path follows UNC style syntax (\\server\share) and indicates the name
174 173 * of the resource to which the client wishes to connect.
175 174 *
176 175 * Because Password may be an authentication response, it is a variable
177 176 * length field with the length specified by PasswordLength. If
178 177 * authentication is not being used, Password should be a null terminated
179 178 * ASCII string with PasswordLength set to the string size including the
180 179 * terminating null.
181 180 *
182 181 * The server can enforce whatever policy it desires to govern share
183 182 * access. Administrative privilege is required for administrative
184 183 * shares (C$, etc.).
185 184 *
186 185 * The Service component indicates the type of resource the client
187 186 * intends to access. Valid values are:
188 187 *
189 188 * Service Description Earliest Dialect Allowed
190 189 * ======== ======================== ================================
191 190 *
192 191 * A: disk share PC NETWORK PROGRAM 1.0
193 192 * LPT1: printer PC NETWORK PROGRAM 1.0
194 193 * IPC named pipe MICROSOFT NETWORKS 3.0
195 194 * COMM communications device MICROSOFT NETWORKS 3.0
196 195 * ????? any type of device MICROSOFT NETWORKS 3.0
197 196 *
198 197 * If the negotiated dialect is earlier than DOS LANMAN2.1, the response to
199 198 * this SMB is:
200 199 *
201 200 * Server Response Description
202 201 * ================================ ===================================
203 202 *
204 203 * UCHAR WordCount; Count of parameter words = 2
205 204 * UCHAR AndXCommand; Secondary (X) command; 0xFF = none
206 205 * UCHAR AndXReserved; Reserved (must be 0)
207 206 * USHORT AndXOffset; Offset to next command WordCount
208 207 * USHORT ByteCount; Count of data bytes; min = 3
209 208 *
210 209 * If the negotiated is DOS LANMAN2.1 or later, the response to this SMB
211 210 * is:
212 211 *
213 212 * Server Response Description
214 213 * ================================ ===================================
215 214 *
216 215 * UCHAR WordCount; Count of parameter words = 3
217 216 * UCHAR AndXCommand; Secondary (X) command; 0xFF = none
218 217 * UCHAR AndXReserved; Reserved (must be 0)
219 218 * USHORT AndXOffset; Offset to next command WordCount
220 219 * USHORT OptionalSupport; Optional support bits
221 220 * USHORT ByteCount; Count of data bytes; min = 3
222 221 * UCHAR Service[]; Service type connected to. Always
223 222 * ANSII.
224 223 * STRING NativeFileSystem[]; Native file system for this tree
225 224 *
226 225 * NativeFileSystem is the name of the filesystem; values to be expected
227 226 * include FAT, NTFS, etc.
228 227 *
229 228 * OptionalSupport:
230 229 * ============================== ==========================
231 230 * 0x0001 SMB_SUPPORT_SEARCH_BITS The server supports the use of Search
232 231 * Attributes in client requests.
233 232 * 0x0002 SMB_SHARE_IS_IN_DFS The share is managed by DFS.
234 233 * 0x000C SMB_CSC_MASK Offline-caching mask - see CSC flags.
235 234 * 0x0010 SMB_UNIQUE_FILE_NAME The server uses long names and does not
236 235 * support short names. Indicator for
237 236 * clients directory/name-space caching.
238 237 * 0x0020 SMB_EXTENDED_SIGNATURES The server will use signing key protection.
239 238 *
240 239 * Client-side caching (offline files):
241 240 * ============================== ==========================
242 241 * 0x0000 SMB_CSC_CACHE_MANUAL_REINT Clients may cache files for offline use
243 242 * but automatic file-by-file reintegration
244 243 * is not allowed.
245 244 * 0x0004 SMB_CSC_CACHE_AUTO_REINT Automatic file-by-file reintegration is
246 245 * allowed.
247 246 * 0x0008 SMB_CSC_CACHE_VDO File opens do not need to be flowed.
248 247 * 0x000C SMB_CSC_CACHE_NONE CSC is disabled for this share.
249 248 *
250 249 * Some servers negotiate "DOS LANMAN2.1" dialect or later and still send
251 250 * the "downlevel" (i.e. wordcount==2) response. Valid AndX following
252 251 * commands are
253 252 *
254 253 * SMB_COM_OPEN SMB_COM_OPEN_ANDX SMB_COM_CREATE
255 254 * SMB_COM_CREATE_NEW SMB_COM_CREATE_DIRECTORY SMB_COM_DELETE
256 255 * SMB_COM_DELETE_DIRECTORY SMB_COM_FIND SMB_COM_COPY
257 256 * SMB_COM_FIND_UNIQUE SMB_COM_RENAME
258 257 * SMB_COM_CHECK_DIRECTORY SMB_COM_QUERY_INFORMATION
259 258 * SMB_COM_GET_PRINT_QUEUE SMB_COM_OPEN_PRINT_FILE
260 259 * SMB_COM_TRANSACTION SMB_COM_NO_ANDX_CMD
261 260 * SMB_COM_SET_INFORMATION SMB_COM_NT_RENAME
262 261 *
263 262 * Errors:
264 263 * ERRDOS/ERRnomem
265 264 * ERRDOS/ERRbadpath
266 265 * ERRDOS/ERRinvdevice
267 266 * ERRSRV/ERRaccess
268 267 * ERRSRV/ERRbadpw
269 268 * ERRSRV/ERRinvnetname
270 269 */
271 270 smb_sdrc_t
272 271 smb_pre_tree_connect_andx(smb_request_t *sr)
273 272 {
274 273 smb_arg_tcon_t *tcon = &sr->sr_tcon;
275 274 uint8_t *pwbuf = NULL;
276 275 uint16_t pwlen = 0;
277 276 int rc;
278 277
279 278 rc = smbsr_decode_vwv(sr, "b.www", &sr->andx_com, &sr->andx_off,
280 279 &tcon->flags, &pwlen);
281 280 if (rc == 0) {
282 281 if (pwlen != 0)
283 282 pwbuf = smb_srm_zalloc(sr, pwlen);
|
↓ open down ↓ |
161 lines elided |
↑ open up ↑ |
284 283
285 284 rc = smbsr_decode_data(sr, "%#cus", sr, pwlen, pwbuf,
286 285 &tcon->path, &tcon->service);
287 286
288 287 tcon->pwdlen = pwlen;
289 288 tcon->password = (char *)pwbuf;
290 289 }
291 290
292 291 tcon->optional_support = 0;
293 292
294 - DTRACE_SMB_2(op__TreeConnectX__start, smb_request_t *, sr,
295 - smb_arg_tcon_t *, tcon);
293 + DTRACE_SMB_START(op__TreeConnectX, smb_request_t *, sr);
296 294
297 295 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
298 296 }
299 297
300 298 void
301 299 smb_post_tree_connect_andx(smb_request_t *sr)
302 300 {
303 - DTRACE_SMB_1(op__TreeConnectX__done, smb_request_t *, sr);
301 + DTRACE_SMB_DONE(op__TreeConnectX, smb_request_t *, sr);
304 302 }
305 303
306 304 smb_sdrc_t
307 305 smb_com_tree_connect_andx(smb_request_t *sr)
308 306 {
309 307 smb_arg_tcon_t *tcon = &sr->sr_tcon;
308 + smb_tree_t *tree;
310 309 char *service;
311 310 uint32_t status;
312 311 int rc;
313 312
313 + if (tcon->flags & SMB_TCONX_DISCONECT_TID) {
314 + tree = smb_session_lookup_tree(sr->session, sr->smb_tid);
315 + if (tree != NULL) {
316 + smb_tree_disconnect(tree, B_TRUE);
317 + smb_session_cancel_requests(sr->session, tree, sr);
318 + }
319 + }
320 +
314 321 status = smb_tree_connect(sr);
315 322 if (status) {
316 323 smb_tcon_puterror(sr, status);
317 324 return (SDRC_ERROR);
318 325 }
326 + tree = sr->tid_tree;
319 327
320 - switch (sr->tid_tree->t_res_type & STYPE_MASK) {
328 + switch (tree->t_res_type & STYPE_MASK) {
321 329 case STYPE_IPC:
322 330 service = "IPC";
323 331 break;
324 332 case STYPE_PRINTQ:
325 333 service = "LPT1:";
326 334 break;
327 335 case STYPE_DISKTREE:
328 336 default:
329 337 service = "A:";
330 338 }
331 339
332 340 if (sr->session->dialect < NT_LM_0_12) {
333 - rc = smbsr_encode_result(sr, 2, VAR_BCC, "bb.wwss",
341 + rc = smbsr_encode_result(sr, 2, VAR_BCC, "bb.ww%ss",
334 342 (char)2, /* wct */
335 343 sr->andx_com,
336 344 VAR_BCC,
337 345 VAR_BCC,
346 + sr,
338 347 service,
339 - sr->tid_tree->t_typename);
340 - } else {
341 - rc = smbsr_encode_result(sr, 3, VAR_BCC, "bb.wwws%u",
348 + tree->t_typename);
349 + } else if ((tcon->flags & SMB_TCONX_EXTENDED_RESPONSE) == 0) {
350 + rc = smbsr_encode_result(sr, 3, VAR_BCC, "bb.www%su",
342 351 (char)3, /* wct */
343 352 sr->andx_com,
344 353 (short)64,
345 354 tcon->optional_support,
346 355 VAR_BCC,
347 - service,
348 356 sr,
349 - sr->tid_tree->t_typename);
357 + service,
358 + tree->t_typename);
359 +
360 + } else {
361 + rc = smbsr_encode_result(sr, 7, VAR_BCC, "bb.wwllw%su",
362 + (char)7, /* wct (b) */
363 + sr->andx_com, /* AndXcmd (b) */
364 + (short)72, /* AndXoff (w) */
365 + tcon->optional_support, /* (w) */
366 + tree->t_access, /* (l) */
367 + 0, /* guest_access (l) */
368 + VAR_BCC, /* (w) */
369 + sr, /* (%) */
370 + service, /* (s) */
371 + tree->t_typename); /* (u) */
350 372 }
351 373
352 374 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
353 375 }
354 376
355 377 /*
356 378 * SmbTreeDisconnect: Disconnect a tree.
357 379 *
358 380 * Note: SDDF_SUPPRESS_UID is set for this operation, which means the sr
359 381 * uid_user field will not be valid on entry to these functions. Do not
360 382 * use it until it is set up in smb_com_tree_disconnect() or the system
361 383 * will panic.
362 384 *
363 385 * Note: there are scenarios in which the client does not send a tree
364 386 * disconnect request, for example, when ERRbaduid is returned from
365 387 * SmbReadX after a user has logged off. Any open files will remain
366 388 * around until the session is destroyed.
367 389 *
368 390 * Client Request Description
369 391 * ================================== =================================
370 392 *
371 393 * UCHAR WordCount; Count of parameter words = 0
372 394 * USHORT ByteCount; Count of data bytes = 0
373 395 *
374 396 * The resource sharing connection identified by Tid in the SMB header is
375 397 * logically disconnected from the server. Tid is invalidated; it will not
376 398 * be recognized if used by the client for subsequent requests. All locks,
377 399 * open files, etc. created on behalf of Tid are released.
378 400 *
379 401 * Server Response Description
380 402 * ================================== =================================
381 403 *
382 404 * UCHAR WordCount; Count of parameter words = 0
383 405 * USHORT ByteCount; Count of data bytes = 0
384 406 *
|
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
385 407 * Errors:
386 408 * ERRSRV/ERRinvnid
387 409 * ERRSRV/ERRbaduid
388 410 */
389 411 smb_sdrc_t
390 412 smb_pre_tree_disconnect(smb_request_t *sr)
391 413 {
392 414 sr->uid_user = smb_session_lookup_uid(sr->session, sr->smb_uid);
393 415 sr->tid_tree = smb_session_lookup_tree(sr->session, sr->smb_tid);
394 416
395 - DTRACE_SMB_1(op__TreeDisconnect__start, smb_request_t *, sr);
417 + DTRACE_SMB_START(op__TreeDisconnect, smb_request_t *, sr);
396 418 return (SDRC_SUCCESS);
397 419 }
398 420
399 421 void
400 422 smb_post_tree_disconnect(smb_request_t *sr)
401 423 {
402 - DTRACE_SMB_1(op__TreeDisconnect__done, smb_request_t *, sr);
424 + DTRACE_SMB_DONE(op__TreeDisconnect, smb_request_t *, sr);
403 425 }
404 426
405 427 /*
406 428 * SmbTreeDisconnect requires a valid UID as well as a valid TID. Some
407 429 * clients logoff a user and then try to disconnect the trees connected
408 430 * by the user who has just been logged off, which would normally fail
409 431 * in the dispatch code with ERRbaduid but, unfortunately, ERRbaduid
410 432 * causes a problem for some of those clients. Windows returns ERRinvnid.
411 433 *
412 434 * To prevent ERRbaduid being returned, the UID and TID are looked up here
413 435 * rather than prior to dispatching SmbTreeDisconnect requests. If either
414 436 * the UID or the TID is invalid, ERRinvnid is returned.
415 437 */
|
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
416 438 smb_sdrc_t
417 439 smb_com_tree_disconnect(smb_request_t *sr)
418 440 {
419 441 if (sr->uid_user == NULL || sr->tid_tree == NULL) {
420 442 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRinvnid);
421 443 return (SDRC_ERROR);
422 444 }
423 445
424 446 sr->user_cr = smb_user_getcred(sr->uid_user);
425 447
426 - smb_session_cancel_requests(sr->session, sr->tid_tree, sr);
427 448 smb_tree_disconnect(sr->tid_tree, B_TRUE);
449 + smb_session_cancel_requests(sr->session, sr->tid_tree, sr);
428 450
429 451 if (smbsr_encode_empty_result(sr))
430 452 return (SDRC_ERROR);
431 453
432 454 return (SDRC_SUCCESS);
433 455 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX