1 /*
2 * CDDL HEADER START
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 /*
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2019 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 /*
28 * This module provides the common open functionality to the various
29 * open and create SMB interface functions.
30 */
31
32 #include <sys/types.h>
33 #include <sys/cmn_err.h>
34 #include <sys/fcntl.h>
35 #include <sys/nbmlock.h>
36 #include <smbsrv/string.h>
37 #include <smbsrv/smb_kproto.h>
38 #include <smbsrv/smb_fsops.h>
39 #include <smbsrv/smbinfo.h>
40 #include <smbsrv/smb2_kproto.h>
41
42 int smb_session_ofile_max = 32768;
43
44 extern uint32_t smb_is_executable(char *);
45 static void smb_delete_new_object(smb_request_t *);
46 static int smb_set_open_attributes(smb_request_t *, smb_ofile_t *);
47
48 /*
49 * smb_access_generic_to_file
50 *
51 * Search MSDN for IoCreateFile to see following mapping.
52 *
53 * GENERIC_READ STANDARD_RIGHTS_READ, FILE_READ_DATA,
54 * FILE_READ_ATTRIBUTES and FILE_READ_EA
55 *
56 * GENERIC_WRITE STANDARD_RIGHTS_WRITE, FILE_WRITE_DATA,
57 * FILE_WRITE_ATTRIBUTES, FILE_WRITE_EA, and FILE_APPEND_DATA
58 *
59 * GENERIC_EXECUTE STANDARD_RIGHTS_EXECUTE, SYNCHRONIZE, and FILE_EXECUTE.
60 */
61 static uint32_t
62 smb_access_generic_to_file(uint32_t desired_access)
63 {
64 uint32_t access = 0;
65
66 if (desired_access & GENERIC_ALL)
67 return (FILE_ALL_ACCESS & ~SYNCHRONIZE);
68
69 if (desired_access & GENERIC_EXECUTE) {
70 desired_access &= ~GENERIC_EXECUTE;
71 access |= (STANDARD_RIGHTS_EXECUTE |
72 SYNCHRONIZE | FILE_EXECUTE);
73 }
74
75 if (desired_access & GENERIC_WRITE) {
76 desired_access &= ~GENERIC_WRITE;
77 access |= (FILE_GENERIC_WRITE & ~SYNCHRONIZE);
78 }
79
80 if (desired_access & GENERIC_READ) {
81 desired_access &= ~GENERIC_READ;
82 access |= FILE_GENERIC_READ;
83 }
84
85 return (access | desired_access);
86 }
87
88 /*
89 * smb_omode_to_amask
90 *
91 * This function converts open modes used by Open and Open AndX
92 * commands to desired access bits used by NT Create AndX command.
93 */
94 uint32_t
95 smb_omode_to_amask(uint32_t desired_access)
96 {
97 switch (desired_access & SMB_DA_ACCESS_MASK) {
98 case SMB_DA_ACCESS_READ:
99 return (FILE_GENERIC_READ);
100
101 case SMB_DA_ACCESS_WRITE:
102 return (FILE_GENERIC_WRITE);
103
104 case SMB_DA_ACCESS_READ_WRITE:
105 return (FILE_GENERIC_READ | FILE_GENERIC_WRITE);
106
107 case SMB_DA_ACCESS_EXECUTE:
108 return (FILE_GENERIC_READ | FILE_GENERIC_EXECUTE);
109
110 default:
111 return (FILE_GENERIC_ALL);
112 }
113 }
114
115 /*
116 * smb_denymode_to_sharemode
117 *
118 * This function converts deny modes used by Open and Open AndX
119 * commands to share access bits used by NT Create AndX command.
120 */
121 uint32_t
122 smb_denymode_to_sharemode(uint32_t desired_access, char *fname)
123 {
124 switch (desired_access & SMB_DA_SHARE_MASK) {
125 case SMB_DA_SHARE_COMPATIBILITY:
126 if (smb_is_executable(fname))
127 return (FILE_SHARE_READ | FILE_SHARE_WRITE);
128
129 return (FILE_SHARE_ALL);
130
131 case SMB_DA_SHARE_EXCLUSIVE:
132 return (FILE_SHARE_NONE);
133
134 case SMB_DA_SHARE_DENY_WRITE:
135 return (FILE_SHARE_READ);
136
137 case SMB_DA_SHARE_DENY_READ:
138 return (FILE_SHARE_WRITE);
139
140 case SMB_DA_SHARE_DENY_NONE:
141 default:
142 return (FILE_SHARE_READ | FILE_SHARE_WRITE);
143 }
144 }
145
146 /*
147 * smb_ofun_to_crdisposition
148 *
149 * This function converts open function values used by Open and Open AndX
150 * commands to create disposition values used by NT Create AndX command.
151 */
152 uint32_t
153 smb_ofun_to_crdisposition(uint16_t ofun)
154 {
155 static int ofun_cr_map[3][2] =
156 {
157 { -1, FILE_CREATE },
158 { FILE_OPEN, FILE_OPEN_IF },
159 { FILE_OVERWRITE, FILE_OVERWRITE_IF }
160 };
161
162 int row = ofun & SMB_OFUN_OPEN_MASK;
163 int col = (ofun & SMB_OFUN_CREATE_MASK) >> 4;
164
165 if (row == 3)
166 return (FILE_MAXIMUM_DISPOSITION + 1);
167
168 return (ofun_cr_map[row][col]);
169 }
170
171 /*
172 * smb_common_open
173 *
174 * Notes on write-through behaviour. It looks like pre-LM0.12 versions
175 * of the protocol specify the write-through mode when a file is opened,
176 * (SmbOpen, SmbOpenAndX) so the write calls (SmbWrite, SmbWriteAndClose,
177 * SmbWriteAndUnlock) don't need to contain a write-through flag.
178 *
179 * With LM0.12, the open calls (SmbCreateAndX, SmbNtTransactCreate)
180 * don't indicate which write-through mode to use. Instead the write
181 * calls (SmbWriteAndX, SmbWriteRaw) specify the mode on a per call
182 * basis.
183 *
184 * We don't care which open call was used to get us here, we just need
185 * to ensure that the write-through mode flag is copied from the open
186 * parameters to the node. We test the omode write-through flag in all
187 * write functions.
188 *
189 * This function returns NT status codes.
190 *
191 * The following rules apply when processing a file open request:
192 *
193 * - Oplocks must be broken prior to share checking as the break may
194 * cause other clients to close the file, which would affect sharing
195 * checks.
196 *
197 * - Share checks must take place prior to access checks for correct
198 * Windows semantics and to prevent unnecessary NFS delegation recalls.
199 *
200 * - Oplocks must be acquired after open to ensure the correct
201 * synchronization with NFS delegation and FEM installation.
202 *
203 * DOS readonly bit rules
204 *
205 * 1. The creator of a readonly file can write to/modify the size of the file
206 * using the original create fid, even though the file will appear as readonly
207 * to all other fids and via a CIFS getattr call.
208 *
209 * 2. A setinfo operation (using either an open fid or a path) to set/unset
210 * readonly will be successful regardless of whether a creator of a readonly
211 * file has an open fid.
212 *
213 * 3. The DOS readonly bit affects only data and some metadata.
214 * The following metadata can be changed regardless of the readonly bit:
215 * - security descriptors
216 * - DOS attributes
217 * - timestamps
218 *
219 * In the current implementation, the file size cannot be changed (except for
220 * the exceptions in #1 and #2, above).
221 *
222 *
223 * DOS attribute rules
224 *
225 * These rules are specific to creating / opening files and directories.
226 * How the attribute value (specifically ZERO or FILE_ATTRIBUTE_NORMAL)
227 * should be interpreted may differ in other requests.
228 *
229 * - An attribute value equal to ZERO or FILE_ATTRIBUTE_NORMAL means that the
230 * file's attributes should be cleared.
231 * - If FILE_ATTRIBUTE_NORMAL is specified with any other attributes,
232 * FILE_ATTRIBUTE_NORMAL is ignored.
233 *
234 * 1. Creating a new file
235 * - The request attributes + FILE_ATTRIBUTE_ARCHIVE are applied to the file.
236 *
237 * 2. Creating a new directory
238 * - The request attributes + FILE_ATTRIBUTE_DIRECTORY are applied to the file.
239 * - FILE_ATTRIBUTE_ARCHIVE does not get set.
240 *
241 * 3. Overwriting an existing file
242 * - the request attributes are used as search attributes. If the existing
243 * file does not meet the search criteria access is denied.
244 * - otherwise, applies attributes + FILE_ATTRIBUTE_ARCHIVE.
245 *
246 * 4. Opening an existing file or directory
247 * The request attributes are ignored.
248 */
249 uint32_t
250 smb_common_open(smb_request_t *sr)
251 {
252 smb_server_t *sv = sr->sr_server;
253 smb_tree_t *tree = sr->tid_tree;
254 smb_node_t *fnode = NULL;
255 smb_node_t *dnode = NULL;
256 smb_node_t *cur_node = NULL;
257 smb_node_t *tmp_node = NULL;
258 smb_arg_open_t *op = &sr->sr_open;
259 smb_pathname_t *pn = &op->fqi.fq_path;
260 smb_ofile_t *of = NULL;
261 smb_attr_t new_attr;
262 hrtime_t shrlock_t0;
263 int max_requested = 0;
264 uint32_t max_allowed;
265 uint32_t status = NT_STATUS_SUCCESS;
266 int is_dir;
267 int rc;
268 boolean_t is_stream = B_FALSE;
269 int lookup_flags = SMB_FOLLOW_LINKS;
270 uint32_t uniq_fid = 0;
271 uint16_t tree_fid = 0;
272 boolean_t created = B_FALSE;
273 boolean_t last_comp_found = B_FALSE;
274 boolean_t stream_found = B_FALSE;
275 boolean_t opening_incr = B_FALSE;
276 boolean_t dnode_held = B_FALSE;
277 boolean_t dnode_wlock = B_FALSE;
278 boolean_t fnode_held = B_FALSE;
279 boolean_t fnode_wlock = B_FALSE;
280 boolean_t fnode_shrlk = B_FALSE;
281 boolean_t did_open = B_FALSE;
282 boolean_t did_break_handle = B_FALSE;
283 boolean_t did_cleanup_orphans = B_FALSE;
284 char *sname = NULL;
285 boolean_t do_audit = B_FALSE;
286
287 /* Get out now if we've been cancelled. */
288 mutex_enter(&sr->sr_mutex);
289 if (sr->sr_state != SMB_REQ_STATE_ACTIVE) {
290 mutex_exit(&sr->sr_mutex);
291 return (NT_STATUS_CANCELLED);
292 }
293 mutex_exit(&sr->sr_mutex);
294
295 is_dir = (op->create_options & FILE_DIRECTORY_FILE) ? 1 : 0;
296
297 /*
298 * If the object being created or opened is a directory
299 * the Disposition parameter must be one of FILE_CREATE,
300 * FILE_OPEN, or FILE_OPEN_IF
301 */
302 if (is_dir) {
303 if ((op->create_disposition != FILE_CREATE) &&
304 (op->create_disposition != FILE_OPEN_IF) &&
305 (op->create_disposition != FILE_OPEN)) {
306 return (NT_STATUS_INVALID_PARAMETER);
307 }
308 }
309
310 if (op->desired_access & MAXIMUM_ALLOWED) {
311 max_requested = 1;
312 op->desired_access &= ~MAXIMUM_ALLOWED;
313 }
314 op->desired_access = smb_access_generic_to_file(op->desired_access);
315
316 if (sr->session->s_file_cnt >= smb_session_ofile_max) {
317 ASSERT(sr->uid_user);
318 cmn_err(CE_NOTE, "smbsrv[%s\\%s]: TOO_MANY_OPENED_FILES",
319 sr->uid_user->u_domain, sr->uid_user->u_name);
320 return (NT_STATUS_TOO_MANY_OPENED_FILES);
321 }
322
323 if (smb_idpool_alloc(&tree->t_fid_pool, &tree_fid))
324 return (NT_STATUS_TOO_MANY_OPENED_FILES);
325
326 /* This must be NULL at this point */
327 sr->fid_ofile = NULL;
328
329 op->devstate = 0;
330
331 switch (sr->tid_tree->t_res_type & STYPE_MASK) {
332 case STYPE_DISKTREE:
333 case STYPE_PRINTQ:
334 break;
335
336 case STYPE_IPC:
337 /*
338 * Security descriptors for pipes are not implemented,
339 * so just setup a reasonable access mask.
340 */
341 op->desired_access = (READ_CONTROL | SYNCHRONIZE |
342 FILE_READ_DATA | FILE_READ_ATTRIBUTES |
343 FILE_WRITE_DATA | FILE_APPEND_DATA);
344
345 /*
346 * Limit the number of open pipe instances.
347 */
348 if ((rc = smb_threshold_enter(&sv->sv_opipe_ct)) != 0) {
349 status = RPC_NT_SERVER_TOO_BUSY;
350 goto errout;
351 }
352
353 /*
354 * Most of IPC open is handled in smb_opipe_open()
355 */
356 op->create_options = 0;
357 of = smb_ofile_alloc(sr, op, NULL, SMB_FTYPE_MESG_PIPE,
358 tree_fid);
359 tree_fid = 0; // given to the ofile
360 status = smb_opipe_open(sr, of);
361 smb_threshold_exit(&sv->sv_opipe_ct);
362 if (status != NT_STATUS_SUCCESS)
363 goto errout;
364 return (NT_STATUS_SUCCESS);
365
366 default:
367 status = NT_STATUS_BAD_DEVICE_TYPE;
368 goto errout;
369 }
370
371 smb_pathname_init(sr, pn, pn->pn_path);
372 if (!smb_pathname_validate(sr, pn)) {
373 status = sr->smb_error.status;
374 goto errout;
375 }
376
377 if (strlen(pn->pn_path) >= SMB_MAXPATHLEN) {
378 status = NT_STATUS_OBJECT_PATH_INVALID;
379 goto errout;
380 }
381
382 if (is_dir) {
383 if (!smb_validate_dirname(sr, pn)) {
384 status = sr->smb_error.status;
385 goto errout;
386 }
387 } else {
388 if (!smb_validate_object_name(sr, pn)) {
389 status = sr->smb_error.status;
390 goto errout;
391 }
392 }
393
394 cur_node = op->fqi.fq_dnode ?
395 op->fqi.fq_dnode : sr->tid_tree->t_snode;
396
397 rc = smb_pathname_reduce(sr, sr->user_cr, pn->pn_path,
398 sr->tid_tree->t_snode, cur_node, &op->fqi.fq_dnode,
399 op->fqi.fq_last_comp);
400 if (rc != 0) {
401 status = smb_errno2status(rc);
402 goto errout;
403 }
404 dnode = op->fqi.fq_dnode;
405 dnode_held = B_TRUE;
406
407 /*
408 * Lock the parent dir node in case another create
409 * request to the same parent directory comes in.
410 * Drop this once either lookup succeeds, or we've
411 * created the object in this directory.
412 */
413 smb_node_wrlock(dnode);
414 dnode_wlock = B_TRUE;
415
416 /*
417 * If the access mask has only DELETE set (ignore
418 * FILE_READ_ATTRIBUTES), then assume that this
419 * is a request to delete the link (if a link)
420 * and do not follow links. Otherwise, follow
421 * the link to the target.
422 */
423 if ((op->desired_access & ~FILE_READ_ATTRIBUTES) == DELETE)
424 lookup_flags &= ~SMB_FOLLOW_LINKS;
425
426 /*
427 * Lookup *just* the file portion of the name.
428 * Returns stream name in sname, which this allocates
429 */
430 rc = smb_fsop_lookup_file(sr, zone_kcred(), lookup_flags,
431 sr->tid_tree->t_snode, op->fqi.fq_dnode, op->fqi.fq_last_comp,
432 &sname, &op->fqi.fq_fnode);
433
434 if (rc == 0) {
435 last_comp_found = B_TRUE;
436 fnode_held = B_TRUE;
437
438 /*
439 * Need the DOS attributes below, where we
440 * check the search attributes (sattr).
441 * Also UID, for owner check below.
442 */
443 op->fqi.fq_fattr.sa_mask = SMB_AT_DOSATTR | SMB_AT_UID;
444 rc = smb_node_getattr(sr, op->fqi.fq_fnode, zone_kcred(),
445 NULL, &op->fqi.fq_fattr);
446 if (rc != 0) {
447 status = NT_STATUS_INTERNAL_ERROR;
448 goto errout;
449 }
450 } else if (rc == ENOENT) {
451 last_comp_found = B_FALSE;
452 op->fqi.fq_fnode = NULL;
453 rc = 0;
454 } else {
455 status = smb_errno2status(rc);
456 goto errout;
457 }
458
459 if (last_comp_found) {
460
461 fnode = op->fqi.fq_fnode;
462 dnode = op->fqi.fq_dnode;
463
464 if (!smb_node_is_file(fnode) &&
465 !smb_node_is_dir(fnode) &&
466 !smb_node_is_symlink(fnode)) {
467 status = NT_STATUS_ACCESS_DENIED;
468 goto errout;
469 }
470
471 /*
472 * Reject this request if either:
473 * - the target IS a directory and the client requires that
474 * it must NOT be (required by Lotus Notes)
475 * - the target is NOT a directory and client requires that
476 * it MUST be.
477 * Streams are never directories.
478 */
479 if (smb_node_is_dir(fnode) && sname == NULL) {
480 if (op->create_options & FILE_NON_DIRECTORY_FILE) {
481 status = NT_STATUS_FILE_IS_A_DIRECTORY;
482 goto errout;
483 }
484 } else {
485 if ((op->create_options & FILE_DIRECTORY_FILE) ||
486 (op->nt_flags & NT_CREATE_FLAG_OPEN_TARGET_DIR)) {
487 status = NT_STATUS_NOT_A_DIRECTORY;
488 goto errout;
489 }
490 }
491
492 /* If we're given a stream name, look it up now */
493 if (sname != NULL) {
494 tmp_node = fnode;
495 rc = smb_fsop_lookup_stream(sr, zone_kcred(),
496 lookup_flags, sr->tid_tree->t_snode, fnode, sname,
497 &fnode);
498 } else {
499 rc = 0;
500 }
501
502 if (rc == 0) { /* Stream Exists (including unnamed stream) */
503 stream_found = B_TRUE;
504 smb_node_unlock(dnode);
505 dnode_wlock = B_FALSE;
506
507 if (tmp_node != NULL)
508 smb_node_release(tmp_node);
509
510 /*
511 * No more open should be accepted when
512 * "Delete on close" flag is set.
513 */
514 if (fnode->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
515 status = NT_STATUS_DELETE_PENDING;
516 goto errout;
517 }
518
519 /*
520 * Specified file already exists
521 * so the operation should fail.
522 */
523 if (op->create_disposition == FILE_CREATE) {
524 status = NT_STATUS_OBJECT_NAME_COLLISION;
525 goto errout;
526 }
527
528 if ((op->create_disposition == FILE_SUPERSEDE) ||
529 (op->create_disposition == FILE_OVERWRITE_IF) ||
530 (op->create_disposition == FILE_OVERWRITE)) {
531
532 if (sname == NULL) {
533 if (!smb_sattr_check(
534 op->fqi.fq_fattr.sa_dosattr,
535 op->dattr)) {
536 status =
537 NT_STATUS_ACCESS_DENIED;
538 goto errout;
539 }
540 op->desired_access |=
541 FILE_WRITE_ATTRIBUTES;
542 }
543
544 if (smb_node_is_dir(fnode)) {
545 status = NT_STATUS_ACCESS_DENIED;
546 goto errout;
547 }
548 }
549
550 /* MS-FSA 2.1.5.1.2 */
551 if (op->create_disposition == FILE_SUPERSEDE)
552 op->desired_access |= DELETE;
553 if ((op->create_disposition == FILE_OVERWRITE_IF) ||
554 (op->create_disposition == FILE_OVERWRITE))
555 op->desired_access |= FILE_WRITE_DATA;
556 } else if (rc == ENOENT) { /* File Exists, but Stream doesn't */
557 if (op->create_disposition == FILE_OPEN ||
558 op->create_disposition == FILE_OVERWRITE) {
559 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
560 goto errout;
561 }
562
563 op->desired_access |= FILE_WRITE_DATA;
564 } else { /* Error looking up stream */
565 status = smb_errno2status(rc);
566 fnode = tmp_node;
567 goto errout;
568 }
569
570 /*
571 * Windows seems to check read-only access before file
572 * sharing check.
573 *
574 * Check to see if the file is currently readonly (regardless
575 * of whether this open will make it readonly).
576 * Readonly is ignored on directories.
577 */
578 if (SMB_PATHFILE_IS_READONLY(sr, fnode) &&
579 !smb_node_is_dir(fnode)) {
580 if (op->desired_access &
581 (FILE_WRITE_DATA | FILE_APPEND_DATA)) {
582 status = NT_STATUS_ACCESS_DENIED;
583 goto errout;
584 }
585 if (op->create_options & FILE_DELETE_ON_CLOSE) {
586 status = NT_STATUS_CANNOT_DELETE;
587 goto errout;
588 }
589 }
590
591 do_audit = smb_audit_init(sr);
592 status = smb_fsop_access(sr, sr->user_cr, fnode,
593 op->desired_access);
594
595 if (max_requested) {
596 smb_fsop_eaccess(sr, sr->user_cr, fnode, &max_allowed);
597 op->desired_access |= max_allowed;
598 }
599
600 if (do_audit) {
601 smb_audit_fini(sr, op->desired_access, fnode,
602 status == NT_STATUS_SUCCESS);
603 }
604
605 if (status != NT_STATUS_SUCCESS)
606 goto errout;
607
608 /*
609 * File owner should always get read control + read attr.
610 */
611 if (crgetuid(sr->user_cr) == op->fqi.fq_fattr.sa_vattr.va_uid)
612 op->desired_access |=
613 (READ_CONTROL | FILE_READ_ATTRIBUTES);
614
615 /*
616 * According to MS "dochelp" mail in Mar 2015, any handle
617 * on which read or write access is granted implicitly
618 * gets "read attributes", even if it was not requested.
619 */
620 if ((op->desired_access & FILE_DATA_ALL) != 0)
621 op->desired_access |= FILE_READ_ATTRIBUTES;
622
623 /* If the stream didn't exist, create it now */
624 if (!stream_found) {
625 smb_node_t *tmp_node = fnode;
626
627 bzero(&new_attr, sizeof (new_attr));
628 new_attr.sa_vattr.va_type = VREG;
629 new_attr.sa_vattr.va_mode = S_IRUSR;
630 new_attr.sa_mask |= SMB_AT_TYPE | SMB_AT_MODE;
631
632 rc = smb_fsop_create_stream(sr, sr->user_cr, dnode,
633 fnode, sname, lookup_flags, &new_attr, &fnode);
634 smb_node_release(tmp_node);
635
636 if (rc != 0) {
637 status = smb_errno2status(rc);
638 fnode_held = B_FALSE;
639 goto errout;
640 }
641 op->action_taken = SMB_OACT_CREATED;
642 created = B_TRUE;
643
644 smb_node_unlock(dnode);
645 dnode_wlock = B_FALSE;
646 }
647
648 /*
649 * Oplock break is done prior to sharing checks as the break
650 * may cause other clients to close the file which would
651 * affect the sharing checks, and may delete the file due to
652 * DELETE_ON_CLOSE. This may block, so set the file opening
653 * count before oplock stuff.
654 *
655 * Need the "proposed" ofile (and it's TargetOplockKey) for
656 * correct oplock break semantics.
657 */
658 of = smb_ofile_alloc(sr, op, fnode, SMB_FTYPE_DISK,
659 tree_fid);
660 tree_fid = 0; // given to the ofile
661 uniq_fid = of->f_uniqid;
662
663 smb_node_inc_opening_count(fnode);
664 opening_incr = B_TRUE;
665
666 if (!stream_found) {
667 /*
668 * Stake our Share Access claim.
669 */
670 smb_node_wrlock(fnode);
671 fnode_wlock = B_TRUE;
672
673 status = smb_fsop_shrlock(sr->user_cr, fnode, uniq_fid,
674 op->desired_access, op->share_access);
675 if (status != 0)
676 goto errout;
677
678 fnode_shrlk = B_TRUE;
679 smb_node_unlock(fnode);
680 fnode_wlock = B_FALSE;
681 goto stream_created;
682 }
683
684 /*
685 * XXX Supposed to do share access checks next.
686 * [MS-FSA] describes that as part of access check:
687 * 2.1.5.1.2.1 Alg... Check Access to an Existing File
688 *
689 * If CreateDisposition is FILE_OPEN or FILE_OPEN_IF:
690 * If Open.Stream.Oplock is not empty and
691 * Open.Stream.Oplock.State contains BATCH_OPLOCK,
692 * the object store MUST check for an oplock
693 * break according to the algorithm in section 2.1.4.12,
694 * with input values as follows:
695 * Open equal to this operation's Open
696 * Oplock equal to Open.Stream.Oplock
697 * Operation equal to "OPEN"
698 * OpParams containing two members:
699 * DesiredAccess, CreateDisposition
700 *
701 * It's not clear how Windows would ask the FS layer if
702 * the file has a BATCH oplock. We'll use a call to the
703 * common oplock code, which calls smb_oplock_break_OPEN
704 * only if the oplock state contains BATCH_OPLOCK.
705 * See: smb_oplock_break_BATCH()
706 *
707 * Also note: There's a nearly identical section in the
708 * spec. at the start of the "else" part of the above
709 * "if (disposition is overwrite, overwrite_if)" so this
710 * section (oplock break, the share mode check, and the
711 * next oplock_break_HANDLE) are all factored out to be
712 * in all cases above that if/else from the spec.
713 */
714 status = smb_oplock_break_BATCH(fnode, of,
715 op->desired_access, op->create_disposition);
716 if (status == NT_STATUS_OPLOCK_BREAK_IN_PROGRESS) {
717 if (sr->session->dialect >= SMB_VERS_2_BASE)
718 (void) smb2sr_go_async(sr);
719 (void) smb_oplock_wait_break(fnode, 0);
720 status = 0;
721 }
722 if (status != NT_STATUS_SUCCESS)
723 goto errout;
724
725 /*
726 * Check for sharing violations, and if any,
727 * do oplock break of handle caching.
728 *
729 * Need node_wrlock during shrlock checks,
730 * and not locked during oplock breaks etc.
731 */
732 shrlock_t0 = gethrtime();
733 shrlock_again:
734 smb_node_wrlock(fnode);
735 fnode_wlock = B_TRUE;
736 status = smb_fsop_shrlock(sr->user_cr, fnode, uniq_fid,
737 op->desired_access, op->share_access);
738 smb_node_unlock(fnode);
739 fnode_wlock = B_FALSE;
740
741 /*
742 * [MS-FSA] "OPEN_BREAK_H"
743 * If the (proposed) new open would violate sharing rules,
744 * indicate an oplock break with OPEN_BREAK_H (to break
745 * handle level caching rights) then try again.
746 */
747 if (status == NT_STATUS_SHARING_VIOLATION &&
748 did_break_handle == B_FALSE) {
749 did_break_handle = B_TRUE;
750
751 status = smb_oplock_break_HANDLE(fnode, of);
752 if (status == NT_STATUS_OPLOCK_BREAK_IN_PROGRESS) {
753 if (sr->session->dialect >= SMB_VERS_2_BASE)
754 (void) smb2sr_go_async(sr);
755 (void) smb_oplock_wait_break(fnode, 0);
756 status = 0;
757 } else {
758 /*
759 * Even when the oplock layer does NOT
760 * give us the special status indicating
761 * we should wait, it may have scheduled
762 * taskq jobs that may close handles.
763 * Give those a chance to run before we
764 * check again for sharing violations.
765 */
766 delay(MSEC_TO_TICK(10));
767 }
768 if (status != NT_STATUS_SUCCESS)
769 goto errout;
770
771 goto shrlock_again;
772 }
773
774 /*
775 * If we still have orphaned durable handles on this file,
776 * let's assume the client has lost interest in those and
777 * close them so they don't cause sharing violations.
778 * See longer comment at smb2_dh_close_my_orphans().
779 */
780 if (status == NT_STATUS_SHARING_VIOLATION &&
781 sr->session->dialect >= SMB_VERS_2_BASE &&
782 did_cleanup_orphans == B_FALSE) {
783
784 did_cleanup_orphans = B_TRUE;
785 smb2_dh_close_my_orphans(sr, of);
786
787 goto shrlock_again;
788 }
789
790 /*
791 * SMB1 expects a 1 sec. delay before returning a
792 * sharing violation error. If breaking oplocks
793 * above took less than a sec, wait some more.
794 * See: smbtorture base.defer_open
795 */
796 if (status == NT_STATUS_SHARING_VIOLATION &&
797 sr->session->dialect < SMB_VERS_2_BASE) {
798 hrtime_t t1 = shrlock_t0 + NANOSEC;
799 hrtime_t now = gethrtime();
800 if (now < t1) {
801 delay(NSEC_TO_TICK_ROUNDUP(t1 - now));
802 }
803 }
804
805 if (status != NT_STATUS_SUCCESS)
806 goto errout;
807 fnode_shrlk = B_TRUE;
808
809 /*
810 * The [MS-FSA] spec. describes this oplock break as
811 * part of the sharing access checks. See:
812 * 2.1.5.1.2.2 Algorithm to Check Sharing Access...
813 * At the end of the share mode tests described there,
814 * if it has not returned "sharing violation", it
815 * specifies a call to the alg. in sec. 2.1.4.12,
816 * that boils down to: smb_oplock_break_OPEN()
817 */
818 status = smb_oplock_break_OPEN(fnode, of,
819 op->desired_access,
820 op->create_disposition);
821 if (status == NT_STATUS_OPLOCK_BREAK_IN_PROGRESS) {
822 if (sr->session->dialect >= SMB_VERS_2_BASE)
823 (void) smb2sr_go_async(sr);
824 (void) smb_oplock_wait_break(fnode, 0);
825 status = 0;
826 }
827 if (status != NT_STATUS_SUCCESS)
828 goto errout;
829
830 if ((fnode->flags & NODE_FLAGS_DELETE_COMMITTED) != 0) {
831 /*
832 * Breaking the oplock caused the file to be deleted,
833 * so let's bail and pretend the file wasn't found.
834 * Have to duplicate much of the logic found a the
835 * "errout" label here.
836 *
837 * This code path is exercised by smbtorture
838 * smb2.durable-open.delete_on_close1
839 */
840 DTRACE_PROBE1(node_deleted, smb_node_t, fnode);
841 smb_ofile_free(of);
842 of = NULL;
843 last_comp_found = B_FALSE;
844
845 /*
846 * Get all the holds and locks into the state
847 * they would have if lookup had failed.
848 */
849 fnode_shrlk = B_FALSE;
850 smb_fsop_unshrlock(sr->user_cr, fnode, uniq_fid);
851
852 opening_incr = B_FALSE;
853 smb_node_dec_opening_count(fnode);
854
855 fnode_held = B_FALSE;
856 smb_node_release(fnode);
857
858 dnode_wlock = B_TRUE;
859 smb_node_wrlock(dnode);
860
861 goto create;
862 }
863
864 /*
865 * Go ahead with modifications as necessary.
866 */
867 switch (op->create_disposition) {
868 case FILE_SUPERSEDE:
869 case FILE_OVERWRITE_IF:
870 case FILE_OVERWRITE:
871 bzero(&new_attr, sizeof (new_attr));
872 if (sname == NULL) {
873 op->dattr |= FILE_ATTRIBUTE_ARCHIVE;
874 /*
875 * Don't apply readonly until
876 * smb_set_open_attributes
877 */
878 if (op->dattr & FILE_ATTRIBUTE_READONLY) {
879 op->dattr &= ~FILE_ATTRIBUTE_READONLY;
880 op->created_readonly = B_TRUE;
881 }
882 new_attr.sa_dosattr = op->dattr;
883 } else {
884 new_attr.sa_dosattr = FILE_ATTRIBUTE_ARCHIVE;
885 }
886
887 /*
888 * Truncate the file data here.
889 * We set alloc_size = op->dsize later,
890 * after we have an ofile. See:
891 * smb_set_open_attributes
892 */
893 new_attr.sa_vattr.va_size = 0;
894 new_attr.sa_mask = SMB_AT_DOSATTR | SMB_AT_SIZE;
895 rc = smb_fsop_setattr(sr, sr->user_cr, fnode,
896 &new_attr);
897 if (rc != 0) {
898 status = smb_errno2status(rc);
899 goto errout;
900 }
901
902 /*
903 * If file is being replaced, remove existing streams
904 */
905 if (SMB_IS_STREAM(fnode) == 0) {
906 status = smb_fsop_remove_streams(sr,
907 sr->user_cr, fnode);
908 if (status != 0)
909 goto errout;
910 }
911
912 op->action_taken = SMB_OACT_TRUNCATED;
913 break;
914
915 default:
916 /*
917 * FILE_OPEN or FILE_OPEN_IF.
918 */
919 /*
920 * Ignore any user-specified alloc_size for
921 * existing files, to avoid truncation in
922 * smb_set_open_attributes
923 */
924 op->dsize = 0L;
925 op->action_taken = SMB_OACT_OPENED;
926 break;
927 }
928 } else {
929 create:
930 /* Last component was not found. */
931 dnode = op->fqi.fq_dnode;
932
933 if (is_dir == 0)
934 is_stream = smb_is_stream_name(pn->pn_path);
935
936 if ((op->create_disposition == FILE_OPEN) ||
937 (op->create_disposition == FILE_OVERWRITE)) {
938 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
939 goto errout;
940 }
941
942 if (pn->pn_fname && smb_is_invalid_filename(pn->pn_fname)) {
943 status = NT_STATUS_OBJECT_NAME_INVALID;
944 goto errout;
945 }
946
947 /*
948 * Don't create in directories marked "Delete on close".
949 */
950 if (dnode->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
951 status = NT_STATUS_DELETE_PENDING;
952 goto errout;
953 }
954
955 /*
956 * Create always sets the DOS attributes, type, and mode
957 * in the if/else below (different for file vs directory).
958 * Don't set the readonly bit until smb_set_open_attributes
959 * or that would prevent this open. Note that op->dattr
960 * needs to be what smb_set_open_attributes will use,
961 * except for the readonly bit.
962 */
963 bzero(&new_attr, sizeof (new_attr));
964 new_attr.sa_mask = SMB_AT_DOSATTR | SMB_AT_TYPE | SMB_AT_MODE;
965 if (op->dattr & FILE_ATTRIBUTE_READONLY) {
966 op->dattr &= ~FILE_ATTRIBUTE_READONLY;
967 op->created_readonly = B_TRUE;
968 }
969
970 /*
971 * SMB create can specify the create time.
972 */
973 if ((op->crtime.tv_sec != 0) &&
974 (op->crtime.tv_sec != UINT_MAX)) {
975 new_attr.sa_mask |= SMB_AT_CRTIME;
976 new_attr.sa_crtime = op->crtime;
977 }
978
979 if (is_dir == 0) {
980 op->dattr |= FILE_ATTRIBUTE_ARCHIVE;
981 new_attr.sa_dosattr = op->dattr;
982 new_attr.sa_vattr.va_type = VREG;
983 if (is_stream)
984 new_attr.sa_vattr.va_mode = S_IRUSR | S_IWUSR;
985 else
986 new_attr.sa_vattr.va_mode =
987 S_IRUSR | S_IRGRP | S_IROTH |
988 S_IWUSR | S_IWGRP | S_IWOTH;
989
990 /*
991 * We set alloc_size = op->dsize later,
992 * (in smb_set_open_attributes) after we
993 * have an ofile on which to save that.
994 *
995 * Legacy Open&X sets size to alloc_size
996 * when creating a new file.
997 */
998 if (sr->smb_com == SMB_COM_OPEN_ANDX) {
999 new_attr.sa_vattr.va_size = op->dsize;
1000 new_attr.sa_mask |= SMB_AT_SIZE;
1001 }
1002
1003 /* auditing handled by fsop layer */
1004 rc = smb_fsop_create(sr, sr->user_cr, dnode,
1005 op->fqi.fq_last_comp, &new_attr, &op->fqi.fq_fnode);
1006 } else {
1007 op->dattr |= FILE_ATTRIBUTE_DIRECTORY;
1008 new_attr.sa_dosattr = op->dattr;
1009 new_attr.sa_vattr.va_type = VDIR;
1010 new_attr.sa_vattr.va_mode = 0777;
1011
1012 /* auditing handled by fsop layer */
1013 rc = smb_fsop_mkdir(sr, sr->user_cr, dnode,
1014 op->fqi.fq_last_comp, &new_attr, &op->fqi.fq_fnode);
1015 }
1016 if (rc != 0) {
1017 status = smb_errno2status(rc);
1018 goto errout;
1019 }
1020
1021 /* Create done. */
1022 smb_node_unlock(dnode);
1023 dnode_wlock = B_FALSE;
1024
1025 created = B_TRUE;
1026 op->action_taken = SMB_OACT_CREATED;
1027
1028 /* Note: hold from create */
1029 fnode = op->fqi.fq_fnode;
1030 fnode_held = B_TRUE;
1031
1032 if (max_requested) {
1033 smb_fsop_eaccess(sr, sr->user_cr, fnode, &max_allowed);
1034 op->desired_access |= max_allowed;
1035 }
1036 /*
1037 * We created this object (we own it) so grant
1038 * read_control + read_attributes on this handle,
1039 * even if that was not requested. This avoids
1040 * unexpected access failures later.
1041 */
1042 op->desired_access |= (READ_CONTROL | FILE_READ_ATTRIBUTES);
1043
1044 /* Allocate the ofile and fill in most of it. */
1045 of = smb_ofile_alloc(sr, op, fnode, SMB_FTYPE_DISK,
1046 tree_fid);
1047 tree_fid = 0; // given to the ofile
1048 uniq_fid = of->f_uniqid;
1049
1050 smb_node_inc_opening_count(fnode);
1051 opening_incr = B_TRUE;
1052
1053 /*
1054 * Share access checks...
1055 */
1056 smb_node_wrlock(fnode);
1057 fnode_wlock = B_TRUE;
1058
1059 status = smb_fsop_shrlock(sr->user_cr, fnode, uniq_fid,
1060 op->desired_access, op->share_access);
1061 if (status != 0)
1062 goto errout;
1063 fnode_shrlk = B_TRUE;
1064
1065 /*
1066 * MS-FSA 2.1.5.1.1
1067 * If the Oplock member of the DirectoryStream in
1068 * Link.ParentFile.StreamList (ParentOplock) is
1069 * not empty ... oplock break on the parent...
1070 * (dnode is the parent directory)
1071 *
1072 * This compares of->ParentOplockKey with each
1073 * oplock of->TargetOplockKey and breaks...
1074 * so it's OK that we're passing an OF that's
1075 * NOT a member of dnode->n_ofile_list
1076 *
1077 * The break never blocks, so ignore the return.
1078 */
1079 (void) smb_oplock_break_PARENT(dnode, of);
1080 }
1081
1082 stream_created:
1083 /*
1084 * We might have blocked in smb_oplock_break_OPEN long enough
1085 * so a tree disconnect might have happened. In that case,
1086 * we would be adding an ofile to a tree that's disconnecting,
1087 * which would interfere with tear-down. If so, error out.
1088 */
1089 if (!smb_tree_is_connected(sr->tid_tree)) {
1090 status = NT_STATUS_INVALID_PARAMETER;
1091 goto errout;
1092 }
1093
1094 /*
1095 * Moved this up from smb_ofile_open()
1096 */
1097 if ((rc = smb_fsop_open(fnode, of->f_mode, of->f_cr)) != 0) {
1098 status = smb_errno2status(rc);
1099 goto errout;
1100 }
1101
1102 /*
1103 * Complete this open (add to ofile lists)
1104 */
1105 smb_ofile_open(sr, op, of);
1106 did_open = B_TRUE;
1107
1108 /*
1109 * This MUST be done after ofile creation, so that explicitly
1110 * set timestamps can be remembered on the ofile, and setting
1111 * the readonly flag won't affect access via this open.
1112 */
1113 if ((rc = smb_set_open_attributes(sr, of)) != 0) {
1114 status = smb_errno2status(rc);
1115 goto errout;
1116 }
1117
1118 /*
1119 * We've already done access checks above,
1120 * and want this call to succeed even when
1121 * !(desired_access & FILE_READ_ATTRIBUTES),
1122 * so pass kcred here.
1123 */
1124 op->fqi.fq_fattr.sa_mask = SMB_AT_ALL;
1125 (void) smb_node_getattr(sr, fnode, zone_kcred(), of,
1126 &op->fqi.fq_fattr);
1127
1128 /*
1129 * Propagate the write-through mode from the open params
1130 * to the node: see the notes in the function header.
1131 * XXX: write_through should be a flag on the ofile.
1132 */
1133 if (sr->sr_cfg->skc_sync_enable ||
1134 (op->create_options & FILE_WRITE_THROUGH))
1135 fnode->flags |= NODE_FLAGS_WRITE_THROUGH;
1136
1137 /*
1138 * Set up the fileid and dosattr in open_param for response
1139 */
1140 op->fileid = op->fqi.fq_fattr.sa_vattr.va_nodeid;
1141 op->dattr = op->fqi.fq_fattr.sa_dosattr;
1142
1143 /*
1144 * Set up the file type in open_param for the response
1145 */
1146 op->ftype = SMB_FTYPE_DISK;
1147 sr->smb_fid = of->f_fid;
1148 sr->fid_ofile = of;
1149
1150 if (smb_node_is_file(fnode)) {
1151 op->dsize = op->fqi.fq_fattr.sa_vattr.va_size;
1152 } else {
1153 /* directory or symlink */
1154 op->dsize = 0;
1155 }
1156
1157 /*
1158 * Note: oplock_acquire happens in callers, because
1159 * how that happens is protocol-specific.
1160 */
1161
1162 if (sname != NULL)
1163 kmem_free(sname, MAXNAMELEN);
1164 if (fnode_wlock)
1165 smb_node_unlock(fnode);
1166 if (opening_incr)
1167 smb_node_dec_opening_count(fnode);
1168 if (fnode_held)
1169 smb_node_release(fnode);
1170 if (dnode_wlock)
1171 smb_node_unlock(dnode);
1172 if (dnode_held)
1173 smb_node_release(dnode);
1174
1175 return (NT_STATUS_SUCCESS);
1176
1177 errout:
1178 if (did_open) {
1179 smb_ofile_close(of, 0);
1180 /* rele via sr->fid_ofile */
1181 } else if (of != NULL) {
1182 /* No other refs possible */
1183 smb_ofile_free(of);
1184 }
1185
1186 if (fnode_shrlk)
1187 smb_fsop_unshrlock(sr->user_cr, fnode, uniq_fid);
1188
1189 if (created) {
1190 /* Try to roll-back create. */
1191 smb_delete_new_object(sr);
1192 }
1193
1194 if (sname != NULL)
1195 kmem_free(sname, MAXNAMELEN);
1196 if (fnode_wlock)
1197 smb_node_unlock(fnode);
1198 if (opening_incr)
1199 smb_node_dec_opening_count(fnode);
1200 if (fnode_held)
1201 smb_node_release(fnode);
1202 if (dnode_wlock)
1203 smb_node_unlock(dnode);
1204 if (dnode_held)
1205 smb_node_release(dnode);
1206
1207 if (tree_fid != 0)
1208 smb_idpool_free(&tree->t_fid_pool, tree_fid);
1209
1210 return (status);
1211 }
1212
1213 /*
1214 * smb_set_open_attributes
1215 *
1216 * Last write time:
1217 * - If the last_write time specified in the open params is not 0 or -1,
1218 * use it as file's mtime. This will be considered an explicitly set
1219 * timestamps, not reset by subsequent writes.
1220 *
1221 * DOS attributes
1222 * - If we created_readonly, we now store the real DOS attributes
1223 * (including the readonly bit) so subsequent opens will see it.
1224 *
1225 * Returns: errno
1226 */
1227 static int
1228 smb_set_open_attributes(smb_request_t *sr, smb_ofile_t *of)
1229 {
1230 smb_attr_t attr;
1231 smb_arg_open_t *op = &sr->sr_open;
1232 smb_node_t *node = of->f_node;
1233 int rc = 0;
1234
1235 bzero(&attr, sizeof (smb_attr_t));
1236
1237 if (op->created_readonly) {
1238 attr.sa_dosattr = op->dattr | FILE_ATTRIBUTE_READONLY;
1239 attr.sa_mask |= SMB_AT_DOSATTR;
1240 }
1241
1242 if (op->dsize != 0) {
1243 attr.sa_allocsz = op->dsize;
1244 attr.sa_mask |= SMB_AT_ALLOCSZ;
1245 }
1246
1247 if ((op->mtime.tv_sec != 0) && (op->mtime.tv_sec != UINT_MAX)) {
1248 attr.sa_vattr.va_mtime = op->mtime;
1249 attr.sa_mask |= SMB_AT_MTIME;
1250 }
1251
1252 /*
1253 * Used to have code here to set mtime, ctime, atime
1254 * when the open op->create_disposition is any of:
1255 * FILE_SUPERSEDE, FILE_OVERWRITE_IF, FILE_OVERWRITE.
1256 * We know that in those cases we will have set the
1257 * file size, in which case the file system will
1258 * update those times, so we don't have to.
1259 *
1260 * However, keep track of the fact that we modified
1261 * the file via this handle, so we can do the evil,
1262 * gratuitious mtime update on close that Windows
1263 * clients expect.
1264 */
1265 if (op->action_taken == SMB_OACT_TRUNCATED)
1266 of->f_written = B_TRUE;
1267
1268 if (attr.sa_mask != 0)
1269 rc = smb_node_setattr(sr, node, of->f_cr, of, &attr);
1270
1271 return (rc);
1272 }
1273
1274 /*
1275 * This function is used to delete a newly created object (file or
1276 * directory) if an error occurs after creation of the object.
1277 */
1278 static void
1279 smb_delete_new_object(smb_request_t *sr)
1280 {
1281 smb_arg_open_t *op = &sr->sr_open;
1282 smb_fqi_t *fqi = &(op->fqi);
1283 uint32_t flags = 0;
1284
1285 if (SMB_TREE_IS_CASEINSENSITIVE(sr))
1286 flags |= SMB_IGNORE_CASE;
1287 if (SMB_TREE_SUPPORTS_CATIA(sr))
1288 flags |= SMB_CATIA;
1289
1290 if (op->create_options & FILE_DIRECTORY_FILE)
1291 (void) smb_fsop_rmdir(sr, sr->user_cr, fqi->fq_dnode,
1292 fqi->fq_last_comp, flags);
1293 else
1294 (void) smb_fsop_remove(sr, sr->user_cr, fqi->fq_dnode,
1295 fqi->fq_last_comp, flags);
1296 }