Print this page
NEX-4324 Should not include $DATA when enumerating streams (try 2)
NEX-3409 SMB2: OSX - cannot display nested folders in finder
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
NEX-2106 SMB2 query_file_info FileAlternateNameInformation fails
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_qinfo_file.c
+++ new/usr/src/uts/common/fs/smbsrv/smb2_qinfo_file.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 2015 Nexenta Systems, Inc. All rights reserved.
14 14 */
15 15
16 16 /*
17 17 * Dispatch function for SMB2_QUERY_INFO
18 18 *
19 19 * [MS-FSCC 2.4] If a file system does not support ...
20 20 * an Information Classs, NT_STATUS_INVALID_PARAMETER...
21 21 */
22 22
23 23 #include <smbsrv/smb2_kproto.h>
24 24 #include <smbsrv/smb_fsops.h>
25 25 #include <smbsrv/ntifs.h>
26 26
27 27 static uint32_t smb2_qif_all(smb_request_t *, smb_queryinfo_t *);
28 28 static uint32_t smb2_qif_basic(smb_request_t *, smb_queryinfo_t *);
29 29 static uint32_t smb2_qif_standard(smb_request_t *, smb_queryinfo_t *);
30 30 static uint32_t smb2_qif_internal(smb_request_t *, smb_queryinfo_t *);
31 31 static uint32_t smb2_qif_ea_size(smb_request_t *, smb_queryinfo_t *);
32 32 static uint32_t smb2_qif_access(smb_request_t *, smb_queryinfo_t *);
33 33 static uint32_t smb2_qif_name(smb_request_t *, smb_queryinfo_t *);
34 34 static uint32_t smb2_qif_position(smb_request_t *, smb_queryinfo_t *);
35 35 static uint32_t smb2_qif_full_ea(smb_request_t *, smb_queryinfo_t *);
36 36 static uint32_t smb2_qif_mode(smb_request_t *, smb_queryinfo_t *);
37 37 static uint32_t smb2_qif_alignment(smb_request_t *, smb_queryinfo_t *);
38 38 static uint32_t smb2_qif_all(smb_request_t *, smb_queryinfo_t *);
39 39 static uint32_t smb2_qif_altname(smb_request_t *, smb_queryinfo_t *);
40 40 static uint32_t smb2_qif_stream(smb_request_t *, smb_queryinfo_t *);
41 41 static uint32_t smb2_qif_pipe(smb_request_t *, smb_queryinfo_t *);
42 42 static uint32_t smb2_qif_pipe_lcl(smb_request_t *, smb_queryinfo_t *);
43 43 static uint32_t smb2_qif_pipe_rem(smb_request_t *, smb_queryinfo_t *);
44 44 static uint32_t smb2_qif_compr(smb_request_t *, smb_queryinfo_t *);
45 45 static uint32_t smb2_qif_opens(smb_request_t *, smb_queryinfo_t *);
46 46 static uint32_t smb2_qif_tags(smb_request_t *, smb_queryinfo_t *);
47 47
48 48
49 49 uint32_t
50 50 smb2_qinfo_file(smb_request_t *sr, smb_queryinfo_t *qi)
51 51 {
52 52 smb_ofile_t *of = sr->fid_ofile;
53 53 uint_t mask = 0;
54 54 boolean_t getstd = B_FALSE;
55 55 boolean_t getname = B_FALSE;
56 56 uint32_t status;
57 57
58 58 /*
59 59 * Which attributes do we need from the FS?
60 60 */
61 61 switch (qi->qi_InfoClass) {
62 62 case FileBasicInformation:
63 63 mask = SMB_AT_BASIC;
64 64 break;
65 65 case FileStandardInformation:
66 66 mask = SMB_AT_STANDARD;
67 67 getstd = B_TRUE;
68 68 break;
69 69 case FileInternalInformation:
70 70 mask = SMB_AT_NODEID;
71 71 break;
72 72 case FileAllInformation:
73 73 mask = SMB_AT_ALL;
74 74 getstd = B_TRUE;
75 75 getname = B_TRUE;
76 76 break;
77 77
78 78 case FileNameInformation:
|
↓ open down ↓ |
55 lines elided |
↑ open up ↑ |
79 79 getname = B_TRUE;
80 80 break;
81 81
82 82 case FileAlternateNameInformation:
83 83 mask = SMB_AT_NODEID;
84 84 getname = B_TRUE;
85 85 break;
86 86
87 87 case FileStreamInformation:
88 88 mask = SMB_AT_STANDARD;
89 + getstd = B_TRUE;
89 90 break;
90 91
91 92 case FileCompressionInformation:
92 93 mask = SMB_AT_SIZE | SMB_AT_ALLOCSZ;
93 94 break;
94 95
95 96 case FileNetworkOpenInformation:
96 97 mask = SMB_AT_BASIC | SMB_AT_STANDARD;
97 98
98 99 default:
99 100 break;
100 101 }
101 102
102 103 qi->qi_attr.sa_mask = mask;
103 104 qi->qi_node = of->f_node;
104 105 if (mask & SMB_AT_ALL) {
105 106 status = smb2_ofile_getattr(sr, of, &qi->qi_attr);
106 107 if (status)
107 108 return (status);
108 109 }
109 110 if (getstd) {
110 111 status = smb2_ofile_getstd(of, qi);
111 112 if (status)
112 113 return (status);
113 114 }
114 115 if (getname) {
115 116 status = smb2_ofile_getname(of, qi);
116 117 if (status)
117 118 return (status);
118 119 }
119 120
120 121 switch (qi->qi_InfoClass) {
121 122 case FileBasicInformation:
122 123 status = smb2_qif_basic(sr, qi);
123 124 break;
124 125 case FileStandardInformation:
125 126 status = smb2_qif_standard(sr, qi);
126 127 break;
127 128 case FileInternalInformation:
128 129 status = smb2_qif_internal(sr, qi);
129 130 break;
130 131 case FileEaInformation:
131 132 status = smb2_qif_ea_size(sr, qi);
132 133 break;
133 134 case FileAccessInformation:
134 135 status = smb2_qif_access(sr, qi);
135 136 break;
136 137 case FileNameInformation:
137 138 status = smb2_qif_name(sr, qi);
138 139 break;
139 140 case FilePositionInformation:
140 141 status = smb2_qif_position(sr, qi);
141 142 break;
142 143 case FileFullEaInformation:
143 144 status = smb2_qif_full_ea(sr, qi);
144 145 break;
145 146 case FileModeInformation:
146 147 status = smb2_qif_mode(sr, qi);
147 148 break;
148 149 case FileAlignmentInformation:
149 150 status = smb2_qif_alignment(sr, qi);
150 151 break;
151 152 case FileAllInformation:
152 153 status = smb2_qif_all(sr, qi);
153 154 break;
154 155 case FileAlternateNameInformation:
155 156 status = smb2_qif_altname(sr, qi);
156 157 break;
157 158 case FileStreamInformation:
158 159 status = smb2_qif_stream(sr, qi);
159 160 break;
160 161 case FilePipeInformation:
161 162 status = smb2_qif_pipe(sr, qi);
162 163 break;
163 164 case FilePipeLocalInformation:
164 165 status = smb2_qif_pipe_lcl(sr, qi);
165 166 break;
166 167 case FilePipeRemoteInformation:
167 168 status = smb2_qif_pipe_rem(sr, qi);
168 169 break;
169 170 case FileCompressionInformation:
170 171 status = smb2_qif_compr(sr, qi);
171 172 break;
172 173 case FileNetworkOpenInformation:
173 174 status = smb2_qif_opens(sr, qi);
174 175 break;
175 176 case FileAttributeTagInformation:
176 177 status = smb2_qif_tags(sr, qi);
177 178 break;
178 179 default:
179 180 status = NT_STATUS_INVALID_INFO_CLASS;
180 181 break;
181 182 }
182 183
183 184 return (status);
184 185 }
185 186
186 187 /*
187 188 * FileAllInformation
188 189 *
189 190 * This returns a concatenation of:
190 191 * FileBasicInformation
191 192 * FileStandardInformation
192 193 * FileInternalInformation
193 194 * FileEaInformation
194 195 * FilePositionInformation
195 196 * FileModeInformation
196 197 * FileAlignmentInformation
197 198 * FileNameInformation
198 199 */
199 200 static uint32_t
200 201 smb2_qif_all(smb_request_t *sr, smb_queryinfo_t *qi)
201 202 {
202 203 uint32_t status;
203 204
204 205 status = smb2_qif_basic(sr, qi);
205 206 if (status)
206 207 return (status);
207 208 status = smb2_qif_standard(sr, qi);
208 209 if (status)
209 210 return (status);
210 211 status = smb2_qif_internal(sr, qi);
211 212 if (status)
212 213 return (status);
213 214 status = smb2_qif_ea_size(sr, qi);
214 215 if (status)
215 216 return (status);
216 217 status = smb2_qif_position(sr, qi);
217 218 if (status)
218 219 return (status);
219 220 status = smb2_qif_mode(sr, qi);
220 221 if (status)
221 222 return (status);
222 223 status = smb2_qif_alignment(sr, qi);
223 224 if (status)
224 225 return (status);
225 226 status = smb2_qif_name(sr, qi);
226 227 if (status)
227 228 return (status);
228 229
229 230 return (0);
230 231 }
231 232
232 233 /*
233 234 * FileBasicInformation
234 235 * See also:
235 236 * case SMB_QUERY_FILE_BASIC_INFO:
236 237 * case SMB_FILE_BASIC_INFORMATION:
237 238 */
238 239 static uint32_t
239 240 smb2_qif_basic(smb_request_t *sr, smb_queryinfo_t *qi)
240 241 {
241 242 smb_attr_t *sa = &qi->qi_attr;
242 243
243 244 ASSERT((sa->sa_mask & SMB_AT_BASIC) == SMB_AT_BASIC);
244 245
245 246 (void) smb_mbc_encodef(
246 247 &sr->raw_data, "TTTTll",
247 248 &sa->sa_crtime, /* T */
248 249 &sa->sa_vattr.va_atime, /* T */
249 250 &sa->sa_vattr.va_mtime, /* T */
250 251 &sa->sa_vattr.va_ctime, /* T */
251 252 sa->sa_dosattr, /* l */
252 253 0); /* reserved */ /* l */
253 254
254 255 return (0);
255 256 }
256 257
257 258 /*
258 259 * FileStandardInformation
259 260 * See also:
260 261 * SMB_QUERY_FILE_STANDARD_INFO
261 262 * SMB_FILE_STANDARD_INFORMATION
262 263 */
263 264 static uint32_t
264 265 smb2_qif_standard(smb_request_t *sr, smb_queryinfo_t *qi)
265 266 {
266 267 smb_attr_t *sa = &qi->qi_attr;
267 268
268 269 ASSERT((sa->sa_mask & SMB_AT_STANDARD) == SMB_AT_STANDARD);
269 270
270 271 (void) smb_mbc_encodef(
271 272 &sr->raw_data, "qqlbbw",
272 273 sa->sa_allocsz, /* q */
273 274 sa->sa_vattr.va_size, /* q */
274 275 sa->sa_vattr.va_nlink, /* l */
275 276 qi->qi_delete_on_close, /* b */
276 277 qi->qi_isdir, /* b */
277 278 0); /* reserved */ /* w */
278 279
279 280 return (0);
280 281 }
|
↓ open down ↓ |
182 lines elided |
↑ open up ↑ |
281 282
282 283 /*
283 284 * FileInternalInformation
284 285 * See also:
285 286 * SMB_FILE_INTERNAL_INFORMATION
286 287 */
287 288 static uint32_t
288 289 smb2_qif_internal(smb_request_t *sr, smb_queryinfo_t *qi)
289 290 {
290 291 smb_attr_t *sa = &qi->qi_attr;
292 + u_longlong_t nodeid;
291 293
292 294 ASSERT((sa->sa_mask & SMB_AT_NODEID) == SMB_AT_NODEID);
295 + nodeid = sa->sa_vattr.va_nodeid;
293 296
297 + if (smb2_aapl_use_file_ids == 0 &&
298 + (sr->session->s_flags & SMB_SSN_AAPL_CCEXT) != 0)
299 + nodeid = 0;
300 +
294 301 (void) smb_mbc_encodef(
295 302 &sr->raw_data, "q",
296 - sa->sa_vattr.va_nodeid); /* q */
303 + nodeid); /* q */
297 304
298 305 return (0);
299 306 }
300 307
301 308 /*
302 309 * FileEaInformation
303 310 * See also:
304 311 * SMB_QUERY_FILE_EA_INFO
305 312 * SMB_FILE_EA_INFORMATION
306 313 */
307 314 static uint32_t
308 315 smb2_qif_ea_size(smb_request_t *sr, smb_queryinfo_t *qi)
309 316 {
310 317 _NOTE(ARGUNUSED(qi))
311 318
312 319 (void) smb_mbc_encodef(
313 320 &sr->raw_data, "l", 0);
314 321
315 322 return (0);
316 323 }
317 324
318 325 /*
319 326 * FileFullEaInformation
320 327 * We could put EAs in a named stream...
321 328 */
322 329 /* ARGSUSED */
323 330 static uint32_t
324 331 smb2_qif_full_ea(smb_request_t *sr, smb_queryinfo_t *qi)
325 332 {
326 333 return (NT_STATUS_NO_EAS_ON_FILE);
327 334 }
328 335
329 336 /*
330 337 * FileAccessInformation
331 338 */
332 339 static uint32_t
333 340 smb2_qif_access(smb_request_t *sr, smb_queryinfo_t *qi)
334 341 {
335 342 _NOTE(ARGUNUSED(qi))
336 343 smb_ofile_t *of = sr->fid_ofile;
337 344
338 345 (void) smb_mbc_encodef(
339 346 &sr->raw_data, "l",
340 347 of->f_granted_access);
341 348
342 349 return (0);
343 350 }
344 351
345 352 /*
346 353 * FileNameInformation
347 354 * See also:
348 355 * SMB_QUERY_FILE_NAME_INFO
349 356 * SMB_FILE_NAME_INFORMATION
350 357 */
351 358 static uint32_t
352 359 smb2_qif_name(smb_request_t *sr, smb_queryinfo_t *qi)
353 360 {
354 361
355 362 ASSERT(qi->qi_namelen > 0);
356 363
357 364 (void) smb_mbc_encodef(
358 365 &sr->raw_data, "llU",
359 366 0, /* FileIndex (l) */
360 367 qi->qi_namelen, /* l */
361 368 qi->qi_name); /* U */
362 369
363 370 return (0);
364 371 }
365 372
366 373 /*
367 374 * FilePositionInformation
368 375 */
369 376 static uint32_t
370 377 smb2_qif_position(smb_request_t *sr, smb_queryinfo_t *qi)
371 378 {
372 379 _NOTE(ARGUNUSED(qi))
373 380 smb_ofile_t *of = sr->fid_ofile;
374 381 uint64_t pos;
375 382
376 383 mutex_enter(&of->f_mutex);
377 384 pos = of->f_seek_pos;
378 385 mutex_exit(&of->f_mutex);
379 386
380 387 (void) smb_mbc_encodef(
381 388 &sr->raw_data, "q", pos);
382 389
383 390 return (0);
384 391 }
385 392
386 393 /*
387 394 * FileModeInformation [MS-FSA 2.4.24]
388 395 * XXX: These mode flags are supposed to be on the open handle,
389 396 * XXX: or I think so. Not yet... (just put zero for now)
390 397 */
391 398 static uint32_t
392 399 smb2_qif_mode(smb_request_t *sr, smb_queryinfo_t *qi)
393 400 {
394 401 _NOTE(ARGUNUSED(qi))
395 402
396 403 (void) smb_mbc_encodef(
397 404 &sr->raw_data, "l", 0);
398 405
399 406 return (0);
400 407 }
401 408
402 409 /*
403 410 * FileAlignmentInformation
404 411 */
405 412 static uint32_t
406 413 smb2_qif_alignment(smb_request_t *sr, smb_queryinfo_t *qi)
407 414 {
408 415 _NOTE(ARGUNUSED(qi))
409 416
410 417 (void) smb_mbc_encodef(
411 418 &sr->raw_data, "l", 0);
412 419
413 420 return (0);
414 421 }
415 422
416 423 /*
417 424 * FileAlternateNameInformation
418 425 * See also:
419 426 * SMB_QUERY_FILE_ALT_NAME_INFO
420 427 * SMB_FILE_ALT_NAME_INFORMATION
421 428 */
422 429 static uint32_t
423 430 smb2_qif_altname(smb_request_t *sr, smb_queryinfo_t *qi)
424 431 {
425 432 smb_ofile_t *of = sr->fid_ofile;
426 433
427 434 ASSERT(qi->qi_namelen > 0);
428 435 ASSERT(qi->qi_attr.sa_mask & SMB_AT_NODEID);
429 436
430 437 if (of->f_ftype != SMB_FTYPE_DISK)
431 438 return (NT_STATUS_OBJECT_NAME_NOT_FOUND);
432 439 if ((of->f_tree->t_flags & SMB_TREE_SHORTNAMES) == 0)
433 440 return (NT_STATUS_OBJECT_NAME_NOT_FOUND);
434 441
435 442 /* fill in qi->qi_shortname */
436 443 smb_query_shortname(of->f_node, qi);
437 444
438 445 (void) smb_mbc_encodef(
439 446 &sr->raw_data, "%lU", sr,
440 447 smb_wcequiv_strlen(qi->qi_shortname),
441 448 qi->qi_shortname);
442 449
443 450 return (0);
444 451 }
445 452
446 453 /*
447 454 * FileStreamInformation
448 455 */
449 456 static uint32_t
450 457 smb2_qif_stream(smb_request_t *sr, smb_queryinfo_t *qi)
451 458 {
452 459 smb_ofile_t *of = sr->fid_ofile;
453 460 smb_attr_t *attr = &qi->qi_attr;
454 461 uint32_t status;
455 462
456 463 ASSERT((attr->sa_mask & SMB_AT_STANDARD) == SMB_AT_STANDARD);
457 464 if (of->f_ftype != SMB_FTYPE_DISK) {
458 465 (void) smb_mbc_encodef(
459 466 &sr->raw_data, "l", 0);
460 467 return (0);
461 468 }
462 469
463 470 status = smb_query_stream_info(sr, &sr->raw_data, qi);
464 471 return (status);
465 472 }
466 473
467 474 /*
468 475 * FilePipeInformation
469 476 */
470 477 static uint32_t
471 478 smb2_qif_pipe(smb_request_t *sr, smb_queryinfo_t *qi)
472 479 {
473 480 _NOTE(ARGUNUSED(qi))
474 481 smb_ofile_t *of = sr->fid_ofile;
475 482 uint32_t pipe_mode;
476 483 uint32_t nonblock;
477 484
478 485 switch (of->f_ftype) {
479 486 case SMB_FTYPE_BYTE_PIPE:
480 487 pipe_mode = 0; /* FILE_PIPE_BYTE_STREAM_MODE */
481 488 break;
482 489 case SMB_FTYPE_MESG_PIPE:
483 490 pipe_mode = 1; /* FILE_PIPE_MESSAGE_MODE */
484 491 break;
485 492 case SMB_FTYPE_DISK:
486 493 case SMB_FTYPE_PRINTER:
487 494 default:
488 495 return (NT_STATUS_INVALID_PARAMETER);
489 496 }
490 497 nonblock = 0; /* XXX todo: Get this from the pipe handle. */
491 498
492 499 (void) smb_mbc_encodef(
493 500 &sr->raw_data, "ll",
494 501 pipe_mode, nonblock);
495 502
496 503 return (0);
497 504 }
498 505
499 506 /*
500 507 * FilePipeLocalInformation
501 508 */
502 509 /* ARGSUSED */
503 510 static uint32_t
504 511 smb2_qif_pipe_lcl(smb_request_t *sr, smb_queryinfo_t *qi)
505 512 {
506 513 return (NT_STATUS_INVALID_PARAMETER); /* XXX todo */
507 514 }
508 515
509 516 /*
510 517 * FilePipeRemoteInformation
511 518 */
512 519 /* ARGSUSED */
513 520 static uint32_t
514 521 smb2_qif_pipe_rem(smb_request_t *sr, smb_queryinfo_t *qi)
515 522 {
516 523 return (NT_STATUS_INVALID_PARAMETER); /* XXX todo */
517 524 }
518 525
519 526 /*
520 527 * FileCompressionInformation
521 528 * XXX: For now, just say "not compressed".
522 529 */
523 530 static uint32_t
524 531 smb2_qif_compr(smb_request_t *sr, smb_queryinfo_t *qi)
525 532 {
526 533 smb_attr_t *sa = &qi->qi_attr;
527 534 uint16_t CompressionFormat = 0; /* COMPRESSION_FORMAT_NONE */
528 535
529 536 ASSERT(sa->sa_mask & SMB_AT_SIZE);
530 537
531 538 (void) smb_mbc_encodef(
532 539 &sr->raw_data, "qw6.",
533 540 sa->sa_vattr.va_size, /* q */
534 541 CompressionFormat); /* w */
535 542
536 543 return (0);
537 544 }
538 545
539 546 /*
540 547 * FileNetworkOpenInformation
541 548 */
542 549 static uint32_t
543 550 smb2_qif_opens(smb_request_t *sr, smb_queryinfo_t *qi)
544 551 {
545 552 smb_attr_t *sa = &qi->qi_attr;
546 553
547 554 (void) smb_mbc_encodef(
548 555 &sr->raw_data, "TTTTqqll",
549 556 &sa->sa_crtime, /* T */
550 557 &sa->sa_vattr.va_atime, /* T */
551 558 &sa->sa_vattr.va_mtime, /* T */
552 559 &sa->sa_vattr.va_ctime, /* T */
553 560 sa->sa_allocsz, /* q */
554 561 sa->sa_vattr.va_size, /* q */
555 562 sa->sa_dosattr, /* l */
556 563 0); /* reserved */ /* l */
557 564
558 565 return (0);
559 566 }
560 567
561 568 /*
562 569 * FileAttributeTagInformation
563 570 *
564 571 * If dattr includes FILE_ATTRIBUTE_REPARSE_POINT, the
565 572 * second dword should be the reparse tag. Otherwise
566 573 * the tag value should be set to zero.
567 574 * We don't support reparse points, so we set the tag
568 575 * to zero.
569 576 */
570 577 static uint32_t
571 578 smb2_qif_tags(smb_request_t *sr, smb_queryinfo_t *qi)
572 579 {
573 580 _NOTE(ARGUNUSED(qi))
574 581 (void) smb_mbc_encodef(
575 582 &sr->raw_data, "ll", 0, 0);
576 583
577 584 return (0);
578 585 }
|
↓ open down ↓ |
272 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX