3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
24 */
25
26 #include <smbsrv/smb_kproto.h>
27 #include <smbsrv/smb_vops.h>
28
29 int smb_open_dsize_check = 0;
30
31 /*
32 * Client Request Description
33 * ================================== =================================
34 *
35 * UCHAR WordCount; Count of parameter words = 15
36 * UCHAR AndXCommand; Secondary (X) command; 0xFF =
37 * none
38 * UCHAR AndXReserved; Reserved (must be 0)
39 * USHORT AndXOffset; Offset to next command WordCount
40 * USHORT Flags; Additional information: bit set-
41 * 0 - return additional info
42 * 1 - exclusive oplock requested
43 * 2 - batch oplock requested
44 * USHORT DesiredAccess; File open mode
45 * USHORT SearchAttributes;
46 * USHORT FileAttributes;
209 * those access rights determined by "anding" the open mode rights and the
210 * deny mode rights, i.e., the deny mode is checked on all file accesses.
211 * For example, if a file is opened for Read/Write in Deny write mode, then
212 * other clients may only read the file and cannot write; if a file is
213 * opened for Read in Deny read mode, then the other clients can neither
214 * read nor write the file.
215 */
216
217 smb_sdrc_t
218 smb_pre_open(smb_request_t *sr)
219 {
220 struct open_param *op = &sr->arg.open;
221 int rc;
222
223 bzero(op, sizeof (sr->arg.open));
224
225 rc = smbsr_decode_vwv(sr, "ww", &op->omode, &op->fqi.fq_sattr);
226 if (rc == 0)
227 rc = smbsr_decode_data(sr, "%S", sr, &op->fqi.fq_path.pn_path);
228
229 DTRACE_SMB_2(op__Open__start, smb_request_t *, sr,
230 struct open_param *, op);
231
232 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
233 }
234
235 void
236 smb_post_open(smb_request_t *sr)
237 {
238 DTRACE_SMB_1(op__Open__done, smb_request_t *, sr);
239 }
240
241 smb_sdrc_t
242 smb_com_open(smb_request_t *sr)
243 {
244 struct open_param *op = &sr->arg.open;
245 smb_ofile_t *of;
246 smb_attr_t attr;
247 uint32_t status;
248 uint16_t file_attr;
249 int rc;
250
251 op->desired_access = smb_omode_to_amask(op->omode);
252 op->share_access = smb_denymode_to_sharemode(op->omode,
253 op->fqi.fq_path.pn_path);
254 op->crtime.tv_sec = op->crtime.tv_nsec = 0;
255 op->create_disposition = FILE_OPEN;
256 op->create_options = FILE_NON_DIRECTORY_FILE;
257 if (op->omode & SMB_DA_WRITE_THROUGH)
258 op->create_options |= FILE_WRITE_THROUGH;
259
260 if (sr->smb_flg & SMB_FLAGS_OPLOCK) {
261 if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY)
262 op->op_oplock_level = SMB_OPLOCK_BATCH;
263 else
264 op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
265 } else {
266 op->op_oplock_level = SMB_OPLOCK_NONE;
267 }
268 op->op_oplock_levelII = B_FALSE;
269
270 if (smb_open_dsize_check && op->dsize > UINT_MAX) {
271 smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
272 return (SDRC_ERROR);
273 }
274
275 status = smb_common_open(sr);
276 if (status != NT_STATUS_SUCCESS) {
277 smbsr_status(sr, status, 0, 0);
278 return (SDRC_ERROR);
279 }
280
281 /*
282 * NB: after the above smb_common_open() success,
283 * we have a handle allocated (sr->fid_ofile).
284 * If we don't return success, we must close it.
285 */
286 of = sr->fid_ofile;
287
288 if (op->op_oplock_level == SMB_OPLOCK_NONE) {
289 sr->smb_flg &=
290 ~(SMB_FLAGS_OPLOCK | SMB_FLAGS_OPLOCK_NOTIFY_ANY);
291 }
292
293 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
302 rc = smbsr_encode_result(sr, 7, 0, "bwwllww",
303 7,
304 sr->smb_fid,
305 file_attr,
306 smb_time_gmt_to_local(sr, attr.sa_vattr.va_mtime.tv_sec),
307 (uint32_t)op->dsize,
308 op->omode,
309 (uint16_t)0); /* bcc */
310
311 if (rc == 0)
312 return (SDRC_SUCCESS);
313
314 errout:
315 smb_ofile_close(of, 0);
316 return (SDRC_ERROR);
317 }
318
319 /*
320 * smb_pre_open_andx
321 * For compatibility with windows servers, the search attributes
322 * specified in the request are ignored.
323 */
324 smb_sdrc_t
325 smb_pre_open_andx(smb_request_t *sr)
326 {
327 struct open_param *op = &sr->arg.open;
328 uint16_t flags;
329 uint32_t alloc_size;
330 uint32_t creation_time;
331 uint16_t file_attr, sattr;
332 int rc;
333
334 bzero(op, sizeof (sr->arg.open));
335
336 rc = smbsr_decode_vwv(sr, "b.wwwwwlwll4.", &sr->andx_com,
337 &sr->andx_off, &flags, &op->omode, &sattr,
338 &file_attr, &creation_time, &op->ofun, &alloc_size, &op->timeo);
339
340 if (rc == 0) {
341 rc = smbsr_decode_data(sr, "%u", sr, &op->fqi.fq_path.pn_path);
342
343 op->dattr = file_attr;
344 op->dsize = alloc_size;
345
346 if (flags & 2)
347 op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
348 else if (flags & 4)
349 op->op_oplock_level = SMB_OPLOCK_BATCH;
350 else
351 op->op_oplock_level = SMB_OPLOCK_NONE;
352
353 if ((creation_time != 0) && (creation_time != UINT_MAX))
354 op->crtime.tv_sec =
355 smb_time_local_to_gmt(sr, creation_time);
356 op->crtime.tv_nsec = 0;
357
358 op->create_disposition = smb_ofun_to_crdisposition(op->ofun);
359 }
360
361 DTRACE_SMB_2(op__OpenX__start, smb_request_t *, sr,
362 struct open_param *, op);
363
364 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
365 }
366
367 void
368 smb_post_open_andx(smb_request_t *sr)
369 {
370 DTRACE_SMB_1(op__OpenX__done, smb_request_t *, sr);
371 }
372
373 smb_sdrc_t
374 smb_com_open_andx(smb_request_t *sr)
375 {
376 struct open_param *op = &sr->arg.open;
377 smb_ofile_t *of;
378 uint32_t status;
379 uint16_t file_attr;
380 smb_attr_t attr;
381 int rc;
382
383 op->desired_access = smb_omode_to_amask(op->omode);
384 op->share_access = smb_denymode_to_sharemode(op->omode,
385 op->fqi.fq_path.pn_path);
386
387 if (op->create_disposition > FILE_MAXIMUM_DISPOSITION) {
388 smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
389 return (SDRC_ERROR);
390 }
391
392 op->create_options = FILE_NON_DIRECTORY_FILE;
393 if (op->omode & SMB_DA_WRITE_THROUGH)
394 op->create_options |= FILE_WRITE_THROUGH;
395
396 op->op_oplock_levelII = B_FALSE;
397
398 if (smb_open_dsize_check && op->dsize > UINT_MAX) {
399 smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
400 return (SDRC_ERROR);
401 }
402
403 status = smb_common_open(sr);
404 if (status != NT_STATUS_SUCCESS) {
405 smbsr_status(sr, status, 0, 0);
406 return (SDRC_ERROR);
407 }
408
409 /*
410 * NB: after the above smb_common_open() success,
411 * we have a handle allocated (sr->fid_ofile).
412 * If we don't return success, we must close it.
413 */
414 of = sr->fid_ofile;
415
416 if (op->op_oplock_level != SMB_OPLOCK_NONE)
417 op->action_taken |= SMB_OACT_LOCK;
418 else
419 op->action_taken &= ~SMB_OACT_LOCK;
420
421 file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
422 bzero(&attr, sizeof (attr));
423
424 switch (sr->tid_tree->t_res_type & STYPE_MASK) {
425 case STYPE_DISKTREE:
426 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 break;
447
448 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);
461 break;
462
463 default:
464 smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST,
465 ERRDOS, ERROR_INVALID_FUNCTION);
466 goto errout;
467 }
468
469 if (rc == 0)
470 return (SDRC_SUCCESS);
471
472 errout:
473 smb_ofile_close(of, 0);
474 return (SDRC_ERROR);
475 }
476
477 smb_sdrc_t
478 smb_com_trans2_open2(smb_request_t *sr, smb_xa_t *xa)
479 {
480 struct open_param *op = &sr->arg.open;
481 uint32_t creation_time;
482 uint32_t alloc_size;
483 uint16_t flags;
484 uint16_t file_attr;
485 uint32_t status;
486 int rc;
487
488 bzero(op, sizeof (sr->arg.open));
489
490 rc = smb_mbc_decodef(&xa->req_param_mb, "%wwwwlwl10.u",
491 sr, &flags, &op->omode, &op->fqi.fq_sattr, &file_attr,
492 &creation_time, &op->ofun, &alloc_size, &op->fqi.fq_path.pn_path);
493 if (rc != 0)
494 return (SDRC_ERROR);
495
496 if ((creation_time != 0) && (creation_time != UINT_MAX))
497 op->crtime.tv_sec = smb_time_local_to_gmt(sr, creation_time);
498 op->crtime.tv_nsec = 0;
499
500 op->dattr = file_attr;
501 op->dsize = alloc_size;
502 op->create_options = FILE_NON_DIRECTORY_FILE;
503
504 op->desired_access = smb_omode_to_amask(op->omode);
505 op->share_access = smb_denymode_to_sharemode(op->omode,
506 op->fqi.fq_path.pn_path);
507
508 op->create_disposition = smb_ofun_to_crdisposition(op->ofun);
509 if (op->create_disposition > FILE_MAXIMUM_DISPOSITION)
510 op->create_disposition = FILE_CREATE;
511
512 if (op->omode & SMB_DA_WRITE_THROUGH)
513 op->create_options |= FILE_WRITE_THROUGH;
514
515 if (sr->smb_flg & SMB_FLAGS_OPLOCK) {
516 if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY)
517 op->op_oplock_level = SMB_OPLOCK_BATCH;
518 else
519 op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
520 } else {
521 op->op_oplock_level = SMB_OPLOCK_NONE;
522 }
523 op->op_oplock_levelII = B_FALSE;
524
525 status = smb_common_open(sr);
526 if (status != NT_STATUS_SUCCESS) {
527 smbsr_status(sr, status, 0, 0);
528 return (SDRC_ERROR);
529 }
530
531 if (op->op_oplock_level != SMB_OPLOCK_NONE)
532 op->action_taken |= SMB_OACT_LOCK;
533 else
534 op->action_taken &= ~SMB_OACT_LOCK;
535
536 file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
537
538 if (STYPE_ISIPC(sr->tid_tree->t_res_type))
539 op->dsize = 0;
540
541 (void) smb_mbc_encodef(&xa->rep_param_mb, "wwllwwwwlwl",
542 sr->smb_fid,
543 file_attr,
544 (uint32_t)0, /* creation time */
545 (uint32_t)op->dsize,
546 op->omode,
547 op->ftype,
548 op->devstate,
549 op->action_taken,
550 op->fileid,
551 (uint16_t)0, /* EA error offset */
552 (uint32_t)0); /* EA list length */
553
554 return (SDRC_SUCCESS);
|
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
24 */
25
26 #include <smbsrv/smb_kproto.h>
27 #include <smbsrv/smb_fsops.h>
28 #include <smbsrv/smb_vops.h>
29
30 int smb_open_dsize_check = 0;
31
32 /*
33 * Client Request Description
34 * ================================== =================================
35 *
36 * UCHAR WordCount; Count of parameter words = 15
37 * UCHAR AndXCommand; Secondary (X) command; 0xFF =
38 * none
39 * UCHAR AndXReserved; Reserved (must be 0)
40 * USHORT AndXOffset; Offset to next command WordCount
41 * USHORT Flags; Additional information: bit set-
42 * 0 - return additional info
43 * 1 - exclusive oplock requested
44 * 2 - batch oplock requested
45 * USHORT DesiredAccess; File open mode
46 * USHORT SearchAttributes;
47 * USHORT FileAttributes;
210 * those access rights determined by "anding" the open mode rights and the
211 * deny mode rights, i.e., the deny mode is checked on all file accesses.
212 * For example, if a file is opened for Read/Write in Deny write mode, then
213 * other clients may only read the file and cannot write; if a file is
214 * opened for Read in Deny read mode, then the other clients can neither
215 * read nor write the file.
216 */
217
218 smb_sdrc_t
219 smb_pre_open(smb_request_t *sr)
220 {
221 struct open_param *op = &sr->arg.open;
222 int rc;
223
224 bzero(op, sizeof (sr->arg.open));
225
226 rc = smbsr_decode_vwv(sr, "ww", &op->omode, &op->fqi.fq_sattr);
227 if (rc == 0)
228 rc = smbsr_decode_data(sr, "%S", sr, &op->fqi.fq_path.pn_path);
229
230 DTRACE_SMB_START(op__Open, smb_request_t *, sr); /* arg.open */
231
232 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
233 }
234
235 void
236 smb_post_open(smb_request_t *sr)
237 {
238 DTRACE_SMB_DONE(op__Open, smb_request_t *, sr);
239 }
240
241 smb_sdrc_t
242 smb_com_open(smb_request_t *sr)
243 {
244 struct open_param *op = &sr->arg.open;
245 smb_ofile_t *of;
246 uint32_t mtime_sec;
247 uint32_t status;
248 uint16_t file_attr;
249 int rc;
250
251 op->desired_access = smb_omode_to_amask(op->omode);
252 op->share_access = smb_denymode_to_sharemode(op->omode,
253 op->fqi.fq_path.pn_path);
254 op->crtime.tv_sec = op->crtime.tv_nsec = 0;
255 op->create_disposition = FILE_OPEN;
256 op->create_options = FILE_NON_DIRECTORY_FILE;
257 if (op->omode & SMB_DA_WRITE_THROUGH)
258 op->create_options |= FILE_WRITE_THROUGH;
259
260 if (sr->smb_flg & SMB_FLAGS_OPLOCK) {
261 if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY)
262 op->op_oplock_level = SMB_OPLOCK_BATCH;
263 else
264 op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
265 } else {
266 op->op_oplock_level = SMB_OPLOCK_NONE;
267 }
268
269 if (smb_open_dsize_check && op->dsize > UINT_MAX) {
270 smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
271 return (SDRC_ERROR);
272 }
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 */
278 status = smb_common_open(sr);
279 if (status != NT_STATUS_SUCCESS) {
280 smbsr_status(sr, status, 0, 0);
281 return (SDRC_ERROR);
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 }
287
288 /*
289 * NB: after the above smb_common_open() success,
290 * we have a handle allocated (sr->fid_ofile).
291 * If we don't return success, we must close it.
292 */
293 of = sr->fid_ofile;
294
295 if (op->op_oplock_level == SMB_OPLOCK_NONE) {
296 sr->smb_flg &=
297 ~(SMB_FLAGS_OPLOCK | SMB_FLAGS_OPLOCK_NOTIFY_ANY);
298 }
299
300 file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
301 mtime_sec = smb_time_gmt_to_local(sr,
302 op->fqi.fq_fattr.sa_vattr.va_mtime.tv_sec);
303
304 rc = smbsr_encode_result(sr, 7, 0, "bwwllww",
305 7,
306 sr->smb_fid,
307 file_attr,
308 mtime_sec,
309 (uint32_t)op->dsize,
310 op->omode,
311 (uint16_t)0); /* bcc */
312
313 if (rc == 0)
314 return (SDRC_SUCCESS);
315
316 smb_ofile_close(of, 0);
317 return (SDRC_ERROR);
318 }
319
320 int smb_openx_enable_extended_response = 1;
321
322 /*
323 * smb_pre_open_andx
324 * For compatibility with windows servers, the search attributes
325 * specified in the request are ignored.
326 */
327 smb_sdrc_t
328 smb_pre_open_andx(smb_request_t *sr)
329 {
330 struct open_param *op = &sr->arg.open;
331 uint16_t openx_flags;
332 uint32_t alloc_size;
333 uint32_t creation_time;
334 uint16_t file_attr, sattr;
335 int rc;
336
337 bzero(op, sizeof (sr->arg.open));
338
339 rc = smbsr_decode_vwv(sr, "b.wwwwwlwll4.", &sr->andx_com,
340 &sr->andx_off, &openx_flags, &op->omode, &sattr,
341 &file_attr, &creation_time, &op->ofun, &alloc_size, &op->timeo);
342
343 if (rc == 0) {
344 rc = smbsr_decode_data(sr, "%u", sr, &op->fqi.fq_path.pn_path);
345
346 op->dattr = file_attr;
347 op->dsize = alloc_size;
348
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)
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;
357 else
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;
361
362 if ((creation_time != 0) && (creation_time != UINT_MAX))
363 op->crtime.tv_sec =
364 smb_time_local_to_gmt(sr, creation_time);
365 op->crtime.tv_nsec = 0;
366
367 op->create_disposition = smb_ofun_to_crdisposition(op->ofun);
368 }
369
370 DTRACE_SMB_START(op__OpenX, smb_request_t *, sr); /* arg.open */
371
372 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
373 }
374
375 void
376 smb_post_open_andx(smb_request_t *sr)
377 {
378 DTRACE_SMB_DONE(op__OpenX, smb_request_t *, sr);
379 }
380
381 smb_sdrc_t
382 smb_com_open_andx(smb_request_t *sr)
383 {
384 struct open_param *op = &sr->arg.open;
385 smb_attr_t *ap = &op->fqi.fq_fattr;
386 smb_ofile_t *of;
387 uint32_t status;
388 uint32_t mtime_sec;
389 uint16_t file_attr;
390 int rc;
391
392 op->desired_access = smb_omode_to_amask(op->omode);
393 op->share_access = smb_denymode_to_sharemode(op->omode,
394 op->fqi.fq_path.pn_path);
395
396 if (op->create_disposition > FILE_MAXIMUM_DISPOSITION) {
397 smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
398 return (SDRC_ERROR);
399 }
400
401 op->create_options = FILE_NON_DIRECTORY_FILE;
402 if (op->omode & SMB_DA_WRITE_THROUGH)
403 op->create_options |= FILE_WRITE_THROUGH;
404
405 if (smb_open_dsize_check && op->dsize > UINT_MAX) {
406 smbsr_error(sr, 0, ERRDOS, ERRbadaccess);
407 return (SDRC_ERROR);
408 }
409
410 status = smb_common_open(sr);
411 if (status != NT_STATUS_SUCCESS) {
412 smbsr_status(sr, status, 0, 0);
413 return (SDRC_ERROR);
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 }
419
420 /*
421 * NB: after the above smb_common_open() success,
422 * we have a handle allocated (sr->fid_ofile).
423 * If we don't return success, we must close it.
424 */
425 of = sr->fid_ofile;
426
427 if (op->op_oplock_level != SMB_OPLOCK_NONE)
428 op->action_taken |= SMB_OACT_OPLOCK;
429 else
430 op->action_taken &= ~SMB_OACT_OPLOCK;
431
432 file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
433 mtime_sec = smb_time_gmt_to_local(sr, ap->sa_vattr.va_mtime.tv_sec);
434
435 switch (sr->tid_tree->t_res_type & STYPE_MASK) {
436 case STYPE_DISKTREE:
437 case STYPE_PRINTQ:
438 break;
439
440 case STYPE_IPC:
441 mtime_sec = 0;
442 break;
443
444 default:
445 smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST,
446 ERRDOS, ERROR_INVALID_FUNCTION);
447 goto errout;
448 }
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
496 if (rc == 0)
497 return (SDRC_SUCCESS);
498
499 errout:
500 smb_ofile_close(of, 0);
501 return (SDRC_ERROR);
502 }
503
504 smb_sdrc_t
505 smb_com_trans2_open2(smb_request_t *sr, smb_xa_t *xa)
506 {
507 struct open_param *op = &sr->arg.open;
508 uint32_t creation_time;
509 uint32_t alloc_size;
510 uint32_t ea_list_size;
511 uint16_t flags;
512 uint16_t file_attr;
513 uint32_t status;
514 int rc;
515
516 bzero(op, sizeof (sr->arg.open));
517
518 rc = smb_mbc_decodef(&xa->req_param_mb, "%wwwwlwl10.u",
519 sr, &flags, &op->omode, &op->fqi.fq_sattr, &file_attr,
520 &creation_time, &op->ofun, &alloc_size, &op->fqi.fq_path.pn_path);
521 if (rc != 0)
522 return (SDRC_ERROR);
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
542 if ((creation_time != 0) && (creation_time != UINT_MAX))
543 op->crtime.tv_sec = smb_time_local_to_gmt(sr, creation_time);
544 op->crtime.tv_nsec = 0;
545
546 op->dattr = file_attr;
547 op->dsize = alloc_size;
548 op->create_options = FILE_NON_DIRECTORY_FILE;
549
550 op->desired_access = smb_omode_to_amask(op->omode);
551 op->share_access = smb_denymode_to_sharemode(op->omode,
552 op->fqi.fq_path.pn_path);
553
554 op->create_disposition = smb_ofun_to_crdisposition(op->ofun);
555 if (op->create_disposition > FILE_MAXIMUM_DISPOSITION)
556 op->create_disposition = FILE_CREATE;
557
558 if (op->omode & SMB_DA_WRITE_THROUGH)
559 op->create_options |= FILE_WRITE_THROUGH;
560
561 if (sr->smb_flg & SMB_FLAGS_OPLOCK) {
562 if (sr->smb_flg & SMB_FLAGS_OPLOCK_NOTIFY_ANY)
563 op->op_oplock_level = SMB_OPLOCK_BATCH;
564 else
565 op->op_oplock_level = SMB_OPLOCK_EXCLUSIVE;
566 } else {
567 op->op_oplock_level = SMB_OPLOCK_NONE;
568 }
569
570 status = smb_common_open(sr);
571 if (status != NT_STATUS_SUCCESS) {
572 smbsr_status(sr, status, 0, 0);
573 return (SDRC_ERROR);
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 }
579
580 if (op->op_oplock_level != SMB_OPLOCK_NONE)
581 op->action_taken |= SMB_OACT_OPLOCK;
582 else
583 op->action_taken &= ~SMB_OACT_OPLOCK;
584
585 file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
586
587 if (STYPE_ISIPC(sr->tid_tree->t_res_type))
588 op->dsize = 0;
589
590 (void) smb_mbc_encodef(&xa->rep_param_mb, "wwllwwwwlwl",
591 sr->smb_fid,
592 file_attr,
593 (uint32_t)0, /* creation time */
594 (uint32_t)op->dsize,
595 op->omode,
596 op->ftype,
597 op->devstate,
598 op->action_taken,
599 op->fileid,
600 (uint16_t)0, /* EA error offset */
601 (uint32_t)0); /* EA list length */
602
603 return (SDRC_SUCCESS);
|