xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_common_open.c (revision b5b772b09624dfff0e83299d0f7b895129f7bf26)
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 2017 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 
41 int smb_session_ofile_max = 32768;
42 
43 static volatile uint32_t smb_fids = 0;
44 #define	SMB_UNIQ_FID()	atomic_inc_32_nv(&smb_fids)
45 
46 static uint32_t smb_open_subr(smb_request_t *);
47 extern uint32_t smb_is_executable(char *);
48 static void smb_delete_new_object(smb_request_t *);
49 static int smb_set_open_attributes(smb_request_t *, smb_ofile_t *);
50 static void smb_open_oplock_break(smb_request_t *, smb_node_t *);
51 static boolean_t smb_open_attr_only(smb_arg_open_t *);
52 static boolean_t smb_open_overwrite(smb_arg_open_t *);
53 
54 /*
55  * smb_access_generic_to_file
56  *
57  * Search MSDN for IoCreateFile to see following mapping.
58  *
59  * GENERIC_READ		STANDARD_RIGHTS_READ, FILE_READ_DATA,
60  *			FILE_READ_ATTRIBUTES and FILE_READ_EA
61  *
62  * GENERIC_WRITE	STANDARD_RIGHTS_WRITE, FILE_WRITE_DATA,
63  *               FILE_WRITE_ATTRIBUTES, FILE_WRITE_EA, and FILE_APPEND_DATA
64  *
65  * GENERIC_EXECUTE	STANDARD_RIGHTS_EXECUTE, SYNCHRONIZE, and FILE_EXECUTE.
66  */
67 static uint32_t
68 smb_access_generic_to_file(uint32_t desired_access)
69 {
70 	uint32_t access = 0;
71 
72 	if (desired_access & GENERIC_ALL)
73 		return (FILE_ALL_ACCESS & ~SYNCHRONIZE);
74 
75 	if (desired_access & GENERIC_EXECUTE) {
76 		desired_access &= ~GENERIC_EXECUTE;
77 		access |= (STANDARD_RIGHTS_EXECUTE |
78 		    SYNCHRONIZE | FILE_EXECUTE);
79 	}
80 
81 	if (desired_access & GENERIC_WRITE) {
82 		desired_access &= ~GENERIC_WRITE;
83 		access |= (FILE_GENERIC_WRITE & ~SYNCHRONIZE);
84 	}
85 
86 	if (desired_access & GENERIC_READ) {
87 		desired_access &= ~GENERIC_READ;
88 		access |= FILE_GENERIC_READ;
89 	}
90 
91 	return (access | desired_access);
92 }
93 
94 /*
95  * smb_omode_to_amask
96  *
97  * This function converts open modes used by Open and Open AndX
98  * commands to desired access bits used by NT Create AndX command.
99  */
100 uint32_t
101 smb_omode_to_amask(uint32_t desired_access)
102 {
103 	switch (desired_access & SMB_DA_ACCESS_MASK) {
104 	case SMB_DA_ACCESS_READ:
105 		return (FILE_GENERIC_READ);
106 
107 	case SMB_DA_ACCESS_WRITE:
108 		return (FILE_GENERIC_WRITE);
109 
110 	case SMB_DA_ACCESS_READ_WRITE:
111 		return (FILE_GENERIC_READ | FILE_GENERIC_WRITE);
112 
113 	case SMB_DA_ACCESS_EXECUTE:
114 		return (FILE_GENERIC_READ | FILE_GENERIC_EXECUTE);
115 
116 	default:
117 		return (FILE_GENERIC_ALL);
118 	}
119 }
120 
121 /*
122  * smb_denymode_to_sharemode
123  *
124  * This function converts deny modes used by Open and Open AndX
125  * commands to share access bits used by NT Create AndX command.
126  */
127 uint32_t
128 smb_denymode_to_sharemode(uint32_t desired_access, char *fname)
129 {
130 	switch (desired_access & SMB_DA_SHARE_MASK) {
131 	case SMB_DA_SHARE_COMPATIBILITY:
132 		if (smb_is_executable(fname))
133 			return (FILE_SHARE_READ | FILE_SHARE_WRITE);
134 
135 		return (FILE_SHARE_ALL);
136 
137 	case SMB_DA_SHARE_EXCLUSIVE:
138 		return (FILE_SHARE_NONE);
139 
140 	case SMB_DA_SHARE_DENY_WRITE:
141 		return (FILE_SHARE_READ);
142 
143 	case SMB_DA_SHARE_DENY_READ:
144 		return (FILE_SHARE_WRITE);
145 
146 	case SMB_DA_SHARE_DENY_NONE:
147 	default:
148 		return (FILE_SHARE_READ | FILE_SHARE_WRITE);
149 	}
150 }
151 
152 /*
153  * smb_ofun_to_crdisposition
154  *
155  * This function converts open function values used by Open and Open AndX
156  * commands to create disposition values used by NT Create AndX command.
157  */
158 uint32_t
159 smb_ofun_to_crdisposition(uint16_t  ofun)
160 {
161 	static int ofun_cr_map[3][2] =
162 	{
163 		{ -1,			FILE_CREATE },
164 		{ FILE_OPEN,		FILE_OPEN_IF },
165 		{ FILE_OVERWRITE,	FILE_OVERWRITE_IF }
166 	};
167 
168 	int row = ofun & SMB_OFUN_OPEN_MASK;
169 	int col = (ofun & SMB_OFUN_CREATE_MASK) >> 4;
170 
171 	if (row == 3)
172 		return (FILE_MAXIMUM_DISPOSITION + 1);
173 
174 	return (ofun_cr_map[row][col]);
175 }
176 
177 /*
178  * Retry opens to avoid spurious sharing violations, due to timing
179  * issues between closes and opens.  The client that already has the
180  * file open may be in the process of closing it.
181  */
182 uint32_t
183 smb_common_open(smb_request_t *sr)
184 {
185 	smb_arg_open_t	*parg;
186 	uint32_t	status = NT_STATUS_SUCCESS;
187 	int		count;
188 
189 	parg = kmem_alloc(sizeof (*parg), KM_SLEEP);
190 	bcopy(&sr->arg.open, parg, sizeof (*parg));
191 
192 	for (count = 0; count <= 4; count++) {
193 		if (count != 0)
194 			delay(MSEC_TO_TICK(400));
195 
196 		status = smb_open_subr(sr);
197 		if (status != NT_STATUS_SHARING_VIOLATION)
198 			break;
199 
200 		bcopy(parg, &sr->arg.open, sizeof (*parg));
201 	}
202 
203 	if (status == NT_STATUS_NO_SUCH_FILE)
204 		status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
205 
206 	kmem_free(parg, sizeof (*parg));
207 	return (status);
208 }
209 
210 /*
211  * smb_open_subr
212  *
213  * Notes on write-through behaviour. It looks like pre-LM0.12 versions
214  * of the protocol specify the write-through mode when a file is opened,
215  * (SmbOpen, SmbOpenAndX) so the write calls (SmbWrite, SmbWriteAndClose,
216  * SmbWriteAndUnlock) don't need to contain a write-through flag.
217  *
218  * With LM0.12, the open calls (SmbCreateAndX, SmbNtTransactCreate)
219  * don't indicate which write-through mode to use. Instead the write
220  * calls (SmbWriteAndX, SmbWriteRaw) specify the mode on a per call
221  * basis.
222  *
223  * We don't care which open call was used to get us here, we just need
224  * to ensure that the write-through mode flag is copied from the open
225  * parameters to the node. We test the omode write-through flag in all
226  * write functions.
227  *
228  * This function returns NT status codes.
229  *
230  * The following rules apply when processing a file open request:
231  *
232  * - Oplocks must be broken prior to share checking as the break may
233  *   cause other clients to close the file, which would affect sharing
234  *   checks.
235  *
236  * - Share checks must take place prior to access checks for correct
237  * Windows semantics and to prevent unnecessary NFS delegation recalls.
238  *
239  * - Oplocks must be acquired after open to ensure the correct
240  * synchronization with NFS delegation and FEM installation.
241  *
242  * DOS readonly bit rules
243  *
244  * 1. The creator of a readonly file can write to/modify the size of the file
245  * using the original create fid, even though the file will appear as readonly
246  * to all other fids and via a CIFS getattr call.
247  * The readonly bit therefore cannot be set in the filesystem until the file
248  * is closed (smb_ofile_close). It is accounted for via ofile and node flags.
249  *
250  * 2. A setinfo operation (using either an open fid or a path) to set/unset
251  * readonly will be successful regardless of whether a creator of a readonly
252  * file has an open fid (and has the special privilege mentioned in #1,
253  * above).  I.e., the creator of a readonly fid holding that fid will no longer
254  * have a special privilege.
255  *
256  * 3. The DOS readonly bit affects only data and some metadata.
257  * The following metadata can be changed regardless of the readonly bit:
258  * 	- security descriptors
259  *	- DOS attributes
260  *	- timestamps
261  *
262  * In the current implementation, the file size cannot be changed (except for
263  * the exceptions in #1 and #2, above).
264  *
265  *
266  * DOS attribute rules
267  *
268  * These rules are specific to creating / opening files and directories.
269  * How the attribute value (specifically ZERO or FILE_ATTRIBUTE_NORMAL)
270  * should be interpreted may differ in other requests.
271  *
272  * - An attribute value equal to ZERO or FILE_ATTRIBUTE_NORMAL means that the
273  *   file's attributes should be cleared.
274  * - If FILE_ATTRIBUTE_NORMAL is specified with any other attributes,
275  *   FILE_ATTRIBUTE_NORMAL is ignored.
276  *
277  * 1. Creating a new file
278  * - The request attributes + FILE_ATTRIBUTE_ARCHIVE are applied to the file.
279  *
280  * 2. Creating a new directory
281  * - The request attributes + FILE_ATTRIBUTE_DIRECTORY are applied to the file.
282  * - FILE_ATTRIBUTE_ARCHIVE does not get set.
283  *
284  * 3. Overwriting an existing file
285  * - the request attributes are used as search attributes. If the existing
286  *   file does not meet the search criteria access is denied.
287  * - otherwise, applies attributes + FILE_ATTRIBUTE_ARCHIVE.
288  *
289  * 4. Opening an existing file or directory
290  *    The request attributes are ignored.
291  */
292 static uint32_t
293 smb_open_subr(smb_request_t *sr)
294 {
295 	boolean_t	created = B_FALSE;
296 	boolean_t	last_comp_found = B_FALSE;
297 	smb_node_t	*node = NULL;
298 	smb_node_t	*dnode = NULL;
299 	smb_node_t	*cur_node = NULL;
300 	smb_arg_open_t	*op = &sr->sr_open;
301 	int		rc;
302 	smb_ofile_t	*of;
303 	smb_attr_t	new_attr;
304 	int		max_requested = 0;
305 	uint32_t	max_allowed;
306 	uint32_t	status = NT_STATUS_SUCCESS;
307 	int		is_dir;
308 	smb_error_t	err;
309 	boolean_t	is_stream = B_FALSE;
310 	int		lookup_flags = SMB_FOLLOW_LINKS;
311 	uint32_t	uniq_fid;
312 	smb_pathname_t	*pn = &op->fqi.fq_path;
313 	smb_server_t	*sv = sr->sr_server;
314 
315 	/* Get out now if we've been cancelled. */
316 	mutex_enter(&sr->sr_mutex);
317 	if (sr->sr_state != SMB_REQ_STATE_ACTIVE) {
318 		mutex_exit(&sr->sr_mutex);
319 		return (NT_STATUS_CANCELLED);
320 	}
321 	mutex_exit(&sr->sr_mutex);
322 
323 	is_dir = (op->create_options & FILE_DIRECTORY_FILE) ? 1 : 0;
324 
325 	/*
326 	 * If the object being created or opened is a directory
327 	 * the Disposition parameter must be one of FILE_CREATE,
328 	 * FILE_OPEN, or FILE_OPEN_IF
329 	 */
330 	if (is_dir) {
331 		if ((op->create_disposition != FILE_CREATE) &&
332 		    (op->create_disposition != FILE_OPEN_IF) &&
333 		    (op->create_disposition != FILE_OPEN)) {
334 			return (NT_STATUS_INVALID_PARAMETER);
335 		}
336 	}
337 
338 	if (op->desired_access & MAXIMUM_ALLOWED) {
339 		max_requested = 1;
340 		op->desired_access &= ~MAXIMUM_ALLOWED;
341 	}
342 	op->desired_access = smb_access_generic_to_file(op->desired_access);
343 
344 	if (sr->session->s_file_cnt >= smb_session_ofile_max) {
345 		ASSERT(sr->uid_user);
346 		cmn_err(CE_NOTE, "smbsrv[%s\\%s]: TOO_MANY_OPENED_FILES",
347 		    sr->uid_user->u_domain, sr->uid_user->u_name);
348 		return (NT_STATUS_TOO_MANY_OPENED_FILES);
349 	}
350 
351 	/* This must be NULL at this point */
352 	sr->fid_ofile = NULL;
353 
354 	op->devstate = 0;
355 
356 	switch (sr->tid_tree->t_res_type & STYPE_MASK) {
357 	case STYPE_DISKTREE:
358 	case STYPE_PRINTQ:
359 		break;
360 
361 	case STYPE_IPC:
362 		/*
363 		 * Security descriptors for pipes are not implemented,
364 		 * so just setup a reasonable access mask.
365 		 */
366 		op->desired_access = (READ_CONTROL | SYNCHRONIZE |
367 		    FILE_READ_DATA | FILE_READ_ATTRIBUTES |
368 		    FILE_WRITE_DATA | FILE_APPEND_DATA);
369 
370 		/*
371 		 * Limit the number of open pipe instances.
372 		 */
373 		if ((rc = smb_threshold_enter(&sv->sv_opipe_ct)) != 0) {
374 			status = RPC_NT_SERVER_TOO_BUSY;
375 			return (status);
376 		}
377 
378 		/*
379 		 * No further processing for IPC, we need to either
380 		 * raise an exception or return success here.
381 		 */
382 		uniq_fid = SMB_UNIQ_FID();
383 		status = smb_opipe_open(sr, uniq_fid);
384 		smb_threshold_exit(&sv->sv_opipe_ct);
385 		return (status);
386 
387 	default:
388 		return (NT_STATUS_BAD_DEVICE_TYPE);
389 	}
390 
391 	smb_pathname_init(sr, pn, pn->pn_path);
392 	if (!smb_pathname_validate(sr, pn))
393 		return (sr->smb_error.status);
394 
395 	if (strlen(pn->pn_path) >= SMB_MAXPATHLEN) {
396 		return (NT_STATUS_OBJECT_PATH_INVALID);
397 	}
398 
399 	if (is_dir) {
400 		if (!smb_validate_dirname(sr, pn))
401 			return (sr->smb_error.status);
402 	} else {
403 		if (!smb_validate_object_name(sr, pn))
404 			return (sr->smb_error.status);
405 	}
406 
407 	cur_node = op->fqi.fq_dnode ?
408 	    op->fqi.fq_dnode : sr->tid_tree->t_snode;
409 
410 	rc = smb_pathname_reduce(sr, sr->user_cr, pn->pn_path,
411 	    sr->tid_tree->t_snode, cur_node, &op->fqi.fq_dnode,
412 	    op->fqi.fq_last_comp);
413 	if (rc != 0) {
414 		return (smb_errno2status(rc));
415 	}
416 
417 	/*
418 	 * If the access mask has only DELETE set (ignore
419 	 * FILE_READ_ATTRIBUTES), then assume that this
420 	 * is a request to delete the link (if a link)
421 	 * and do not follow links.  Otherwise, follow
422 	 * the link to the target.
423 	 */
424 	if ((op->desired_access & ~FILE_READ_ATTRIBUTES) == DELETE)
425 		lookup_flags &= ~SMB_FOLLOW_LINKS;
426 
427 	rc = smb_fsop_lookup_name(sr, zone_kcred(), lookup_flags,
428 	    sr->tid_tree->t_snode, op->fqi.fq_dnode, op->fqi.fq_last_comp,
429 	    &op->fqi.fq_fnode);
430 
431 	if (rc == 0) {
432 		last_comp_found = B_TRUE;
433 		/*
434 		 * Need the DOS attributes below, where we
435 		 * check the search attributes (sattr).
436 		 */
437 		op->fqi.fq_fattr.sa_mask = SMB_AT_DOSATTR;
438 		rc = smb_node_getattr(sr, op->fqi.fq_fnode, zone_kcred(),
439 		    NULL, &op->fqi.fq_fattr);
440 		if (rc != 0) {
441 			smb_node_release(op->fqi.fq_fnode);
442 			smb_node_release(op->fqi.fq_dnode);
443 			return (NT_STATUS_INTERNAL_ERROR);
444 		}
445 	} else if (rc == ENOENT) {
446 		last_comp_found = B_FALSE;
447 		op->fqi.fq_fnode = NULL;
448 		rc = 0;
449 	} else {
450 		smb_node_release(op->fqi.fq_dnode);
451 		return (smb_errno2status(rc));
452 	}
453 
454 
455 	/*
456 	 * The uniq_fid is a CIFS-server-wide unique identifier for an ofile
457 	 * which is used to uniquely identify open instances for the
458 	 * VFS share reservation and POSIX locks.
459 	 */
460 
461 	uniq_fid = SMB_UNIQ_FID();
462 
463 	if (last_comp_found) {
464 
465 		node = op->fqi.fq_fnode;
466 		dnode = op->fqi.fq_dnode;
467 
468 		if (!smb_node_is_file(node) && !smb_node_is_dir(node) &&
469 		    !smb_node_is_symlink(node)) {
470 			smb_node_release(node);
471 			smb_node_release(dnode);
472 			return (NT_STATUS_ACCESS_DENIED);
473 		}
474 
475 		/*
476 		 * Reject this request if either:
477 		 * - the target IS a directory and the client requires that
478 		 *   it must NOT be (required by Lotus Notes)
479 		 * - the target is NOT a directory and client requires that
480 		 *   it MUST be.
481 		 */
482 		if (smb_node_is_dir(node)) {
483 			if (op->create_options & FILE_NON_DIRECTORY_FILE) {
484 				smb_node_release(node);
485 				smb_node_release(dnode);
486 				return (NT_STATUS_FILE_IS_A_DIRECTORY);
487 			}
488 		} else {
489 			if ((op->create_options & FILE_DIRECTORY_FILE) ||
490 			    (op->nt_flags & NT_CREATE_FLAG_OPEN_TARGET_DIR)) {
491 				smb_node_release(node);
492 				smb_node_release(dnode);
493 				return (NT_STATUS_NOT_A_DIRECTORY);
494 			}
495 		}
496 
497 		/*
498 		 * No more open should be accepted when "Delete on close"
499 		 * flag is set.
500 		 */
501 		if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
502 			smb_node_release(node);
503 			smb_node_release(dnode);
504 			return (NT_STATUS_DELETE_PENDING);
505 		}
506 
507 		/*
508 		 * Specified file already exists so the operation should fail.
509 		 */
510 		if (op->create_disposition == FILE_CREATE) {
511 			smb_node_release(node);
512 			smb_node_release(dnode);
513 			return (NT_STATUS_OBJECT_NAME_COLLISION);
514 		}
515 
516 		/*
517 		 * Windows seems to check read-only access before file
518 		 * sharing check.
519 		 *
520 		 * Check to see if the file is currently readonly (irrespective
521 		 * of whether this open will make it readonly).
522 		 */
523 		if (SMB_PATHFILE_IS_READONLY(sr, node)) {
524 			/* Files data only */
525 			if (!smb_node_is_dir(node)) {
526 				if (op->desired_access & (FILE_WRITE_DATA |
527 				    FILE_APPEND_DATA)) {
528 					smb_node_release(node);
529 					smb_node_release(dnode);
530 					return (NT_STATUS_ACCESS_DENIED);
531 				}
532 				if (op->create_options & FILE_DELETE_ON_CLOSE) {
533 					smb_node_release(node);
534 					smb_node_release(dnode);
535 					return (NT_STATUS_CANNOT_DELETE);
536 				}
537 			}
538 		}
539 
540 		if ((op->create_disposition == FILE_SUPERSEDE) ||
541 		    (op->create_disposition == FILE_OVERWRITE_IF) ||
542 		    (op->create_disposition == FILE_OVERWRITE)) {
543 
544 			if (!smb_sattr_check(op->fqi.fq_fattr.sa_dosattr,
545 			    op->dattr)) {
546 				smb_node_release(node);
547 				smb_node_release(dnode);
548 				return (NT_STATUS_ACCESS_DENIED);
549 			}
550 
551 			if (smb_node_is_dir(node)) {
552 				smb_node_release(node);
553 				smb_node_release(dnode);
554 				return (NT_STATUS_ACCESS_DENIED);
555 			}
556 		}
557 
558 		/* MS-FSA 2.1.5.1.2 */
559 		if (op->create_disposition == FILE_SUPERSEDE)
560 			op->desired_access |= DELETE;
561 		if ((op->create_disposition == FILE_OVERWRITE_IF) ||
562 		    (op->create_disposition == FILE_OVERWRITE))
563 			op->desired_access |= FILE_WRITE_DATA;
564 
565 		status = smb_fsop_access(sr, sr->user_cr, node,
566 		    op->desired_access);
567 		if (status != NT_STATUS_SUCCESS) {
568 			smb_node_release(node);
569 			smb_node_release(dnode);
570 
571 			/* SMB1 specific? NT_STATUS_PRIVILEGE_NOT_HELD */
572 			if (status == NT_STATUS_PRIVILEGE_NOT_HELD) {
573 				return (status);
574 			} else {
575 				return (NT_STATUS_ACCESS_DENIED);
576 			}
577 		}
578 
579 		if (max_requested) {
580 			smb_fsop_eaccess(sr, sr->user_cr, node, &max_allowed);
581 			op->desired_access |= max_allowed;
582 		}
583 		/*
584 		 * According to MS "dochelp" mail in Mar 2015, any handle
585 		 * on which read or write access is granted implicitly
586 		 * gets "read attributes", even if it was not requested.
587 		 * This avoids unexpected access failures later that
588 		 * would happen if these were not granted.
589 		 */
590 		if ((op->desired_access & FILE_DATA_ALL) != 0) {
591 			op->desired_access |= (READ_CONTROL |
592 			    FILE_READ_ATTRIBUTES);
593 		}
594 
595 		/*
596 		 * Oplock break is done prior to sharing checks as the break
597 		 * may cause other clients to close the file which would
598 		 * affect the sharing checks. This may block, so set the
599 		 * file opening count before oplock stuff.
600 		 */
601 		smb_node_inc_opening_count(node);
602 		smb_open_oplock_break(sr, node);
603 
604 		smb_node_wrlock(node);
605 
606 		/*
607 		 * Check for sharing violations
608 		 */
609 		status = smb_fsop_shrlock(sr->user_cr, node, uniq_fid,
610 		    op->desired_access, op->share_access);
611 		if (status == NT_STATUS_SHARING_VIOLATION) {
612 			smb_node_unlock(node);
613 			smb_node_dec_opening_count(node);
614 			smb_node_release(node);
615 			smb_node_release(dnode);
616 			return (status);
617 		}
618 
619 		/*
620 		 * Go ahead with modifications as necessary.
621 		 */
622 		switch (op->create_disposition) {
623 		case FILE_SUPERSEDE:
624 		case FILE_OVERWRITE_IF:
625 		case FILE_OVERWRITE:
626 			op->dattr |= FILE_ATTRIBUTE_ARCHIVE;
627 			/* Don't apply readonly bit until smb_ofile_close */
628 			if (op->dattr & FILE_ATTRIBUTE_READONLY) {
629 				op->created_readonly = B_TRUE;
630 				op->dattr &= ~FILE_ATTRIBUTE_READONLY;
631 			}
632 
633 			/*
634 			 * Truncate the file data here.
635 			 * We set alloc_size = op->dsize later,
636 			 * after we have an ofile.  See:
637 			 * smb_set_open_attributes
638 			 */
639 			bzero(&new_attr, sizeof (new_attr));
640 			new_attr.sa_dosattr = op->dattr;
641 			new_attr.sa_vattr.va_size = 0;
642 			new_attr.sa_mask = SMB_AT_DOSATTR | SMB_AT_SIZE;
643 			rc = smb_fsop_setattr(sr, sr->user_cr, node, &new_attr);
644 			if (rc != 0) {
645 				smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
646 				smb_node_unlock(node);
647 				smb_node_dec_opening_count(node);
648 				smb_node_release(node);
649 				smb_node_release(dnode);
650 				return (smb_errno2status(rc));
651 			}
652 
653 			/*
654 			 * If file is being replaced, remove existing streams
655 			 */
656 			if (SMB_IS_STREAM(node) == 0) {
657 				status = smb_fsop_remove_streams(sr,
658 				    sr->user_cr, node);
659 				if (status != 0) {
660 					smb_fsop_unshrlock(sr->user_cr, node,
661 					    uniq_fid);
662 					smb_node_unlock(node);
663 					smb_node_dec_opening_count(node);
664 					smb_node_release(node);
665 					smb_node_release(dnode);
666 					return (status);
667 				}
668 			}
669 
670 			op->action_taken = SMB_OACT_TRUNCATED;
671 			break;
672 
673 		default:
674 			/*
675 			 * FILE_OPEN or FILE_OPEN_IF.
676 			 */
677 			/*
678 			 * Ignore any user-specified alloc_size for
679 			 * existing files, to avoid truncation in
680 			 * smb_set_open_attributes
681 			 */
682 			op->dsize = 0L;
683 			op->action_taken = SMB_OACT_OPENED;
684 			break;
685 		}
686 	} else {
687 		/* Last component was not found. */
688 		dnode = op->fqi.fq_dnode;
689 
690 		if (is_dir == 0)
691 			is_stream = smb_is_stream_name(pn->pn_path);
692 
693 		if ((op->create_disposition == FILE_OPEN) ||
694 		    (op->create_disposition == FILE_OVERWRITE)) {
695 			smb_node_release(dnode);
696 			return (NT_STATUS_OBJECT_NAME_NOT_FOUND);
697 		}
698 
699 		if (pn->pn_fname && smb_is_invalid_filename(pn->pn_fname)) {
700 			smb_node_release(dnode);
701 			return (NT_STATUS_OBJECT_NAME_INVALID);
702 		}
703 
704 		/*
705 		 * lock the parent dir node in case another create
706 		 * request to the same parent directory comes in.
707 		 */
708 		smb_node_wrlock(dnode);
709 
710 		/* Don't apply readonly bit until smb_ofile_close */
711 		if (op->dattr & FILE_ATTRIBUTE_READONLY) {
712 			op->dattr &= ~FILE_ATTRIBUTE_READONLY;
713 			op->created_readonly = B_TRUE;
714 		}
715 
716 		bzero(&new_attr, sizeof (new_attr));
717 		if ((op->crtime.tv_sec != 0) &&
718 		    (op->crtime.tv_sec != UINT_MAX)) {
719 
720 			new_attr.sa_mask |= SMB_AT_CRTIME;
721 			new_attr.sa_crtime = op->crtime;
722 		}
723 
724 		if (is_dir == 0) {
725 			op->dattr |= FILE_ATTRIBUTE_ARCHIVE;
726 			new_attr.sa_dosattr = op->dattr;
727 			new_attr.sa_vattr.va_type = VREG;
728 			new_attr.sa_vattr.va_mode = is_stream ? S_IRUSR :
729 			    S_IRUSR | S_IRGRP | S_IROTH |
730 			    S_IWUSR | S_IWGRP | S_IWOTH;
731 			new_attr.sa_mask |=
732 			    SMB_AT_DOSATTR | SMB_AT_TYPE | SMB_AT_MODE;
733 
734 			/*
735 			 * We set alloc_size = op->dsize later,
736 			 * (in smb_set_open_attributes) after we
737 			 * have an ofile on which to save that.
738 			 *
739 			 * Legacy Open&X sets size to alloc_size
740 			 * when creating a new file.
741 			 */
742 			if (sr->smb_com == SMB_COM_OPEN_ANDX) {
743 				new_attr.sa_vattr.va_size = op->dsize;
744 				new_attr.sa_mask |= SMB_AT_SIZE;
745 			}
746 
747 			rc = smb_fsop_create(sr, sr->user_cr, dnode,
748 			    op->fqi.fq_last_comp, &new_attr, &op->fqi.fq_fnode);
749 
750 			if (rc != 0) {
751 				smb_node_unlock(dnode);
752 				smb_node_release(dnode);
753 				return (smb_errno2status(rc));
754 			}
755 
756 			node = op->fqi.fq_fnode;
757 			smb_node_inc_opening_count(node);
758 			smb_node_wrlock(node);
759 
760 			status = smb_fsop_shrlock(sr->user_cr, node, uniq_fid,
761 			    op->desired_access, op->share_access);
762 
763 			if (status == NT_STATUS_SHARING_VIOLATION) {
764 				smb_node_unlock(node);
765 				smb_node_dec_opening_count(node);
766 				smb_delete_new_object(sr);
767 				smb_node_release(node);
768 				smb_node_unlock(dnode);
769 				smb_node_release(dnode);
770 				return (status);
771 			}
772 		} else {
773 			op->dattr |= FILE_ATTRIBUTE_DIRECTORY;
774 			new_attr.sa_dosattr = op->dattr;
775 			new_attr.sa_vattr.va_type = VDIR;
776 			new_attr.sa_vattr.va_mode = 0777;
777 			new_attr.sa_mask |=
778 			    SMB_AT_DOSATTR | SMB_AT_TYPE | SMB_AT_MODE;
779 
780 			rc = smb_fsop_mkdir(sr, sr->user_cr, dnode,
781 			    op->fqi.fq_last_comp, &new_attr, &op->fqi.fq_fnode);
782 			if (rc != 0) {
783 				smb_node_unlock(dnode);
784 				smb_node_release(dnode);
785 				return (smb_errno2status(rc));
786 			}
787 
788 			node = op->fqi.fq_fnode;
789 			smb_node_inc_opening_count(node);
790 			smb_node_wrlock(node);
791 		}
792 
793 		created = B_TRUE;
794 		op->action_taken = SMB_OACT_CREATED;
795 
796 		if (max_requested) {
797 			smb_fsop_eaccess(sr, sr->user_cr, node, &max_allowed);
798 			op->desired_access |= max_allowed;
799 		}
800 		/*
801 		 * We created this object (we own it) so grant
802 		 * read_control + read_attributes on this handle,
803 		 * even if that was not requested.  This avoids
804 		 * unexpected access failures later.
805 		 */
806 		op->desired_access |= (READ_CONTROL | FILE_READ_ATTRIBUTES);
807 	}
808 
809 	status = NT_STATUS_SUCCESS;
810 
811 	of = smb_ofile_open(sr, node, op, SMB_FTYPE_DISK, uniq_fid,
812 	    &err);
813 	if (of == NULL) {
814 		status = err.status;
815 	}
816 
817 	/*
818 	 * We might have blocked in smb_ofile_open long enough so a
819 	 * tree disconnect might have happened.  In that case, we've
820 	 * just added an ofile to a tree that's disconnecting, and
821 	 * need to undo that to avoid interfering with tear-down of
822 	 * the tree connection.
823 	 */
824 	if (status == NT_STATUS_SUCCESS &&
825 	    !smb_tree_is_connected(sr->tid_tree)) {
826 		status = NT_STATUS_INVALID_PARAMETER;
827 	}
828 
829 	/*
830 	 * This MUST be done after ofile creation, so that explicitly
831 	 * set timestamps can be remembered on the ofile, and the
832 	 * readonly flag will be stored "pending" on the node.
833 	 */
834 	if (status == NT_STATUS_SUCCESS) {
835 		if ((rc = smb_set_open_attributes(sr, of)) != 0) {
836 			status = smb_errno2status(rc);
837 		}
838 	}
839 
840 	if (status == NT_STATUS_SUCCESS) {
841 		/*
842 		 * We've already done access checks above,
843 		 * and want this call to succeed even when
844 		 * !(desired_access & FILE_READ_ATTRIBUTES),
845 		 * so pass kcred here.
846 		 */
847 		op->fqi.fq_fattr.sa_mask = SMB_AT_ALL;
848 		rc = smb_node_getattr(sr, node, zone_kcred(), of,
849 		    &op->fqi.fq_fattr);
850 		if (rc != 0) {
851 			status = NT_STATUS_INTERNAL_ERROR;
852 		}
853 	}
854 
855 	/*
856 	 * smb_fsop_unshrlock is a no-op if node is a directory
857 	 * smb_fsop_unshrlock is done in smb_ofile_close
858 	 */
859 	if (status != NT_STATUS_SUCCESS) {
860 		if (of == NULL) {
861 			smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
862 		} else {
863 			smb_ofile_close(of, 0);
864 			smb_ofile_release(of);
865 		}
866 		if (created)
867 			smb_delete_new_object(sr);
868 		smb_node_unlock(node);
869 		smb_node_dec_opening_count(node);
870 		smb_node_release(node);
871 		if (created)
872 			smb_node_unlock(dnode);
873 		smb_node_release(dnode);
874 		return (status);
875 	}
876 
877 	/*
878 	 * Propagate the write-through mode from the open params
879 	 * to the node: see the notes in the function header.
880 	 */
881 	if (sr->sr_cfg->skc_sync_enable ||
882 	    (op->create_options & FILE_WRITE_THROUGH))
883 		node->flags |= NODE_FLAGS_WRITE_THROUGH;
884 
885 	/*
886 	 * Set up the fileid and dosattr in open_param for response
887 	 */
888 	op->fileid = op->fqi.fq_fattr.sa_vattr.va_nodeid;
889 	op->dattr = op->fqi.fq_fattr.sa_dosattr;
890 
891 	/*
892 	 * Set up the file type in open_param for the response
893 	 */
894 	op->ftype = SMB_FTYPE_DISK;
895 	sr->smb_fid = of->f_fid;
896 	sr->fid_ofile = of;
897 
898 	if (smb_node_is_file(node)) {
899 		smb_oplock_acquire(sr, node, of);
900 		op->dsize = op->fqi.fq_fattr.sa_vattr.va_size;
901 	} else {
902 		/* directory or symlink */
903 		op->op_oplock_level = SMB_OPLOCK_NONE;
904 		op->dsize = 0;
905 	}
906 
907 	smb_node_dec_opening_count(node);
908 
909 	smb_node_unlock(node);
910 	if (created)
911 		smb_node_unlock(dnode);
912 
913 	smb_node_release(node);
914 	smb_node_release(dnode);
915 
916 	return (NT_STATUS_SUCCESS);
917 }
918 
919 /*
920  * smb_open_oplock_break
921  *
922  * If the node has an ofile opened with share access none,
923  * (smb_node_share_check = FALSE) only break BATCH oplock.
924  * Otherwise:
925  * If overwriting, break to SMB_OPLOCK_NONE, else
926  * If opening for anything other than attribute access,
927  * break oplock to LEVEL_II.
928  */
929 static void
930 smb_open_oplock_break(smb_request_t *sr, smb_node_t *node)
931 {
932 	smb_arg_open_t	*op = &sr->sr_open;
933 	uint32_t	flags = 0;
934 
935 	if (!smb_node_share_check(node))
936 		flags |= SMB_OPLOCK_BREAK_BATCH;
937 
938 	if (smb_open_overwrite(op)) {
939 		flags |= SMB_OPLOCK_BREAK_TO_NONE;
940 		(void) smb_oplock_break(sr, node, flags);
941 	} else if (!smb_open_attr_only(op)) {
942 		flags |= SMB_OPLOCK_BREAK_TO_LEVEL_II;
943 		(void) smb_oplock_break(sr, node, flags);
944 	}
945 }
946 
947 /*
948  * smb_open_attr_only
949  *
950  * Determine if file is being opened for attribute access only.
951  * This is used to determine whether it is necessary to break
952  * existing oplocks on the file.
953  */
954 static boolean_t
955 smb_open_attr_only(smb_arg_open_t *op)
956 {
957 	if (((op->desired_access & ~(FILE_READ_ATTRIBUTES |
958 	    FILE_WRITE_ATTRIBUTES | SYNCHRONIZE | READ_CONTROL)) == 0) &&
959 	    (op->create_disposition != FILE_SUPERSEDE) &&
960 	    (op->create_disposition != FILE_OVERWRITE)) {
961 		return (B_TRUE);
962 	}
963 	return (B_FALSE);
964 }
965 
966 static boolean_t
967 smb_open_overwrite(smb_arg_open_t *op)
968 {
969 	if ((op->create_disposition == FILE_SUPERSEDE) ||
970 	    (op->create_disposition == FILE_OVERWRITE_IF) ||
971 	    (op->create_disposition == FILE_OVERWRITE)) {
972 		return (B_TRUE);
973 	}
974 	return (B_FALSE);
975 }
976 
977 /*
978  * smb_set_open_attributes
979  *
980  * Last write time:
981  * - If the last_write time specified in the open params is not 0 or -1,
982  *   use it as file's mtime. This will be considered an explicitly set
983  *   timestamps, not reset by subsequent writes.
984  *
985  * DOS attributes
986  * - If we created_readonly, we now store the real DOS attributes
987  *   (including the readonly bit) so subsequent opens will see it.
988  *
989  * Both are stored "pending" rather than in the file system.
990  *
991  * Returns: errno
992  */
993 static int
994 smb_set_open_attributes(smb_request_t *sr, smb_ofile_t *of)
995 {
996 	smb_attr_t	attr;
997 	smb_arg_open_t	*op = &sr->sr_open;
998 	smb_node_t	*node = of->f_node;
999 	int		rc = 0;
1000 
1001 	bzero(&attr, sizeof (smb_attr_t));
1002 
1003 	if (op->created_readonly) {
1004 		attr.sa_dosattr = op->dattr | FILE_ATTRIBUTE_READONLY;
1005 		attr.sa_mask |= SMB_AT_DOSATTR;
1006 	}
1007 
1008 	if (op->dsize != 0) {
1009 		attr.sa_allocsz = op->dsize;
1010 		attr.sa_mask |= SMB_AT_ALLOCSZ;
1011 	}
1012 
1013 	if ((op->mtime.tv_sec != 0) && (op->mtime.tv_sec != UINT_MAX)) {
1014 		attr.sa_vattr.va_mtime = op->mtime;
1015 		attr.sa_mask |= SMB_AT_MTIME;
1016 	}
1017 
1018 	/*
1019 	 * Used to have code here to set mtime, ctime, atime
1020 	 * when the open op->create_disposition is any of:
1021 	 * FILE_SUPERSEDE, FILE_OVERWRITE_IF, FILE_OVERWRITE.
1022 	 * We know that in those cases we will have set the
1023 	 * file size, in which case the file system will
1024 	 * update those times, so we don't have to.
1025 	 *
1026 	 * However, keep track of the fact that we modified
1027 	 * the file via this handle, so we can do the evil,
1028 	 * gratuitious mtime update on close that Windows
1029 	 * clients appear to expect.
1030 	 */
1031 	if (op->action_taken == SMB_OACT_TRUNCATED)
1032 		of->f_written = B_TRUE;
1033 
1034 	if (attr.sa_mask != 0)
1035 		rc = smb_node_setattr(sr, node, of->f_cr, of, &attr);
1036 
1037 	return (rc);
1038 }
1039 
1040 /*
1041  * This function is used to delete a newly created object (file or
1042  * directory) if an error occurs after creation of the object.
1043  */
1044 static void
1045 smb_delete_new_object(smb_request_t *sr)
1046 {
1047 	smb_arg_open_t	*op = &sr->sr_open;
1048 	smb_fqi_t	*fqi = &(op->fqi);
1049 	uint32_t	flags = 0;
1050 
1051 	if (SMB_TREE_IS_CASEINSENSITIVE(sr))
1052 		flags |= SMB_IGNORE_CASE;
1053 	if (SMB_TREE_SUPPORTS_CATIA(sr))
1054 		flags |= SMB_CATIA;
1055 
1056 	if (op->create_options & FILE_DIRECTORY_FILE)
1057 		(void) smb_fsop_rmdir(sr, sr->user_cr, fqi->fq_dnode,
1058 		    fqi->fq_last_comp, flags);
1059 	else
1060 		(void) smb_fsop_remove(sr, sr->user_cr, fqi->fq_dnode,
1061 		    fqi->fq_last_comp, flags);
1062 }
1063