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