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