Print this page
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@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-4538 SMB1 create file should support extended_response format (2)
NEX-6116 Failures in smbtorture raw.open
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Include this commit if upstreaming/backporting any of:
NEX-4540 SMB server declines EA support incorrectly
NEX-4239 smbtorture create failures re. allocation size
(illumos) 6398 SMB should support path names longer than 1024
NEX-4538 SMB1 create file should support extended_response format
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
NEX-4239 smbtorture create failures re. allocation size
Reviewed by: Matt Barden <Matt.Barden@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)
re #14152 Race between ipmi_submit_driver_request() and kcs_loop() (sync with illumos fix 3902)
SMB-46 File handle leaks exposed by mtime fixes (rm 7815)
re #7815 SMB server delivers old modification time...
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/fs/smbsrv/smb_open_andx.c
+++ new/usr/src/uts/common/fs/smbsrv/smb_open_andx.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 2015 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 +#include <smbsrv/smb_fsops.h>
27 28 #include <smbsrv/smb_vops.h>
28 29
29 30 int smb_open_dsize_check = 0;
30 31
31 32 /*
32 33 * Client Request Description
33 34 * ================================== =================================
34 35 *
35 36 * UCHAR WordCount; Count of parameter words = 15
36 37 * UCHAR AndXCommand; Secondary (X) command; 0xFF =
37 38 * none
38 39 * UCHAR AndXReserved; Reserved (must be 0)
39 40 * USHORT AndXOffset; Offset to next command WordCount
40 41 * USHORT Flags; Additional information: bit set-
41 42 * 0 - return additional info
42 43 * 1 - exclusive oplock requested
43 44 * 2 - batch oplock requested
44 45 * USHORT DesiredAccess; File open mode
45 46 * USHORT SearchAttributes;
46 47 * USHORT FileAttributes;
47 48 * UTIME CreationTime; Creation timestamp for file if it
48 49 * gets created
49 50 * USHORT OpenFunction; Action to take if file exists
50 51 * ULONG AllocationSize; Bytes to reserve on create or
51 52 * truncate
52 53 * ULONG Reserved[2]; Must be 0
53 54 * USHORT ByteCount; Count of data bytes; min = 1
54 55 * UCHAR BufferFormat 0x04
55 56 * STRING FileName;
56 57 *
57 58 * Server Response Description
58 59 * ================================== =================================
59 60 *
60 61 * UCHAR WordCount; Count of parameter words = 15
61 62 * UCHAR AndXCommand; Secondary (X) command; 0xFF =
62 63 * none
63 64 * UCHAR AndXReserved; Reserved (must be 0)
64 65 * USHORT AndXOffset; Offset to next command WordCount
65 66 * USHORT Fid; File handle
66 67 * USHORT FileAttributes;
67 68 * UTIME LastWriteTime;
68 69 * ULONG DataSize; Current file size
69 70 * USHORT GrantedAccess; Access permissions actually
70 71 * allowed
71 72 * USHORT FileType; Type of file opened
72 73 * USHORT DeviceState; State of the named pipe
73 74 * USHORT Action; Action taken
74 75 * ULONG ServerFid; Server unique file id
75 76 * USHORT Reserved; Reserved (must be 0)
76 77 * USHORT ByteCount; Count of data bytes = 0
77 78 *
78 79 * DesiredAccess describes the access the client desires for the file (see
79 80 * section 3.6 - Access Mode Encoding).
80 81 *
81 82 * OpenFunction specifies the action to be taken depending on whether or
82 83 * not the file exists (see section 3.8 - Open Function Encoding). Action
83 84 *
84 85 * in the response specifies the action as a result of the Open request
85 86 * (see section 3.9 - Open Action Encoding).
86 87 *
87 88 * SearchAttributes indicates the attributes that the file must have to be
88 89 * found while searching to see if it exists. The encoding of this field
89 90 * is described in the "File Attribute Encoding" section elsewhere in this
90 91 * document. If SearchAttributes is zero then only normal files are
91 92 * returned. If the system file, hidden or directory attributes are
92 93 * specified then the search is inclusive -- both the specified type(s) of
93 94 * files and normal files are returned.
94 95 *
95 96 * FileType returns the kind of resource actually opened:
96 97 *
97 98 * Name Value Description
98 99 * ========================== ====== ==================================
99 100 *
100 101 * FileTypeDisk 0 Disk file or directory as defined
101 102 * in the attribute field
102 103 * FileTypeByteModePipe 1 Named pipe in byte mode
103 104 * FileTypeMessageModePipe 2 Named pipe in message mode
104 105 * FileTypePrinter 3 Spooled printer
105 106 * FileTypeUnknown 0xFFFF Unrecognized resource type
106 107 *
107 108 * If bit0 of Flags is clear, the FileAttributes, LastWriteTime, DataSize,
108 109 * FileType, and DeviceState have indeterminate values in the response.
109 110 *
110 111 * This SMB can request an oplock on the opened file. Oplocks are fully
111 112 * described in the "Oplocks" section elsewhere in this document, and there
112 113 * is also discussion of oplocks in the SMB_COM_LOCKING_ANDX SMB
113 114 * description. Bit1 and bit2 of the Flags field are used to request
114 115 * oplocks during open.
115 116 *
116 117 * The following SMBs may follow SMB_COM_OPEN_ANDX:
117 118 *
118 119 * SMB_COM_READ SMB_COM_READ_ANDX
119 120 * SMB_COM_IOCTL
120 121 */
121 122
122 123 /*
123 124 * This message is sent to obtain a file handle for a data file. This
124 125 * returned Fid is used in subsequent client requests such as read, write,
125 126 * close, etc.
126 127 *
127 128 * Client Request Description
128 129 * ================================== =================================
129 130 *
130 131 * UCHAR WordCount; Count of parameter words = 2
131 132 * USHORT DesiredAccess; Mode - read/write/share
132 133 * USHORT SearchAttributes;
133 134 * USHORT ByteCount; Count of data bytes; min = 2
134 135 * UCHAR BufferFormat; 0x04
135 136 * STRING FileName[]; File name
136 137 *
137 138 * FileName is the fully qualified file name, relative to the root of the
138 139 * share specified in the Tid field of the SMB header. If Tid in the SMB
139 140 * header refers to a print share, this SMB creates a new file which will
140 141 * be spooled to the printer when closed. In this case, FileName is
141 142 * ignored.
142 143 *
143 144 * SearchAttributes specifies the type of file desired. The encoding is
144 145 * described in the "File Attribute Encoding" section.
145 146 *
146 147 * DesiredAccess controls the mode under which the file is opened, and the
147 148 * file will be opened only if the client has the appropriate permissions.
148 149 * The encoding of DesiredAccess is discussed in the section entitled
149 150 * "Access Mode Encoding".
150 151 *
151 152 * Server Response Description
152 153 * ================================== =================================
153 154 *
154 155 * UCHAR WordCount; Count of parameter words = 7
155 156 * USHORT Fid; File handle
156 157 * USHORT FileAttributes; Attributes of opened file
157 158 * UTIME LastWriteTime; Time file was last written
158 159 * ULONG DataSize; File size
159 160 * USHORT GrantedAccess; Access allowed
160 161 * USHORT ByteCount; Count of data bytes = 0
161 162 *
162 163 * Fid is the handle value which should be used for subsequent file
163 164 * operations.
164 165 *
165 166 * FileAttributes specifies the type of file obtained. The encoding is
166 167 * described in the "File Attribute Encoding" section.
167 168 *
168 169 * GrantedAccess indicates the access permissions actually allowed, and may
169 170 * have one of the following values:
170 171 *
171 172 * 0 read-only
172 173 * 1 write-only
173 174 * 2 read/write
174 175 *
175 176 * File Handles (Fids) are scoped per client. A Pid may reference any Fid
176 177 * established by itself or any other Pid on the client (so far as the
177 178 * server is concerned). The actual accesses allowed through the Fid
178 179 * depends on the open and deny modes specified when the file was opened
179 180 * (see below).
180 181 *
181 182 * The MS-DOS compatibility mode of file open provides exclusion at the
182 183 * client level. A file open in compatibility mode may be opened (also in
183 184 * compatibility mode) any number of times for any combination of reading
184 185 * and writing (subject to the user's permissions) by any Pid on the same
185 186 * client. If the first client has the file open for writing, then the
186 187 * file may not be opened in any way by any other client. If the first
187 188 * client has the file open only for reading, then other clients may open
188 189 * the file, in compatibility mode, for reading.. The above
189 190 * notwithstanding, if the filename has an extension of .EXE, .DLL, .SYM,
190 191 * or .COM other clients are permitted to open the file regardless of
191 192 * read/write open modes of other compatibility mode opens. However, once
192 193 * multiple clients have the file open for reading, no client is permitted
193 194 * to open the file for writing and no other client may open the file in
194 195 * any mode other than compatibility mode.
195 196 *
196 197 * The other file exclusion modes (Deny read/write, Deny write, Deny read,
197 198 * Deny none) provide exclusion at the file level. A file opened in any
198 199 * "Deny" mode may be opened again only for the accesses allowed by the
199 200 * Deny mode (subject to the user's permissions). This is true regardless
200 201 * of the identity of the second opener -a different client, a Pid from the
201 202 * same client, or the Pid that already has the file open. For example, if
202 203 * a file is open in "Deny write" mode a second open may only obtain read
203 204 * permission to the file.
204 205 *
205 206 * Although Fids are available to all Pids on a client, Pids other than the
206 207 * owner may not have the full access rights specified in the open mode by
207 208 * the Fid's creator. If the open creating the Fid specified a deny mode,
208 209 * then any Pid using the Fid, other than the creating Pid, will have only
209 210 * those access rights determined by "anding" the open mode rights and the
210 211 * deny mode rights, i.e., the deny mode is checked on all file accesses.
211 212 * For example, if a file is opened for Read/Write in Deny write mode, then
212 213 * other clients may only read the file and cannot write; if a file is
213 214 * opened for Read in Deny read mode, then the other clients can neither
214 215 * read nor write the file.
215 216 */
216 217
217 218 smb_sdrc_t
218 219 smb_pre_open(smb_request_t *sr)
|
↓ open down ↓ |
182 lines elided |
↑ open up ↑ |
219 220 {
220 221 struct open_param *op = &sr->arg.open;
221 222 int rc;
222 223
223 224 bzero(op, sizeof (sr->arg.open));
224 225
225 226 rc = smbsr_decode_vwv(sr, "ww", &op->omode, &op->fqi.fq_sattr);
226 227 if (rc == 0)
227 228 rc = smbsr_decode_data(sr, "%S", sr, &op->fqi.fq_path.pn_path);
228 229
229 - DTRACE_SMB_2(op__Open__start, smb_request_t *, sr,
230 - struct open_param *, op);
230 + DTRACE_SMB_START(op__Open, smb_request_t *, sr); /* arg.open */
231 231
232 232 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
233 233 }
234 234
235 235 void
236 236 smb_post_open(smb_request_t *sr)
237 237 {
238 - DTRACE_SMB_1(op__Open__done, smb_request_t *, sr);
238 + DTRACE_SMB_DONE(op__Open, smb_request_t *, sr);
239 239 }
240 240
241 241 smb_sdrc_t
242 242 smb_com_open(smb_request_t *sr)
243 243 {
244 244 struct open_param *op = &sr->arg.open;
245 245 smb_ofile_t *of;
246 - smb_attr_t attr;
246 + uint32_t mtime_sec;
247 247 uint32_t status;
248 248 uint16_t file_attr;
249 249 int rc;
250 250
251 251 op->desired_access = smb_omode_to_amask(op->omode);
252 252 op->share_access = smb_denymode_to_sharemode(op->omode,
253 253 op->fqi.fq_path.pn_path);
254 254 op->crtime.tv_sec = op->crtime.tv_nsec = 0;
255 255 op->create_disposition = FILE_OPEN;
256 256 op->create_options = FILE_NON_DIRECTORY_FILE;
257 257 if (op->omode & SMB_DA_WRITE_THROUGH)
|
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
258 258 op->create_options |= FILE_WRITE_THROUGH;
259 259
260 260 if (sr->smb_flg & SMB_FLAGS_OPLOCK) {
261 261 if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY)
262 262 op->op_oplock_level = SMB_OPLOCK_BATCH;
263 263 else
264 264 op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
265 265 } else {
266 266 op->op_oplock_level = SMB_OPLOCK_NONE;
267 267 }
268 - op->op_oplock_levelII = B_FALSE;
269 268
270 269 if (smb_open_dsize_check && op->dsize > UINT_MAX) {
271 270 smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
272 271 return (SDRC_ERROR);
273 272 }
274 273
274 + /*
275 + * The real open call. Note: this gets attributes into
276 + * op->fqi.fq_fattr (SMB_AT_ALL). We need those below.
277 + */
275 278 status = smb_common_open(sr);
276 279 if (status != NT_STATUS_SUCCESS) {
277 280 smbsr_status(sr, status, 0, 0);
278 281 return (SDRC_ERROR);
279 282 }
283 + if (op->op_oplock_level != SMB_OPLOCK_NONE) {
284 + /* Oplock req. in op->op_oplock_level etc. */
285 + smb1_oplock_acquire(sr, B_FALSE);
286 + }
280 287
281 288 /*
282 289 * NB: after the above smb_common_open() success,
283 290 * we have a handle allocated (sr->fid_ofile).
284 291 * If we don't return success, we must close it.
285 292 */
286 293 of = sr->fid_ofile;
287 294
288 295 if (op->op_oplock_level == SMB_OPLOCK_NONE) {
289 296 sr->smb_flg &=
290 297 ~(SMB_FLAGS_OPLOCK | SMB_FLAGS_OPLOCK_NOTIFY_ANY);
291 298 }
292 299
293 300 file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
294 - bzero(&attr, sizeof (attr));
295 - attr.sa_mask = SMB_AT_MTIME;
296 - rc = smb_node_getattr(sr, of->f_node, of->f_cr, of, &attr);
297 - if (rc != 0) {
298 - smbsr_errno(sr, rc);
299 - goto errout;
300 - }
301 + mtime_sec = smb_time_gmt_to_local(sr,
302 + op->fqi.fq_fattr.sa_vattr.va_mtime.tv_sec);
301 303
302 304 rc = smbsr_encode_result(sr, 7, 0, "bwwllww",
303 305 7,
304 306 sr->smb_fid,
305 307 file_attr,
306 - smb_time_gmt_to_local(sr, attr.sa_vattr.va_mtime.tv_sec),
308 + mtime_sec,
307 309 (uint32_t)op->dsize,
308 310 op->omode,
309 311 (uint16_t)0); /* bcc */
310 312
311 313 if (rc == 0)
312 314 return (SDRC_SUCCESS);
313 315
314 -errout:
315 316 smb_ofile_close(of, 0);
316 317 return (SDRC_ERROR);
317 318 }
318 319
320 +int smb_openx_enable_extended_response = 1;
321 +
319 322 /*
320 323 * smb_pre_open_andx
321 324 * For compatibility with windows servers, the search attributes
322 325 * specified in the request are ignored.
323 326 */
324 327 smb_sdrc_t
325 328 smb_pre_open_andx(smb_request_t *sr)
326 329 {
327 330 struct open_param *op = &sr->arg.open;
328 - uint16_t flags;
331 + uint16_t openx_flags;
329 332 uint32_t alloc_size;
330 333 uint32_t creation_time;
331 334 uint16_t file_attr, sattr;
332 335 int rc;
333 336
334 337 bzero(op, sizeof (sr->arg.open));
335 338
336 339 rc = smbsr_decode_vwv(sr, "b.wwwwwlwll4.", &sr->andx_com,
337 - &sr->andx_off, &flags, &op->omode, &sattr,
340 + &sr->andx_off, &openx_flags, &op->omode, &sattr,
338 341 &file_attr, &creation_time, &op->ofun, &alloc_size, &op->timeo);
339 342
340 343 if (rc == 0) {
341 344 rc = smbsr_decode_data(sr, "%u", sr, &op->fqi.fq_path.pn_path);
342 345
343 346 op->dattr = file_attr;
344 347 op->dsize = alloc_size;
345 348
346 - if (flags & 2)
347 - op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
348 - else if (flags & 4)
349 + /*
350 + * The openx_flags use some "extended" flags that
351 + * happen to match some of the NtCreateX flags.
352 + */
353 + if (openx_flags & NT_CREATE_FLAG_REQUEST_OPBATCH)
349 354 op->op_oplock_level = SMB_OPLOCK_BATCH;
355 + else if (openx_flags & NT_CREATE_FLAG_REQUEST_OPLOCK)
356 + op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
350 357 else
351 358 op->op_oplock_level = SMB_OPLOCK_NONE;
359 + if (openx_flags & NT_CREATE_FLAG_EXTENDED_RESPONSE)
360 + op->nt_flags |= NT_CREATE_FLAG_EXTENDED_RESPONSE;
352 361
353 362 if ((creation_time != 0) && (creation_time != UINT_MAX))
354 363 op->crtime.tv_sec =
355 364 smb_time_local_to_gmt(sr, creation_time);
356 365 op->crtime.tv_nsec = 0;
357 366
358 367 op->create_disposition = smb_ofun_to_crdisposition(op->ofun);
359 368 }
360 369
361 - DTRACE_SMB_2(op__OpenX__start, smb_request_t *, sr,
362 - struct open_param *, op);
370 + DTRACE_SMB_START(op__OpenX, smb_request_t *, sr); /* arg.open */
363 371
364 372 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
365 373 }
366 374
367 375 void
368 376 smb_post_open_andx(smb_request_t *sr)
369 377 {
370 - DTRACE_SMB_1(op__OpenX__done, smb_request_t *, sr);
378 + DTRACE_SMB_DONE(op__OpenX, smb_request_t *, sr);
371 379 }
372 380
373 381 smb_sdrc_t
374 382 smb_com_open_andx(smb_request_t *sr)
375 383 {
376 384 struct open_param *op = &sr->arg.open;
385 + smb_attr_t *ap = &op->fqi.fq_fattr;
377 386 smb_ofile_t *of;
378 387 uint32_t status;
388 + uint32_t mtime_sec;
379 389 uint16_t file_attr;
380 - smb_attr_t attr;
381 390 int rc;
382 391
383 392 op->desired_access = smb_omode_to_amask(op->omode);
384 393 op->share_access = smb_denymode_to_sharemode(op->omode,
385 394 op->fqi.fq_path.pn_path);
386 395
387 396 if (op->create_disposition > FILE_MAXIMUM_DISPOSITION) {
388 397 smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
389 398 return (SDRC_ERROR);
390 399 }
391 400
392 401 op->create_options = FILE_NON_DIRECTORY_FILE;
393 402 if (op->omode & SMB_DA_WRITE_THROUGH)
394 403 op->create_options |= FILE_WRITE_THROUGH;
395 404
396 - op->op_oplock_levelII = B_FALSE;
397 -
398 405 if (smb_open_dsize_check && op->dsize > UINT_MAX) {
399 406 smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
400 407 return (SDRC_ERROR);
401 408 }
402 409
403 410 status = smb_common_open(sr);
404 411 if (status != NT_STATUS_SUCCESS) {
405 412 smbsr_status(sr, status, 0, 0);
406 413 return (SDRC_ERROR);
407 414 }
415 + if (op->op_oplock_level != SMB_OPLOCK_NONE) {
416 + /* Oplock req. in op->op_oplock_level etc. */
417 + smb1_oplock_acquire(sr, B_FALSE);
418 + }
408 419
409 420 /*
410 421 * NB: after the above smb_common_open() success,
411 422 * we have a handle allocated (sr->fid_ofile).
412 423 * If we don't return success, we must close it.
413 424 */
414 425 of = sr->fid_ofile;
415 426
416 427 if (op->op_oplock_level != SMB_OPLOCK_NONE)
417 - op->action_taken |= SMB_OACT_LOCK;
428 + op->action_taken |= SMB_OACT_OPLOCK;
418 429 else
419 - op->action_taken &= ~SMB_OACT_LOCK;
430 + op->action_taken &= ~SMB_OACT_OPLOCK;
420 431
421 432 file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
422 - bzero(&attr, sizeof (attr));
433 + mtime_sec = smb_time_gmt_to_local(sr, ap->sa_vattr.va_mtime.tv_sec);
423 434
424 435 switch (sr->tid_tree->t_res_type & STYPE_MASK) {
425 436 case STYPE_DISKTREE:
426 437 case STYPE_PRINTQ:
427 - attr.sa_mask = SMB_AT_MTIME;
428 - rc = smb_node_getattr(sr, of->f_node, of->f_cr, of, &attr);
429 - if (rc != 0) {
430 - smbsr_errno(sr, rc);
431 - goto errout;
432 - }
433 -
434 - rc = smbsr_encode_result(sr, 15, 0,
435 - "bb.wwwllwwwwl2.w",
436 - 15,
437 - sr->andx_com, VAR_BCC,
438 - sr->smb_fid,
439 - file_attr,
440 - smb_time_gmt_to_local(sr, attr.sa_vattr.va_mtime.tv_sec),
441 - (uint32_t)op->dsize,
442 - op->omode, op->ftype,
443 - op->devstate,
444 - op->action_taken, op->fileid,
445 - 0);
446 438 break;
447 439
448 440 case STYPE_IPC:
449 - rc = smbsr_encode_result(sr, 15, 0,
450 - "bb.wwwllwwwwl2.w",
451 - 15,
452 - sr->andx_com, VAR_BCC,
453 - sr->smb_fid,
454 - file_attr,
455 - 0L,
456 - 0L,
457 - op->omode, op->ftype,
458 - op->devstate,
459 - op->action_taken, op->fileid,
460 - 0);
441 + mtime_sec = 0;
461 442 break;
462 443
463 444 default:
464 445 smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST,
465 446 ERRDOS, ERROR_INVALID_FUNCTION);
466 447 goto errout;
467 448 }
468 449
450 + if ((op->nt_flags & NT_CREATE_FLAG_EXTENDED_RESPONSE) != 0 &&
451 + smb_openx_enable_extended_response != 0) {
452 + uint32_t MaxAccess = 0;
453 + if (of->f_node != NULL) {
454 + smb_fsop_eaccess(sr, of->f_cr, of->f_node, &MaxAccess);
455 + }
456 + MaxAccess |= of->f_granted_access;
457 +
458 + rc = smbsr_encode_result(
459 + sr, 19, 0, "bb.wwwllwwwwl2.llw",
460 + 19, /* word count (b) */
461 + sr->andx_com, /* (b.) */
462 + VAR_BCC, /* andx offset (w) */
463 + sr->smb_fid, /* (w) */
464 + file_attr, /* (w) */
465 + mtime_sec, /* (l) */
466 + (uint32_t)op->dsize, /* (l) */
467 + op->omode, /* (w) */
468 + op->ftype, /* (w) */
469 + op->devstate, /* (w) */
470 + op->action_taken, /* (w) */
471 + 0, /* legacy fileid (l) */
472 + /* reserved (2.) */
473 + MaxAccess, /* (l) */
474 + 0, /* guest access (l) */
475 + 0); /* byte count (w) */
476 +
477 + } else {
478 + rc = smbsr_encode_result(
479 + sr, 15, 0, "bb.wwwllwwwwl2.w",
480 + 15, /* word count (b) */
481 + sr->andx_com, /* (b.) */
482 + VAR_BCC, /* andx offset (w) */
483 + sr->smb_fid, /* (w) */
484 + file_attr, /* (w) */
485 + mtime_sec, /* (l) */
486 + (uint32_t)op->dsize, /* (l) */
487 + op->omode, /* (w) */
488 + op->ftype, /* (w) */
489 + op->devstate, /* (w) */
490 + op->action_taken, /* (w) */
491 + 0, /* legacy fileid (l) */
492 + /* reserved (2.) */
493 + 0); /* byte count (w) */
494 + }
495 +
469 496 if (rc == 0)
470 497 return (SDRC_SUCCESS);
471 498
472 499 errout:
473 500 smb_ofile_close(of, 0);
474 501 return (SDRC_ERROR);
475 502 }
476 503
477 504 smb_sdrc_t
478 505 smb_com_trans2_open2(smb_request_t *sr, smb_xa_t *xa)
479 506 {
480 507 struct open_param *op = &sr->arg.open;
481 508 uint32_t creation_time;
482 509 uint32_t alloc_size;
510 + uint32_t ea_list_size;
483 511 uint16_t flags;
484 512 uint16_t file_attr;
485 513 uint32_t status;
486 514 int rc;
487 515
488 516 bzero(op, sizeof (sr->arg.open));
489 517
490 518 rc = smb_mbc_decodef(&xa->req_param_mb, "%wwwwlwl10.u",
491 519 sr, &flags, &op->omode, &op->fqi.fq_sattr, &file_attr,
492 520 &creation_time, &op->ofun, &alloc_size, &op->fqi.fq_path.pn_path);
493 521 if (rc != 0)
494 522 return (SDRC_ERROR);
495 523
524 + /*
525 + * The data part of this transaction may contain an EA list.
526 + * See: SMB_FEA_LIST ExtendedAttributeList
527 + *
528 + * If we find a non-empty EA list payload, return the special
529 + * error that tells the caller this FS does not suport EAs.
530 + *
531 + * Note: the first word is the size of the whole data segment,
532 + * INCLUDING the size of that length word. That means if
533 + * the length word specifies a size less than four, it's
534 + * invalid (and probably a client trying something fishy).
535 + */
536 + rc = smb_mbc_decodef(&xa->req_data_mb, "l", &ea_list_size);
537 + if (rc == 0 && ea_list_size > 4) {
538 + smbsr_status(sr, NT_STATUS_EAS_NOT_SUPPORTED, 0, 0);
539 + return (SDRC_ERROR);
540 + }
541 +
496 542 if ((creation_time != 0) && (creation_time != UINT_MAX))
497 543 op->crtime.tv_sec = smb_time_local_to_gmt(sr, creation_time);
498 544 op->crtime.tv_nsec = 0;
499 545
500 546 op->dattr = file_attr;
501 547 op->dsize = alloc_size;
502 548 op->create_options = FILE_NON_DIRECTORY_FILE;
503 549
504 550 op->desired_access = smb_omode_to_amask(op->omode);
505 551 op->share_access = smb_denymode_to_sharemode(op->omode,
506 552 op->fqi.fq_path.pn_path);
507 553
508 554 op->create_disposition = smb_ofun_to_crdisposition(op->ofun);
509 555 if (op->create_disposition > FILE_MAXIMUM_DISPOSITION)
510 556 op->create_disposition = FILE_CREATE;
511 557
512 558 if (op->omode & SMB_DA_WRITE_THROUGH)
|
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
513 559 op->create_options |= FILE_WRITE_THROUGH;
514 560
515 561 if (sr->smb_flg & SMB_FLAGS_OPLOCK) {
516 562 if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY)
517 563 op->op_oplock_level = SMB_OPLOCK_BATCH;
518 564 else
519 565 op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
520 566 } else {
521 567 op->op_oplock_level = SMB_OPLOCK_NONE;
522 568 }
523 - op->op_oplock_levelII = B_FALSE;
524 569
525 570 status = smb_common_open(sr);
526 571 if (status != NT_STATUS_SUCCESS) {
527 572 smbsr_status(sr, status, 0, 0);
528 573 return (SDRC_ERROR);
529 574 }
575 + if (op->op_oplock_level != SMB_OPLOCK_NONE) {
576 + /* Oplock req. in op->op_oplock_level etc. */
577 + smb1_oplock_acquire(sr, B_FALSE);
578 + }
530 579
531 580 if (op->op_oplock_level != SMB_OPLOCK_NONE)
532 - op->action_taken |= SMB_OACT_LOCK;
581 + op->action_taken |= SMB_OACT_OPLOCK;
533 582 else
534 - op->action_taken &= ~SMB_OACT_LOCK;
583 + op->action_taken &= ~SMB_OACT_OPLOCK;
535 584
536 585 file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
537 586
538 587 if (STYPE_ISIPC(sr->tid_tree->t_res_type))
539 588 op->dsize = 0;
540 589
541 590 (void) smb_mbc_encodef(&xa->rep_param_mb, "wwllwwwwlwl",
542 591 sr->smb_fid,
543 592 file_attr,
544 593 (uint32_t)0, /* creation time */
545 594 (uint32_t)op->dsize,
546 595 op->omode,
547 596 op->ftype,
548 597 op->devstate,
549 598 op->action_taken,
550 599 op->fileid,
551 600 (uint16_t)0, /* EA error offset */
552 601 (uint32_t)0); /* EA list length */
553 602
554 603 return (SDRC_SUCCESS);
555 604 }
|
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX