xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_common_open.c (revision 68b2bbf26c7040fea4281dcb58b81e7627e46f34)
1da6c28aaSamw /*
2da6c28aaSamw  * CDDL HEADER START
3da6c28aaSamw  *
4da6c28aaSamw  * The contents of this file are subject to the terms of the
5da6c28aaSamw  * Common Development and Distribution License (the "License").
6da6c28aaSamw  * You may not use this file except in compliance with the License.
7da6c28aaSamw  *
8da6c28aaSamw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9da6c28aaSamw  * or http://www.opensolaris.org/os/licensing.
10da6c28aaSamw  * See the License for the specific language governing permissions
11da6c28aaSamw  * and limitations under the License.
12da6c28aaSamw  *
13da6c28aaSamw  * When distributing Covered Code, include this CDDL HEADER in each
14da6c28aaSamw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15da6c28aaSamw  * If applicable, add the following below this CDDL HEADER, with the
16da6c28aaSamw  * fields enclosed by brackets "[]" replaced with your own identifying
17da6c28aaSamw  * information: Portions Copyright [yyyy] [name of copyright owner]
18da6c28aaSamw  *
19da6c28aaSamw  * CDDL HEADER END
20da6c28aaSamw  */
21148c5f43SAlan Wright 
22da6c28aaSamw /*
23148c5f43SAlan Wright  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24fb699f1eSAlek Pinchuk  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
25da6c28aaSamw  */
26da6c28aaSamw 
27da6c28aaSamw /*
28da6c28aaSamw  * This module provides the common open functionality to the various
29da6c28aaSamw  * open and create SMB interface functions.
30da6c28aaSamw  */
31da6c28aaSamw 
32bbf6f00cSJordan Brown #include <sys/types.h>
33bbf6f00cSJordan Brown #include <sys/cmn_err.h>
34da6c28aaSamw #include <sys/fcntl.h>
35dc20a302Sas200622 #include <sys/nbmlock.h>
36bbf6f00cSJordan Brown #include <smbsrv/string.h>
37bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h>
38bbf6f00cSJordan Brown #include <smbsrv/smb_fsops.h>
39bbf6f00cSJordan Brown #include <smbsrv/smbinfo.h>
40da6c28aaSamw 
41*68b2bbf2SGordon Ross static volatile uint32_t smb_fids = 0;
42b819cea2SGordon Ross #define	SMB_UNIQ_FID()	atomic_inc_32_nv(&smb_fids)
437b59d02dSjb150015 
447b59d02dSjb150015 static uint32_t smb_open_subr(smb_request_t *);
45faa1795aSjb150015 extern uint32_t smb_is_executable(char *);
468b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States static void smb_delete_new_object(smb_request_t *);
475fd03bc0SGordon Ross static int smb_set_open_attributes(smb_request_t *, smb_ofile_t *);
48cb174861Sjoyce mcintosh static void smb_open_oplock_break(smb_request_t *, smb_node_t *);
49cb174861Sjoyce mcintosh static boolean_t smb_open_attr_only(smb_arg_open_t *);
50cb174861Sjoyce mcintosh static boolean_t smb_open_overwrite(smb_arg_open_t *);
51da6c28aaSamw 
52da6c28aaSamw /*
53da6c28aaSamw  * smb_access_generic_to_file
54da6c28aaSamw  *
55da6c28aaSamw  * Search MSDN for IoCreateFile to see following mapping.
56da6c28aaSamw  *
57da6c28aaSamw  * GENERIC_READ		STANDARD_RIGHTS_READ, FILE_READ_DATA,
58da6c28aaSamw  *			FILE_READ_ATTRIBUTES and FILE_READ_EA
59da6c28aaSamw  *
60da6c28aaSamw  * GENERIC_WRITE	STANDARD_RIGHTS_WRITE, FILE_WRITE_DATA,
61da6c28aaSamw  *               FILE_WRITE_ATTRIBUTES, FILE_WRITE_EA, and FILE_APPEND_DATA
62da6c28aaSamw  *
63da6c28aaSamw  * GENERIC_EXECUTE	STANDARD_RIGHTS_EXECUTE, SYNCHRONIZE, and FILE_EXECUTE.
64193e3365SGordon Ross  *
65193e3365SGordon Ross  * Careful, we have to emulate some Windows behavior here.
66193e3365SGordon Ross  * When requested access == zero, you get READ_CONTROL.
67193e3365SGordon Ross  * MacOS 10.7 depends on this.
68da6c28aaSamw  */
69da6c28aaSamw uint32_t
70da6c28aaSamw smb_access_generic_to_file(uint32_t desired_access)
71da6c28aaSamw {
72193e3365SGordon Ross 	uint32_t access = READ_CONTROL;
73da6c28aaSamw 
74da6c28aaSamw 	if (desired_access & GENERIC_ALL)
75da6c28aaSamw 		return (FILE_ALL_ACCESS & ~SYNCHRONIZE);
76da6c28aaSamw 
77da6c28aaSamw 	if (desired_access & GENERIC_EXECUTE) {
78da6c28aaSamw 		desired_access &= ~GENERIC_EXECUTE;
79da6c28aaSamw 		access |= (STANDARD_RIGHTS_EXECUTE |
80da6c28aaSamw 		    SYNCHRONIZE | FILE_EXECUTE);
81da6c28aaSamw 	}
82da6c28aaSamw 
83da6c28aaSamw 	if (desired_access & GENERIC_WRITE) {
84da6c28aaSamw 		desired_access &= ~GENERIC_WRITE;
85da6c28aaSamw 		access |= (FILE_GENERIC_WRITE & ~SYNCHRONIZE);
86da6c28aaSamw 	}
87da6c28aaSamw 
88da6c28aaSamw 	if (desired_access & GENERIC_READ) {
89da6c28aaSamw 		desired_access &= ~GENERIC_READ;
90da6c28aaSamw 		access |= FILE_GENERIC_READ;
91da6c28aaSamw 	}
92da6c28aaSamw 
93da6c28aaSamw 	return (access | desired_access);
94da6c28aaSamw }
95da6c28aaSamw 
96da6c28aaSamw /*
97da6c28aaSamw  * smb_omode_to_amask
98da6c28aaSamw  *
99da6c28aaSamw  * This function converts open modes used by Open and Open AndX
100da6c28aaSamw  * commands to desired access bits used by NT Create AndX command.
101da6c28aaSamw  */
102da6c28aaSamw uint32_t
103da6c28aaSamw smb_omode_to_amask(uint32_t desired_access)
104da6c28aaSamw {
105da6c28aaSamw 	switch (desired_access & SMB_DA_ACCESS_MASK) {
106da6c28aaSamw 	case SMB_DA_ACCESS_READ:
107da6c28aaSamw 		return (FILE_GENERIC_READ);
108da6c28aaSamw 
109da6c28aaSamw 	case SMB_DA_ACCESS_WRITE:
110da6c28aaSamw 		return (FILE_GENERIC_WRITE);
111da6c28aaSamw 
112da6c28aaSamw 	case SMB_DA_ACCESS_READ_WRITE:
113da6c28aaSamw 		return (FILE_GENERIC_READ | FILE_GENERIC_WRITE);
114da6c28aaSamw 
115da6c28aaSamw 	case SMB_DA_ACCESS_EXECUTE:
116da6c28aaSamw 		return (FILE_GENERIC_EXECUTE);
117da6c28aaSamw 
1182c2961f8Sjose borrego 	default:
1192c2961f8Sjose borrego 		return (FILE_GENERIC_ALL);
1202c2961f8Sjose borrego 	}
121da6c28aaSamw }
122da6c28aaSamw 
123da6c28aaSamw /*
124da6c28aaSamw  * smb_denymode_to_sharemode
125da6c28aaSamw  *
126da6c28aaSamw  * This function converts deny modes used by Open and Open AndX
127da6c28aaSamw  * commands to share access bits used by NT Create AndX command.
128da6c28aaSamw  */
129da6c28aaSamw uint32_t
130da6c28aaSamw smb_denymode_to_sharemode(uint32_t desired_access, char *fname)
131da6c28aaSamw {
132da6c28aaSamw 	switch (desired_access & SMB_DA_SHARE_MASK) {
133da6c28aaSamw 	case SMB_DA_SHARE_COMPATIBILITY:
134da6c28aaSamw 		if (smb_is_executable(fname))
135da6c28aaSamw 			return (FILE_SHARE_READ | FILE_SHARE_WRITE);
136c8ec8eeaSjose borrego 
137c8ec8eeaSjose borrego 		return (FILE_SHARE_ALL);
138da6c28aaSamw 
139da6c28aaSamw 	case SMB_DA_SHARE_EXCLUSIVE:
140da6c28aaSamw 		return (FILE_SHARE_NONE);
141da6c28aaSamw 
142da6c28aaSamw 	case SMB_DA_SHARE_DENY_WRITE:
143da6c28aaSamw 		return (FILE_SHARE_READ);
144da6c28aaSamw 
145da6c28aaSamw 	case SMB_DA_SHARE_DENY_READ:
146da6c28aaSamw 		return (FILE_SHARE_WRITE);
147da6c28aaSamw 
148da6c28aaSamw 	case SMB_DA_SHARE_DENY_NONE:
1492c2961f8Sjose borrego 	default:
150da6c28aaSamw 		return (FILE_SHARE_READ | FILE_SHARE_WRITE);
151da6c28aaSamw 	}
152da6c28aaSamw }
153da6c28aaSamw 
154da6c28aaSamw /*
155da6c28aaSamw  * smb_ofun_to_crdisposition
156da6c28aaSamw  *
157da6c28aaSamw  * This function converts open function values used by Open and Open AndX
158da6c28aaSamw  * commands to create disposition values used by NT Create AndX command.
159da6c28aaSamw  */
160da6c28aaSamw uint32_t
161da6c28aaSamw smb_ofun_to_crdisposition(uint16_t  ofun)
162da6c28aaSamw {
163da6c28aaSamw 	static int ofun_cr_map[3][2] =
164da6c28aaSamw 	{
165da6c28aaSamw 		{ -1,			FILE_CREATE },
166da6c28aaSamw 		{ FILE_OPEN,		FILE_OPEN_IF },
167da6c28aaSamw 		{ FILE_OVERWRITE,	FILE_OVERWRITE_IF }
168da6c28aaSamw 	};
169da6c28aaSamw 
170da6c28aaSamw 	int row = ofun & SMB_OFUN_OPEN_MASK;
171da6c28aaSamw 	int col = (ofun & SMB_OFUN_CREATE_MASK) >> 4;
172da6c28aaSamw 
173da6c28aaSamw 	if (row == 3)
1742c2961f8Sjose borrego 		return (FILE_MAXIMUM_DISPOSITION + 1);
175da6c28aaSamw 
176da6c28aaSamw 	return (ofun_cr_map[row][col]);
177da6c28aaSamw }
178da6c28aaSamw 
179da6c28aaSamw /*
1807b59d02dSjb150015  * Retry opens to avoid spurious sharing violations, due to timing
1817b59d02dSjb150015  * issues between closes and opens.  The client that already has the
1827b59d02dSjb150015  * file open may be in the process of closing it.
1837b59d02dSjb150015  */
1847b59d02dSjb150015 uint32_t
1857b59d02dSjb150015 smb_common_open(smb_request_t *sr)
1867b59d02dSjb150015 {
187148c5f43SAlan Wright 	smb_arg_open_t	*parg;
1887b59d02dSjb150015 	uint32_t	status = NT_STATUS_SUCCESS;
1897b59d02dSjb150015 	int		count;
1907b59d02dSjb150015 
191bbf6f00cSJordan Brown 	parg = kmem_alloc(sizeof (*parg), KM_SLEEP);
192bbf6f00cSJordan Brown 	bcopy(&sr->arg.open, parg, sizeof (*parg));
193bbf6f00cSJordan Brown 
1947b59d02dSjb150015 	for (count = 0; count <= 4; count++) {
195bbf6f00cSJordan Brown 		if (count != 0)
1967b59d02dSjb150015 			delay(MSEC_TO_TICK(400));
1977b59d02dSjb150015 
198faa1795aSjb150015 		status = smb_open_subr(sr);
199faa1795aSjb150015 		if (status != NT_STATUS_SHARING_VIOLATION)
2007b59d02dSjb150015 			break;
201bbf6f00cSJordan Brown 
202bbf6f00cSJordan Brown 		bcopy(parg, &sr->arg.open, sizeof (*parg));
2037b59d02dSjb150015 	}
2047b59d02dSjb150015 
205faa1795aSjb150015 	if (status == NT_STATUS_SHARING_VIOLATION) {
2067b59d02dSjb150015 		smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
2077b59d02dSjb150015 		    ERRDOS, ERROR_SHARING_VIOLATION);
2087b59d02dSjb150015 	}
2097b59d02dSjb150015 
2102c2961f8Sjose borrego 	if (status == NT_STATUS_NO_SUCH_FILE) {
2112c2961f8Sjose borrego 		smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND,
2122c2961f8Sjose borrego 		    ERRDOS, ERROR_FILE_NOT_FOUND);
2132c2961f8Sjose borrego 	}
2142c2961f8Sjose borrego 
215bbf6f00cSJordan Brown 	kmem_free(parg, sizeof (*parg));
2167b59d02dSjb150015 	return (status);
2177b59d02dSjb150015 }
2187b59d02dSjb150015 
2197b59d02dSjb150015 /*
220da6c28aaSamw  * smb_open_subr
221da6c28aaSamw  *
222da6c28aaSamw  * Notes on write-through behaviour. It looks like pre-LM0.12 versions
223da6c28aaSamw  * of the protocol specify the write-through mode when a file is opened,
224da6c28aaSamw  * (SmbOpen, SmbOpenAndX) so the write calls (SmbWrite, SmbWriteAndClose,
225da6c28aaSamw  * SmbWriteAndUnlock) don't need to contain a write-through flag.
226da6c28aaSamw  *
227da6c28aaSamw  * With LM0.12, the open calls (SmbCreateAndX, SmbNtTransactCreate)
228da6c28aaSamw  * don't indicate which write-through mode to use. Instead the write
229da6c28aaSamw  * calls (SmbWriteAndX, SmbWriteRaw) specify the mode on a per call
230da6c28aaSamw  * basis.
231da6c28aaSamw  *
232da6c28aaSamw  * We don't care which open call was used to get us here, we just need
233da6c28aaSamw  * to ensure that the write-through mode flag is copied from the open
234da6c28aaSamw  * parameters to the node. We test the omode write-through flag in all
235da6c28aaSamw  * write functions.
236da6c28aaSamw  *
237da6c28aaSamw  * This function will return NT status codes but it also raises errors,
238da6c28aaSamw  * in which case it won't return to the caller. Be careful how you
239da6c28aaSamw  * handle things in here.
2408c10a865Sas200622  *
2418c10a865Sas200622  * The following rules apply when processing a file open request:
2428c10a865Sas200622  *
243cb174861Sjoyce mcintosh  * - Oplocks must be broken prior to share checking as the break may
244cb174861Sjoyce mcintosh  *   cause other clients to close the file, which would affect sharing
245cb174861Sjoyce mcintosh  *   checks.
2468c10a865Sas200622  *
2478c10a865Sas200622  * - Share checks must take place prior to access checks for correct
2488c10a865Sas200622  * Windows semantics and to prevent unnecessary NFS delegation recalls.
2498c10a865Sas200622  *
2508c10a865Sas200622  * - Oplocks must be acquired after open to ensure the correct
2518c10a865Sas200622  * synchronization with NFS delegation and FEM installation.
252c8ec8eeaSjose borrego  *
253c8ec8eeaSjose borrego  * DOS readonly bit rules
254c8ec8eeaSjose borrego  *
255c8ec8eeaSjose borrego  * 1. The creator of a readonly file can write to/modify the size of the file
256c8ec8eeaSjose borrego  * using the original create fid, even though the file will appear as readonly
257c8ec8eeaSjose borrego  * to all other fids and via a CIFS getattr call.
258037cac00Sjoyce mcintosh  * The readonly bit therefore cannot be set in the filesystem until the file
259037cac00Sjoyce mcintosh  * is closed (smb_ofile_close). It is accounted for via ofile and node flags.
260c8ec8eeaSjose borrego  *
261c8ec8eeaSjose borrego  * 2. A setinfo operation (using either an open fid or a path) to set/unset
262c8ec8eeaSjose borrego  * readonly will be successful regardless of whether a creator of a readonly
263c8ec8eeaSjose borrego  * file has an open fid (and has the special privilege mentioned in #1,
264c8ec8eeaSjose borrego  * above).  I.e., the creator of a readonly fid holding that fid will no longer
265c8ec8eeaSjose borrego  * have a special privilege.
266c8ec8eeaSjose borrego  *
267c8ec8eeaSjose borrego  * 3. The DOS readonly bit affects only data and some metadata.
268c8ec8eeaSjose borrego  * The following metadata can be changed regardless of the readonly bit:
269c8ec8eeaSjose borrego  * 	- security descriptors
270c8ec8eeaSjose borrego  *	- DOS attributes
271c8ec8eeaSjose borrego  *	- timestamps
272c8ec8eeaSjose borrego  *
273c8ec8eeaSjose borrego  * In the current implementation, the file size cannot be changed (except for
274c8ec8eeaSjose borrego  * the exceptions in #1 and #2, above).
2752c1b14e5Sjose borrego  *
2762c1b14e5Sjose borrego  *
2772c1b14e5Sjose borrego  * DOS attribute rules
2782c1b14e5Sjose borrego  *
2792c1b14e5Sjose borrego  * These rules are specific to creating / opening files and directories.
2802c1b14e5Sjose borrego  * How the attribute value (specifically ZERO or FILE_ATTRIBUTE_NORMAL)
2812c1b14e5Sjose borrego  * should be interpreted may differ in other requests.
2822c1b14e5Sjose borrego  *
2832c1b14e5Sjose borrego  * - An attribute value equal to ZERO or FILE_ATTRIBUTE_NORMAL means that the
2842c1b14e5Sjose borrego  *   file's attributes should be cleared.
2852c1b14e5Sjose borrego  * - If FILE_ATTRIBUTE_NORMAL is specified with any other attributes,
2862c1b14e5Sjose borrego  *   FILE_ATTRIBUTE_NORMAL is ignored.
2872c1b14e5Sjose borrego  *
2882c1b14e5Sjose borrego  * 1. Creating a new file
2892c1b14e5Sjose borrego  * - The request attributes + FILE_ATTRIBUTE_ARCHIVE are applied to the file.
2902c1b14e5Sjose borrego  *
2912c1b14e5Sjose borrego  * 2. Creating a new directory
2922c1b14e5Sjose borrego  * - The request attributes + FILE_ATTRIBUTE_DIRECTORY are applied to the file.
2932c1b14e5Sjose borrego  * - FILE_ATTRIBUTE_ARCHIVE does not get set.
2942c1b14e5Sjose borrego  *
2952c1b14e5Sjose borrego  * 3. Overwriting an existing file
2962c1b14e5Sjose borrego  * - the request attributes are used as search attributes. If the existing
2972c1b14e5Sjose borrego  *   file does not meet the search criteria access is denied.
2982c1b14e5Sjose borrego  * - otherwise, applies attributes + FILE_ATTRIBUTE_ARCHIVE.
2992c1b14e5Sjose borrego  *
3002c1b14e5Sjose borrego  * 4. Opening an existing file or directory
3012c1b14e5Sjose borrego  *    The request attributes are ignored.
302da6c28aaSamw  */
3037b59d02dSjb150015 static uint32_t
3047b59d02dSjb150015 smb_open_subr(smb_request_t *sr)
305da6c28aaSamw {
306eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	boolean_t	created = B_FALSE;
307eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	boolean_t	last_comp_found = B_FALSE;
3082c2961f8Sjose borrego 	smb_node_t	*node = NULL;
3092c2961f8Sjose borrego 	smb_node_t	*dnode = NULL;
310eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	smb_node_t	*cur_node = NULL;
311148c5f43SAlan Wright 	smb_arg_open_t	*op = &sr->sr_open;
312da6c28aaSamw 	int		rc;
3132c2961f8Sjose borrego 	smb_ofile_t	*of;
314da6c28aaSamw 	smb_attr_t	new_attr;
315da6c28aaSamw 	int		max_requested = 0;
316da6c28aaSamw 	uint32_t	max_allowed;
317da6c28aaSamw 	uint32_t	status = NT_STATUS_SUCCESS;
318da6c28aaSamw 	int		is_dir;
319da6c28aaSamw 	smb_error_t	err;
3202c2961f8Sjose borrego 	boolean_t	is_stream = B_FALSE;
321da6c28aaSamw 	int		lookup_flags = SMB_FOLLOW_LINKS;
322dc20a302Sas200622 	uint32_t	uniq_fid;
323eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	smb_pathname_t	*pn = &op->fqi.fq_path;
324cb174861Sjoyce mcintosh 	smb_server_t	*sv = sr->sr_server;
325da6c28aaSamw 
326da6c28aaSamw 	is_dir = (op->create_options & FILE_DIRECTORY_FILE) ? 1 : 0;
327da6c28aaSamw 
328da6c28aaSamw 	/*
329037cac00Sjoyce mcintosh 	 * If the object being created or opened is a directory
330037cac00Sjoyce mcintosh 	 * the Disposition parameter must be one of FILE_CREATE,
331037cac00Sjoyce mcintosh 	 * FILE_OPEN, or FILE_OPEN_IF
332da6c28aaSamw 	 */
333037cac00Sjoyce mcintosh 	if (is_dir) {
334da6c28aaSamw 		if ((op->create_disposition != FILE_CREATE) &&
335da6c28aaSamw 		    (op->create_disposition != FILE_OPEN_IF) &&
336da6c28aaSamw 		    (op->create_disposition != FILE_OPEN)) {
337dc20a302Sas200622 			smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
338da6c28aaSamw 			    ERRDOS, ERROR_INVALID_ACCESS);
3397b59d02dSjb150015 			return (NT_STATUS_INVALID_PARAMETER);
340da6c28aaSamw 		}
341da6c28aaSamw 	}
342da6c28aaSamw 
343da6c28aaSamw 	if (op->desired_access & MAXIMUM_ALLOWED) {
344da6c28aaSamw 		max_requested = 1;
345da6c28aaSamw 		op->desired_access &= ~MAXIMUM_ALLOWED;
346da6c28aaSamw 	}
347da6c28aaSamw 	op->desired_access = smb_access_generic_to_file(op->desired_access);
348da6c28aaSamw 
349da6c28aaSamw 	if (sr->session->s_file_cnt >= SMB_SESSION_OFILE_MAX) {
350da6c28aaSamw 		ASSERT(sr->uid_user);
351cb174861Sjoyce mcintosh 		cmn_err(CE_NOTE, "smbsrv[%s\\%s]: TOO_MANY_OPENED_FILES",
352148c5f43SAlan Wright 		    sr->uid_user->u_domain, sr->uid_user->u_name);
353da6c28aaSamw 
354dc20a302Sas200622 		smbsr_error(sr, NT_STATUS_TOO_MANY_OPENED_FILES,
355da6c28aaSamw 		    ERRDOS, ERROR_TOO_MANY_OPEN_FILES);
3567b59d02dSjb150015 		return (NT_STATUS_TOO_MANY_OPENED_FILES);
357da6c28aaSamw 	}
358da6c28aaSamw 
359da6c28aaSamw 	/* This must be NULL at this point */
360da6c28aaSamw 	sr->fid_ofile = NULL;
361da6c28aaSamw 
362da6c28aaSamw 	op->devstate = 0;
363da6c28aaSamw 
364da6c28aaSamw 	switch (sr->tid_tree->t_res_type & STYPE_MASK) {
365da6c28aaSamw 	case STYPE_DISKTREE:
366f96bd5c8SAlan Wright 	case STYPE_PRINTQ:
367da6c28aaSamw 		break;
368da6c28aaSamw 
369da6c28aaSamw 	case STYPE_IPC:
370cb174861Sjoyce mcintosh 
371cb174861Sjoyce mcintosh 		if ((rc = smb_threshold_enter(&sv->sv_opipe_ct)) != 0) {
372cb174861Sjoyce mcintosh 			status = RPC_NT_SERVER_TOO_BUSY;
373cb174861Sjoyce mcintosh 			smbsr_error(sr, status, 0, 0);
374cb174861Sjoyce mcintosh 			return (status);
375cb174861Sjoyce mcintosh 		}
376cb174861Sjoyce mcintosh 
377da6c28aaSamw 		/*
378da6c28aaSamw 		 * No further processing for IPC, we need to either
379da6c28aaSamw 		 * raise an exception or return success here.
380da6c28aaSamw 		 */
381*68b2bbf2SGordon Ross 		uniq_fid = SMB_UNIQ_FID();
382*68b2bbf2SGordon Ross 		status = smb_opipe_open(sr, uniq_fid);
383*68b2bbf2SGordon Ross 		if (status != NT_STATUS_SUCCESS)
3847b59d02dSjb150015 			smbsr_error(sr, status, 0, 0);
385cb174861Sjoyce mcintosh 
386856399cfSGordon Ross 		smb_threshold_exit(&sv->sv_opipe_ct);
3877b59d02dSjb150015 		return (status);
388da6c28aaSamw 
389da6c28aaSamw 	default:
3907b59d02dSjb150015 		smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE,
3917b59d02dSjb150015 		    ERRDOS, ERROR_BAD_DEV_TYPE);
3927b59d02dSjb150015 		return (NT_STATUS_BAD_DEVICE_TYPE);
393da6c28aaSamw 	}
394da6c28aaSamw 
395fe1c642dSBill Krier 	smb_pathname_init(sr, pn, pn->pn_path);
396fe1c642dSBill Krier 	if (!smb_pathname_validate(sr, pn))
397fe1c642dSBill Krier 		return (sr->smb_error.status);
398fe1c642dSBill Krier 
399fe1c642dSBill Krier 	if (strlen(pn->pn_path) >= MAXPATHLEN) {
400dc20a302Sas200622 		smbsr_error(sr, 0, ERRSRV, ERRfilespecs);
4017b59d02dSjb150015 		return (NT_STATUS_NAME_TOO_LONG);
402da6c28aaSamw 	}
403da6c28aaSamw 
404fe1c642dSBill Krier 	if (is_dir) {
405fe1c642dSBill Krier 		if (!smb_validate_dirname(sr, pn))
406fe1c642dSBill Krier 			return (sr->smb_error.status);
407fe1c642dSBill Krier 	} else {
408fe1c642dSBill Krier 		if (!smb_validate_object_name(sr, pn))
409fe1c642dSBill Krier 			return (sr->smb_error.status);
410da6c28aaSamw 	}
411da6c28aaSamw 
412eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	cur_node = op->fqi.fq_dnode ?
413eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	    op->fqi.fq_dnode : sr->tid_tree->t_snode;
414da6c28aaSamw 
415eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	/*
416eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	 * if no path or filename are specified the stream should be
417eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	 * created on cur_node
418eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	 */
419eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (!is_dir && !pn->pn_pname && !pn->pn_fname && pn->pn_sname) {
4209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		/*
4219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		 * Can't currently handle a stream on the tree root.
4229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		 * If a stream is being opened return "not found", otherwise
4239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		 * return "access denied".
4249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		 */
425eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		if (cur_node == sr->tid_tree->t_snode) {
4269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			if (op->create_disposition == FILE_OPEN) {
4279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				    ERRDOS, ERROR_FILE_NOT_FOUND);
4299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 				return (NT_STATUS_OBJECT_NAME_NOT_FOUND);
4309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			}
431eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
432eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			    ERROR_ACCESS_DENIED);
433eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			return (NT_STATUS_ACCESS_DENIED);
434eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		}
435eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 
436eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		(void) snprintf(op->fqi.fq_last_comp,
437eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		    sizeof (op->fqi.fq_last_comp),
438eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		    "%s%s", cur_node->od_name, pn->pn_sname);
439eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 
4401fcced4cSJordan Brown 		op->fqi.fq_dnode = cur_node->n_dnode;
441eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		smb_node_ref(op->fqi.fq_dnode);
442eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	} else {
443b819cea2SGordon Ross 		rc = smb_pathname_reduce(sr, sr->user_cr, pn->pn_path,
444eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		    sr->tid_tree->t_snode, cur_node, &op->fqi.fq_dnode,
445b819cea2SGordon Ross 		    op->fqi.fq_last_comp);
446b819cea2SGordon Ross 		if (rc != 0) {
447dc20a302Sas200622 			smbsr_errno(sr, rc);
4487b59d02dSjb150015 			return (sr->smb_error.status);
449da6c28aaSamw 		}
450eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	}
451da6c28aaSamw 
452da6c28aaSamw 	/*
453da6c28aaSamw 	 * If the access mask has only DELETE set (ignore
454da6c28aaSamw 	 * FILE_READ_ATTRIBUTES), then assume that this
455da6c28aaSamw 	 * is a request to delete the link (if a link)
456da6c28aaSamw 	 * and do not follow links.  Otherwise, follow
457da6c28aaSamw 	 * the link to the target.
458da6c28aaSamw 	 */
459037cac00Sjoyce mcintosh 	if ((op->desired_access & ~FILE_READ_ATTRIBUTES) == DELETE)
460da6c28aaSamw 		lookup_flags &= ~SMB_FOLLOW_LINKS;
461da6c28aaSamw 
4628622ec45SGordon Ross 	rc = smb_fsop_lookup_name(sr, zone_kcred(), lookup_flags,
463eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	    sr->tid_tree->t_snode, op->fqi.fq_dnode, op->fqi.fq_last_comp,
464037cac00Sjoyce mcintosh 	    &op->fqi.fq_fnode);
465da6c28aaSamw 
466da6c28aaSamw 	if (rc == 0) {
467eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		last_comp_found = B_TRUE;
4685fd03bc0SGordon Ross 		/*
4695fd03bc0SGordon Ross 		 * Need the DOS attributes below, where we
4705fd03bc0SGordon Ross 		 * check the search attributes (sattr).
4715fd03bc0SGordon Ross 		 */
4725fd03bc0SGordon Ross 		op->fqi.fq_fattr.sa_mask = SMB_AT_DOSATTR;
4738622ec45SGordon Ross 		rc = smb_node_getattr(sr, op->fqi.fq_fnode, zone_kcred(),
4745fd03bc0SGordon Ross 		    NULL, &op->fqi.fq_fattr);
475037cac00Sjoyce mcintosh 		if (rc != 0) {
476037cac00Sjoyce mcintosh 			smb_node_release(op->fqi.fq_fnode);
477037cac00Sjoyce mcintosh 			smb_node_release(op->fqi.fq_dnode);
478037cac00Sjoyce mcintosh 			smbsr_error(sr, NT_STATUS_INTERNAL_ERROR,
479037cac00Sjoyce mcintosh 			    ERRDOS, ERROR_INTERNAL_ERROR);
480037cac00Sjoyce mcintosh 			return (sr->smb_error.status);
481037cac00Sjoyce mcintosh 		}
482da6c28aaSamw 	} else if (rc == ENOENT) {
483eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		last_comp_found = B_FALSE;
484eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		op->fqi.fq_fnode = NULL;
485da6c28aaSamw 		rc = 0;
486da6c28aaSamw 	} else {
487eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		smb_node_release(op->fqi.fq_dnode);
488dc20a302Sas200622 		smbsr_errno(sr, rc);
4897b59d02dSjb150015 		return (sr->smb_error.status);
490da6c28aaSamw 	}
491da6c28aaSamw 
492037cac00Sjoyce mcintosh 
493dc20a302Sas200622 	/*
494dc20a302Sas200622 	 * The uniq_fid is a CIFS-server-wide unique identifier for an ofile
495dc20a302Sas200622 	 * which is used to uniquely identify open instances for the
496c8ec8eeaSjose borrego 	 * VFS share reservation and POSIX locks.
497dc20a302Sas200622 	 */
498dc20a302Sas200622 
499dc20a302Sas200622 	uniq_fid = SMB_UNIQ_FID();
500dc20a302Sas200622 
501eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (last_comp_found) {
5026537f381Sas200622 
5039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		node = op->fqi.fq_fnode;
5049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		dnode = op->fqi.fq_dnode;
5056537f381Sas200622 
5069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (!smb_node_is_file(node) && !smb_node_is_dir(node) &&
5079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    !smb_node_is_symlink(node)) {
5089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_node_release(node);
5099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smb_node_release(dnode);
5106537f381Sas200622 			smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
5116537f381Sas200622 			    ERRnoaccess);
5126537f381Sas200622 			return (NT_STATUS_ACCESS_DENIED);
5136537f381Sas200622 		}
5146537f381Sas200622 
515da6c28aaSamw 		/*
5162c1b14e5Sjose borrego 		 * Reject this request if either:
5172c1b14e5Sjose borrego 		 * - the target IS a directory and the client requires that
5182c1b14e5Sjose borrego 		 *   it must NOT be (required by Lotus Notes)
5192c1b14e5Sjose borrego 		 * - the target is NOT a directory and client requires that
5202c1b14e5Sjose borrego 		 *   it MUST be.
521da6c28aaSamw 		 */
5229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (smb_node_is_dir(node)) {
5232c1b14e5Sjose borrego 			if (op->create_options & FILE_NON_DIRECTORY_FILE) {
524da6c28aaSamw 				smb_node_release(node);
525da6c28aaSamw 				smb_node_release(dnode);
526dc20a302Sas200622 				smbsr_error(sr, NT_STATUS_FILE_IS_A_DIRECTORY,
527da6c28aaSamw 				    ERRDOS, ERROR_ACCESS_DENIED);
5287b59d02dSjb150015 				return (NT_STATUS_FILE_IS_A_DIRECTORY);
529da6c28aaSamw 			}
5302c1b14e5Sjose borrego 		} else {
5312c1b14e5Sjose borrego 			if ((op->create_options & FILE_DIRECTORY_FILE) ||
5322c2961f8Sjose borrego 			    (op->nt_flags & NT_CREATE_FLAG_OPEN_TARGET_DIR)) {
533da6c28aaSamw 				smb_node_release(node);
534da6c28aaSamw 				smb_node_release(dnode);
535dc20a302Sas200622 				smbsr_error(sr, NT_STATUS_NOT_A_DIRECTORY,
536da6c28aaSamw 				    ERRDOS, ERROR_DIRECTORY);
5377b59d02dSjb150015 				return (NT_STATUS_NOT_A_DIRECTORY);
538da6c28aaSamw 			}
5392c1b14e5Sjose borrego 		}
540da6c28aaSamw 
541da6c28aaSamw 		/*
542da6c28aaSamw 		 * No more open should be accepted when "Delete on close"
543da6c28aaSamw 		 * flag is set.
544da6c28aaSamw 		 */
545da6c28aaSamw 		if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
546da6c28aaSamw 			smb_node_release(node);
547da6c28aaSamw 			smb_node_release(dnode);
548dc20a302Sas200622 			smbsr_error(sr, NT_STATUS_DELETE_PENDING,
549da6c28aaSamw 			    ERRDOS, ERROR_ACCESS_DENIED);
5507b59d02dSjb150015 			return (NT_STATUS_DELETE_PENDING);
551da6c28aaSamw 		}
552da6c28aaSamw 
553da6c28aaSamw 		/*
554da6c28aaSamw 		 * Specified file already exists so the operation should fail.
555da6c28aaSamw 		 */
556da6c28aaSamw 		if (op->create_disposition == FILE_CREATE) {
557da6c28aaSamw 			smb_node_release(node);
558da6c28aaSamw 			smb_node_release(dnode);
559dc20a302Sas200622 			smbsr_error(sr, NT_STATUS_OBJECT_NAME_COLLISION,
560b89a8333Snatalie li - Sun Microsystems - Irvine United States 			    ERRDOS, ERROR_FILE_EXISTS);
5617b59d02dSjb150015 			return (NT_STATUS_OBJECT_NAME_COLLISION);
562da6c28aaSamw 		}
563da6c28aaSamw 
564da6c28aaSamw 		/*
565da6c28aaSamw 		 * Windows seems to check read-only access before file
566da6c28aaSamw 		 * sharing check.
567c8ec8eeaSjose borrego 		 *
568c8ec8eeaSjose borrego 		 * Check to see if the file is currently readonly (irrespective
569c8ec8eeaSjose borrego 		 * of whether this open will make it readonly).
570da6c28aaSamw 		 */
571c8ec8eeaSjose borrego 		if (SMB_PATHFILE_IS_READONLY(sr, node)) {
572da6c28aaSamw 			/* Files data only */
573037cac00Sjoyce mcintosh 			if (!smb_node_is_dir(node)) {
574da6c28aaSamw 				if (op->desired_access & (FILE_WRITE_DATA |
575da6c28aaSamw 				    FILE_APPEND_DATA)) {
576da6c28aaSamw 					smb_node_release(node);
577da6c28aaSamw 					smb_node_release(dnode);
578dc20a302Sas200622 					smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
579dc20a302Sas200622 					    ERRDOS, ERRnoaccess);
5807b59d02dSjb150015 					return (NT_STATUS_ACCESS_DENIED);
581da6c28aaSamw 				}
582da6c28aaSamw 			}
583da6c28aaSamw 		}
584da6c28aaSamw 
585dc20a302Sas200622 		if ((op->create_disposition == FILE_SUPERSEDE) ||
586dc20a302Sas200622 		    (op->create_disposition == FILE_OVERWRITE_IF) ||
587dc20a302Sas200622 		    (op->create_disposition == FILE_OVERWRITE)) {
588dc20a302Sas200622 
589fb699f1eSAlek Pinchuk 			if (!smb_sattr_check(op->fqi.fq_fattr.sa_dosattr,
590fb699f1eSAlek Pinchuk 			    op->dattr)) {
591dc20a302Sas200622 				smb_node_release(node);
592dc20a302Sas200622 				smb_node_release(dnode);
593dc20a302Sas200622 				smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
594dc20a302Sas200622 				    ERRDOS, ERRnoaccess);
5957b59d02dSjb150015 				return (NT_STATUS_ACCESS_DENIED);
596dc20a302Sas200622 			}
597dc20a302Sas200622 
598fb699f1eSAlek Pinchuk 			if (smb_node_is_dir(node)) {
599da6c28aaSamw 				smb_node_release(node);
600da6c28aaSamw 				smb_node_release(dnode);
601fb699f1eSAlek Pinchuk 				return (NT_STATUS_ACCESS_DENIED);
602da6c28aaSamw 			}
603fb699f1eSAlek Pinchuk 		}
604fb699f1eSAlek Pinchuk 
605fb699f1eSAlek Pinchuk 		/* MS-FSA 2.1.5.1.2 */
606fb699f1eSAlek Pinchuk 		if (op->create_disposition == FILE_SUPERSEDE)
607fb699f1eSAlek Pinchuk 			op->desired_access |= DELETE;
608fb699f1eSAlek Pinchuk 		if ((op->create_disposition == FILE_OVERWRITE_IF) ||
609fb699f1eSAlek Pinchuk 		    (op->create_disposition == FILE_OVERWRITE))
610fb699f1eSAlek Pinchuk 			op->desired_access |= FILE_WRITE_DATA;
611da6c28aaSamw 
612da6c28aaSamw 		status = smb_fsop_access(sr, sr->user_cr, node,
613da6c28aaSamw 		    op->desired_access);
614da6c28aaSamw 		if (status != NT_STATUS_SUCCESS) {
615da6c28aaSamw 			smb_node_release(node);
616da6c28aaSamw 			smb_node_release(dnode);
617dc20a302Sas200622 
618da6c28aaSamw 			if (status == NT_STATUS_PRIVILEGE_NOT_HELD) {
619dc20a302Sas200622 				smbsr_error(sr, status,
620dc20a302Sas200622 				    ERRDOS, ERROR_PRIVILEGE_NOT_HELD);
6217b59d02dSjb150015 				return (status);
622da6c28aaSamw 			} else {
623dc20a302Sas200622 				smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
624dc20a302Sas200622 				    ERRDOS, ERROR_ACCESS_DENIED);
6257b59d02dSjb150015 				return (NT_STATUS_ACCESS_DENIED);
626da6c28aaSamw 			}
627da6c28aaSamw 		}
628da6c28aaSamw 
629fb699f1eSAlek Pinchuk 		if (max_requested) {
630fb699f1eSAlek Pinchuk 			smb_fsop_eaccess(sr, sr->user_cr, node, &max_allowed);
631fb699f1eSAlek Pinchuk 			op->desired_access |= max_allowed;
632fb699f1eSAlek Pinchuk 		}
633fb699f1eSAlek Pinchuk 
634fb699f1eSAlek Pinchuk 		/*
635fb699f1eSAlek Pinchuk 		 * Oplock break is done prior to sharing checks as the break
636fb699f1eSAlek Pinchuk 		 * may cause other clients to close the file which would
637fb699f1eSAlek Pinchuk 		 * affect the sharing checks. This may block, so set the
638fb699f1eSAlek Pinchuk 		 * file opening count before oplock stuff.
639fb699f1eSAlek Pinchuk 		 */
640fb699f1eSAlek Pinchuk 		smb_node_inc_opening_count(node);
641fb699f1eSAlek Pinchuk 		smb_open_oplock_break(sr, node);
642fb699f1eSAlek Pinchuk 
643fb699f1eSAlek Pinchuk 		smb_node_wrlock(node);
644fb699f1eSAlek Pinchuk 
645fb699f1eSAlek Pinchuk 		/*
646fb699f1eSAlek Pinchuk 		 * Check for sharing violations
647fb699f1eSAlek Pinchuk 		 */
648fb699f1eSAlek Pinchuk 		status = smb_fsop_shrlock(sr->user_cr, node, uniq_fid,
649fb699f1eSAlek Pinchuk 		    op->desired_access, op->share_access);
650fb699f1eSAlek Pinchuk 		if (status == NT_STATUS_SHARING_VIOLATION) {
6512c2961f8Sjose borrego 			smb_node_unlock(node);
652cb174861Sjoyce mcintosh 			smb_node_dec_opening_count(node);
653da6c28aaSamw 			smb_node_release(node);
654da6c28aaSamw 			smb_node_release(dnode);
655fb699f1eSAlek Pinchuk 			return (status);
656da6c28aaSamw 		}
657da6c28aaSamw 
658fb699f1eSAlek Pinchuk 		/*
659fb699f1eSAlek Pinchuk 		 * Go ahead with modifications as necessary.
660fb699f1eSAlek Pinchuk 		 */
661fb699f1eSAlek Pinchuk 		switch (op->create_disposition) {
662fb699f1eSAlek Pinchuk 		case FILE_SUPERSEDE:
663fb699f1eSAlek Pinchuk 		case FILE_OVERWRITE_IF:
664fb699f1eSAlek Pinchuk 		case FILE_OVERWRITE:
665037cac00Sjoyce mcintosh 			op->dattr |= FILE_ATTRIBUTE_ARCHIVE;
666037cac00Sjoyce mcintosh 			/* Don't apply readonly bit until smb_ofile_close */
667037cac00Sjoyce mcintosh 			if (op->dattr & FILE_ATTRIBUTE_READONLY) {
668037cac00Sjoyce mcintosh 				op->created_readonly = B_TRUE;
669037cac00Sjoyce mcintosh 				op->dattr &= ~FILE_ATTRIBUTE_READONLY;
670037cac00Sjoyce mcintosh 			}
671037cac00Sjoyce mcintosh 
672dc20a302Sas200622 			bzero(&new_attr, sizeof (new_attr));
673037cac00Sjoyce mcintosh 			new_attr.sa_dosattr = op->dattr;
674da6c28aaSamw 			new_attr.sa_vattr.va_size = op->dsize;
675037cac00Sjoyce mcintosh 			new_attr.sa_mask = SMB_AT_DOSATTR | SMB_AT_SIZE;
676037cac00Sjoyce mcintosh 			rc = smb_fsop_setattr(sr, sr->user_cr, node, &new_attr);
677037cac00Sjoyce mcintosh 			if (rc != 0) {
678037cac00Sjoyce mcintosh 				smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
6792c2961f8Sjose borrego 				smb_node_unlock(node);
680cb174861Sjoyce mcintosh 				smb_node_dec_opening_count(node);
681da6c28aaSamw 				smb_node_release(node);
682da6c28aaSamw 				smb_node_release(dnode);
683dc20a302Sas200622 				smbsr_errno(sr, rc);
6847b59d02dSjb150015 				return (sr->smb_error.status);
685da6c28aaSamw 			}
686da6c28aaSamw 
687da6c28aaSamw 			/*
688037cac00Sjoyce mcintosh 			 * If file is being replaced, remove existing streams
689da6c28aaSamw 			 */
690eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			if (SMB_IS_STREAM(node) == 0) {
691037cac00Sjoyce mcintosh 				rc = smb_fsop_remove_streams(sr, sr->user_cr,
692037cac00Sjoyce mcintosh 				    node);
693037cac00Sjoyce mcintosh 				if (rc != 0) {
694eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 					smb_fsop_unshrlock(sr->user_cr, node,
695eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 					    uniq_fid);
696eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 					smb_node_unlock(node);
697cb174861Sjoyce mcintosh 					smb_node_dec_opening_count(node);
698eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 					smb_node_release(node);
699eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 					smb_node_release(dnode);
700eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 					return (sr->smb_error.status);
701eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 				}
702eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			}
703da6c28aaSamw 
704da6c28aaSamw 			op->action_taken = SMB_OACT_TRUNCATED;
705da6c28aaSamw 			break;
706da6c28aaSamw 
707da6c28aaSamw 		default:
708da6c28aaSamw 			/*
709da6c28aaSamw 			 * FILE_OPEN or FILE_OPEN_IF.
710da6c28aaSamw 			 */
711da6c28aaSamw 			op->action_taken = SMB_OACT_OPENED;
712da6c28aaSamw 			break;
713da6c28aaSamw 		}
714da6c28aaSamw 	} else {
715da6c28aaSamw 		/* Last component was not found. */
716eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		dnode = op->fqi.fq_dnode;
717da6c28aaSamw 
7187b59d02dSjb150015 		if (is_dir == 0)
719eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			is_stream = smb_is_stream_name(pn->pn_path);
7207b59d02dSjb150015 
721da6c28aaSamw 		if ((op->create_disposition == FILE_OPEN) ||
722da6c28aaSamw 		    (op->create_disposition == FILE_OVERWRITE)) {
723da6c28aaSamw 			smb_node_release(dnode);
724dc20a302Sas200622 			smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND,
725da6c28aaSamw 			    ERRDOS, ERROR_FILE_NOT_FOUND);
7267b59d02dSjb150015 			return (NT_STATUS_OBJECT_NAME_NOT_FOUND);
727da6c28aaSamw 		}
728da6c28aaSamw 
7299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if (pn->pn_fname && smb_is_invalid_filename(pn->pn_fname)) {
7302c2961f8Sjose borrego 			smb_node_release(dnode);
7312c2961f8Sjose borrego 			smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
7322c2961f8Sjose borrego 			    ERRDOS, ERROR_INVALID_NAME);
7332c2961f8Sjose borrego 			return (NT_STATUS_OBJECT_NAME_INVALID);
7342c2961f8Sjose borrego 		}
7352c2961f8Sjose borrego 
736da6c28aaSamw 		/*
737da6c28aaSamw 		 * lock the parent dir node in case another create
738da6c28aaSamw 		 * request to the same parent directory comes in.
739da6c28aaSamw 		 */
7402c2961f8Sjose borrego 		smb_node_wrlock(dnode);
741da6c28aaSamw 
742037cac00Sjoyce mcintosh 		/* Don't apply readonly bit until smb_ofile_close */
743037cac00Sjoyce mcintosh 		if (op->dattr & FILE_ATTRIBUTE_READONLY) {
744037cac00Sjoyce mcintosh 			op->dattr &= ~FILE_ATTRIBUTE_READONLY;
745037cac00Sjoyce mcintosh 			op->created_readonly = B_TRUE;
746037cac00Sjoyce mcintosh 		}
747037cac00Sjoyce mcintosh 
748da6c28aaSamw 		bzero(&new_attr, sizeof (new_attr));
749c8ec8eeaSjose borrego 		if ((op->crtime.tv_sec != 0) &&
750c8ec8eeaSjose borrego 		    (op->crtime.tv_sec != UINT_MAX)) {
751c8ec8eeaSjose borrego 
752c8ec8eeaSjose borrego 			new_attr.sa_mask |= SMB_AT_CRTIME;
753c8ec8eeaSjose borrego 			new_attr.sa_crtime = op->crtime;
754c8ec8eeaSjose borrego 		}
755c8ec8eeaSjose borrego 
756da6c28aaSamw 		if (is_dir == 0) {
757037cac00Sjoyce mcintosh 			op->dattr |= FILE_ATTRIBUTE_ARCHIVE;
758037cac00Sjoyce mcintosh 			new_attr.sa_dosattr = op->dattr;
759da6c28aaSamw 			new_attr.sa_vattr.va_type = VREG;
7607b59d02dSjb150015 			new_attr.sa_vattr.va_mode = is_stream ? S_IRUSR :
7617b59d02dSjb150015 			    S_IRUSR | S_IRGRP | S_IROTH |
7627b59d02dSjb150015 			    S_IWUSR | S_IWGRP | S_IWOTH;
763037cac00Sjoyce mcintosh 			new_attr.sa_mask |=
764037cac00Sjoyce mcintosh 			    SMB_AT_DOSATTR | SMB_AT_TYPE | SMB_AT_MODE;
765dc20a302Sas200622 
7666537f381Sas200622 			if (op->dsize) {
7676537f381Sas200622 				new_attr.sa_vattr.va_size = op->dsize;
7686537f381Sas200622 				new_attr.sa_mask |= SMB_AT_SIZE;
769dc20a302Sas200622 			}
770dc20a302Sas200622 
771da6c28aaSamw 			rc = smb_fsop_create(sr, sr->user_cr, dnode,
772037cac00Sjoyce mcintosh 			    op->fqi.fq_last_comp, &new_attr, &op->fqi.fq_fnode);
773dc20a302Sas200622 
774da6c28aaSamw 			if (rc != 0) {
7752c2961f8Sjose borrego 				smb_node_unlock(dnode);
776da6c28aaSamw 				smb_node_release(dnode);
777dc20a302Sas200622 				smbsr_errno(sr, rc);
7787b59d02dSjb150015 				return (sr->smb_error.status);
779da6c28aaSamw 			}
780da6c28aaSamw 
781eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			node = op->fqi.fq_fnode;
782cb174861Sjoyce mcintosh 			smb_node_inc_opening_count(node);
7832c2961f8Sjose borrego 			smb_node_wrlock(node);
784dc20a302Sas200622 
785faa1795aSjb150015 			status = smb_fsop_shrlock(sr->user_cr, node, uniq_fid,
786c8ec8eeaSjose borrego 			    op->desired_access, op->share_access);
787dc20a302Sas200622 
788dc20a302Sas200622 			if (status == NT_STATUS_SHARING_VIOLATION) {
7892c2961f8Sjose borrego 				smb_node_unlock(node);
790cb174861Sjoyce mcintosh 				smb_node_dec_opening_count(node);
7918b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 				smb_delete_new_object(sr);
792dc20a302Sas200622 				smb_node_release(node);
7932c2961f8Sjose borrego 				smb_node_unlock(dnode);
794dc20a302Sas200622 				smb_node_release(dnode);
795dc20a302Sas200622 				return (status);
796dc20a302Sas200622 			}
797da6c28aaSamw 		} else {
7983db3f65cSamw 			op->dattr |= FILE_ATTRIBUTE_DIRECTORY;
799037cac00Sjoyce mcintosh 			new_attr.sa_dosattr = op->dattr;
800da6c28aaSamw 			new_attr.sa_vattr.va_type = VDIR;
801da6c28aaSamw 			new_attr.sa_vattr.va_mode = 0777;
802037cac00Sjoyce mcintosh 			new_attr.sa_mask |=
803037cac00Sjoyce mcintosh 			    SMB_AT_DOSATTR | SMB_AT_TYPE | SMB_AT_MODE;
804c8ec8eeaSjose borrego 
805da6c28aaSamw 			rc = smb_fsop_mkdir(sr, sr->user_cr, dnode,
806037cac00Sjoyce mcintosh 			    op->fqi.fq_last_comp, &new_attr, &op->fqi.fq_fnode);
807da6c28aaSamw 			if (rc != 0) {
8082c2961f8Sjose borrego 				smb_node_unlock(dnode);
809da6c28aaSamw 				smb_node_release(dnode);
810dc20a302Sas200622 				smbsr_errno(sr, rc);
8117b59d02dSjb150015 				return (sr->smb_error.status);
812da6c28aaSamw 			}
813dc20a302Sas200622 
814eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			node = op->fqi.fq_fnode;
815cb174861Sjoyce mcintosh 			smb_node_inc_opening_count(node);
8162c2961f8Sjose borrego 			smb_node_wrlock(node);
817da6c28aaSamw 		}
818da6c28aaSamw 
819eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		created = B_TRUE;
820da6c28aaSamw 		op->action_taken = SMB_OACT_CREATED;
821c8ec8eeaSjose borrego 
8222c1b14e5Sjose borrego 		if (max_requested) {
8232c1b14e5Sjose borrego 			smb_fsop_eaccess(sr, sr->user_cr, node, &max_allowed);
8242c1b14e5Sjose borrego 			op->desired_access |= max_allowed;
8252c1b14e5Sjose borrego 		}
826fb699f1eSAlek Pinchuk 	}
8272c1b14e5Sjose borrego 
828037cac00Sjoyce mcintosh 	status = NT_STATUS_SUCCESS;
8292c1b14e5Sjose borrego 
830*68b2bbf2SGordon Ross 	of = smb_ofile_open(sr, node, op, SMB_FTYPE_DISK, uniq_fid,
8313b13a1efSThomas Keiser 	    &err);
832da6c28aaSamw 	if (of == NULL) {
833dc20a302Sas200622 		smbsr_error(sr, err.status, err.errcls, err.errcode);
834037cac00Sjoyce mcintosh 		status = err.status;
835da6c28aaSamw 	}
836da6c28aaSamw 
837*68b2bbf2SGordon Ross 	/*
838*68b2bbf2SGordon Ross 	 * We might have blocked in smb_ofile_open long enough so a
839*68b2bbf2SGordon Ross 	 * tree disconnect might have happened.  In that case, we've
840*68b2bbf2SGordon Ross 	 * just added an ofile to a tree that's disconnecting, and
841*68b2bbf2SGordon Ross 	 * need to undo that to avoid interfering with tear-down of
842*68b2bbf2SGordon Ross 	 * the tree connection.
843*68b2bbf2SGordon Ross 	 */
844*68b2bbf2SGordon Ross 	if (status == NT_STATUS_SUCCESS &&
845*68b2bbf2SGordon Ross 	    !smb_tree_is_connected(sr->tid_tree)) {
846037cac00Sjoyce mcintosh 		smbsr_error(sr, 0, ERRSRV, ERRinvnid);
847*68b2bbf2SGordon Ross 		status = NT_STATUS_INVALID_PARAMETER;
848037cac00Sjoyce mcintosh 	}
849037cac00Sjoyce mcintosh 
850037cac00Sjoyce mcintosh 	/*
851037cac00Sjoyce mcintosh 	 * This MUST be done after ofile creation, so that explicitly
8525fd03bc0SGordon Ross 	 * set timestamps can be remembered on the ofile, and the
8535fd03bc0SGordon Ross 	 * readonly flag will be stored "pending" on the node.
854037cac00Sjoyce mcintosh 	 */
855037cac00Sjoyce mcintosh 	if (status == NT_STATUS_SUCCESS) {
8565fd03bc0SGordon Ross 		if ((rc = smb_set_open_attributes(sr, of)) != 0) {
857037cac00Sjoyce mcintosh 			smbsr_errno(sr, rc);
858037cac00Sjoyce mcintosh 			status = sr->smb_error.status;
859037cac00Sjoyce mcintosh 		}
860037cac00Sjoyce mcintosh 	}
861037cac00Sjoyce mcintosh 
862037cac00Sjoyce mcintosh 	if (status == NT_STATUS_SUCCESS) {
8635fd03bc0SGordon Ross 		/*
8645fd03bc0SGordon Ross 		 * We've already done access checks above,
8655fd03bc0SGordon Ross 		 * and want this call to succeed even when
8665fd03bc0SGordon Ross 		 * !(desired_access & FILE_READ_ATTRIBUTES),
8675fd03bc0SGordon Ross 		 * so pass kcred here.
8685fd03bc0SGordon Ross 		 */
8695fd03bc0SGordon Ross 		op->fqi.fq_fattr.sa_mask = SMB_AT_ALL;
8708622ec45SGordon Ross 		rc = smb_node_getattr(sr, node, zone_kcred(), of,
8715fd03bc0SGordon Ross 		    &op->fqi.fq_fattr);
8725fd03bc0SGordon Ross 		if (rc != 0) {
873037cac00Sjoyce mcintosh 			smbsr_error(sr, NT_STATUS_INTERNAL_ERROR,
874037cac00Sjoyce mcintosh 			    ERRDOS, ERROR_INTERNAL_ERROR);
875037cac00Sjoyce mcintosh 			status = NT_STATUS_INTERNAL_ERROR;
876037cac00Sjoyce mcintosh 		}
877037cac00Sjoyce mcintosh 	}
878037cac00Sjoyce mcintosh 
879037cac00Sjoyce mcintosh 	/*
880037cac00Sjoyce mcintosh 	 * smb_fsop_unshrlock is a no-op if node is a directory
881037cac00Sjoyce mcintosh 	 * smb_fsop_unshrlock is done in smb_ofile_close
882037cac00Sjoyce mcintosh 	 */
883037cac00Sjoyce mcintosh 	if (status != NT_STATUS_SUCCESS) {
884037cac00Sjoyce mcintosh 		if (of == NULL) {
885037cac00Sjoyce mcintosh 			smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
886037cac00Sjoyce mcintosh 		} else {
8878b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 			smb_ofile_close(of, 0);
8888b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 			smb_ofile_release(of);
889037cac00Sjoyce mcintosh 		}
8908b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		if (created)
8918b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 			smb_delete_new_object(sr);
8928b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		smb_node_unlock(node);
893cb174861Sjoyce mcintosh 		smb_node_dec_opening_count(node);
8948b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		smb_node_release(node);
8958b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		if (created)
8968b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 			smb_node_unlock(dnode);
8978b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		smb_node_release(dnode);
898037cac00Sjoyce mcintosh 		return (status);
8998b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	}
9008b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
9018c10a865Sas200622 	/*
9028c10a865Sas200622 	 * Propagate the write-through mode from the open params
9038c10a865Sas200622 	 * to the node: see the notes in the function header.
9048c10a865Sas200622 	 */
9058c10a865Sas200622 	if (sr->sr_cfg->skc_sync_enable ||
9068c10a865Sas200622 	    (op->create_options & FILE_WRITE_THROUGH))
9078c10a865Sas200622 		node->flags |= NODE_FLAGS_WRITE_THROUGH;
9088c10a865Sas200622 
909037cac00Sjoyce mcintosh 	/*
910037cac00Sjoyce mcintosh 	 * Set up the fileid and dosattr in open_param for response
911037cac00Sjoyce mcintosh 	 */
912eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	op->fileid = op->fqi.fq_fattr.sa_vattr.va_nodeid;
913037cac00Sjoyce mcintosh 	op->dattr = op->fqi.fq_fattr.sa_dosattr;
9148c10a865Sas200622 
915da6c28aaSamw 	/*
916da6c28aaSamw 	 * Set up the file type in open_param for the response
917da6c28aaSamw 	 */
918da6c28aaSamw 	op->ftype = SMB_FTYPE_DISK;
919da6c28aaSamw 	sr->smb_fid = of->f_fid;
920da6c28aaSamw 	sr->fid_ofile = of;
921da6c28aaSamw 
9229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_node_is_file(node)) {
923cb174861Sjoyce mcintosh 		smb_oplock_acquire(sr, node, of);
924eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		op->dsize = op->fqi.fq_fattr.sa_vattr.va_size;
9259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	} else {
9269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		/* directory or symlink */
9272c2961f8Sjose borrego 		op->op_oplock_level = SMB_OPLOCK_NONE;
9282c2961f8Sjose borrego 		op->dsize = 0;
9292c2961f8Sjose borrego 	}
930dc20a302Sas200622 
931cb174861Sjoyce mcintosh 	smb_node_dec_opening_count(node);
932cb174861Sjoyce mcintosh 
933cb174861Sjoyce mcintosh 	smb_node_unlock(node);
934cb174861Sjoyce mcintosh 	if (created)
935cb174861Sjoyce mcintosh 		smb_node_unlock(dnode);
936cb174861Sjoyce mcintosh 
9378b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	smb_node_release(node);
938da6c28aaSamw 	smb_node_release(dnode);
939da6c28aaSamw 
940da6c28aaSamw 	return (NT_STATUS_SUCCESS);
941da6c28aaSamw }
942da6c28aaSamw 
943da6c28aaSamw /*
944cb174861Sjoyce mcintosh  * smb_open_oplock_break
945cb174861Sjoyce mcintosh  *
946cb174861Sjoyce mcintosh  * If the node has an ofile opened with share access none,
947cb174861Sjoyce mcintosh  * (smb_node_share_check = FALSE) only break BATCH oplock.
948cb174861Sjoyce mcintosh  * Otherwise:
949cb174861Sjoyce mcintosh  * If overwriting, break to SMB_OPLOCK_NONE, else
950cb174861Sjoyce mcintosh  * If opening for anything other than attribute access,
951cb174861Sjoyce mcintosh  * break oplock to LEVEL_II.
952cb174861Sjoyce mcintosh  */
953cb174861Sjoyce mcintosh static void
954cb174861Sjoyce mcintosh smb_open_oplock_break(smb_request_t *sr, smb_node_t *node)
955cb174861Sjoyce mcintosh {
956cb174861Sjoyce mcintosh 	smb_arg_open_t	*op = &sr->sr_open;
957cb174861Sjoyce mcintosh 	uint32_t	flags = 0;
958cb174861Sjoyce mcintosh 
959cb174861Sjoyce mcintosh 	if (!smb_node_share_check(node))
960cb174861Sjoyce mcintosh 		flags |= SMB_OPLOCK_BREAK_BATCH;
961cb174861Sjoyce mcintosh 
962cb174861Sjoyce mcintosh 	if (smb_open_overwrite(op)) {
963cb174861Sjoyce mcintosh 		flags |= SMB_OPLOCK_BREAK_TO_NONE;
964cb174861Sjoyce mcintosh 		(void) smb_oplock_break(sr, node, flags);
965cb174861Sjoyce mcintosh 	} else if (!smb_open_attr_only(op)) {
966cb174861Sjoyce mcintosh 		flags |= SMB_OPLOCK_BREAK_TO_LEVEL_II;
967cb174861Sjoyce mcintosh 		(void) smb_oplock_break(sr, node, flags);
968cb174861Sjoyce mcintosh 	}
969cb174861Sjoyce mcintosh }
970cb174861Sjoyce mcintosh 
971cb174861Sjoyce mcintosh /*
972cb174861Sjoyce mcintosh  * smb_open_attr_only
973cb174861Sjoyce mcintosh  *
974cb174861Sjoyce mcintosh  * Determine if file is being opened for attribute access only.
975cb174861Sjoyce mcintosh  * This is used to determine whether it is necessary to break
976cb174861Sjoyce mcintosh  * existing oplocks on the file.
977cb174861Sjoyce mcintosh  */
978cb174861Sjoyce mcintosh static boolean_t
979cb174861Sjoyce mcintosh smb_open_attr_only(smb_arg_open_t *op)
980cb174861Sjoyce mcintosh {
981cb174861Sjoyce mcintosh 	if (((op->desired_access & ~(FILE_READ_ATTRIBUTES |
982fb699f1eSAlek Pinchuk 	    FILE_WRITE_ATTRIBUTES | SYNCHRONIZE | READ_CONTROL)) == 0) &&
983cb174861Sjoyce mcintosh 	    (op->create_disposition != FILE_SUPERSEDE) &&
984cb174861Sjoyce mcintosh 	    (op->create_disposition != FILE_OVERWRITE)) {
985cb174861Sjoyce mcintosh 		return (B_TRUE);
986cb174861Sjoyce mcintosh 	}
987cb174861Sjoyce mcintosh 	return (B_FALSE);
988cb174861Sjoyce mcintosh }
989cb174861Sjoyce mcintosh 
990cb174861Sjoyce mcintosh static boolean_t
991cb174861Sjoyce mcintosh smb_open_overwrite(smb_arg_open_t *op)
992cb174861Sjoyce mcintosh {
993cb174861Sjoyce mcintosh 	if ((op->create_disposition == FILE_SUPERSEDE) ||
994cb174861Sjoyce mcintosh 	    (op->create_disposition == FILE_OVERWRITE_IF) ||
995cb174861Sjoyce mcintosh 	    (op->create_disposition == FILE_OVERWRITE)) {
996cb174861Sjoyce mcintosh 		return (B_TRUE);
997cb174861Sjoyce mcintosh 	}
998cb174861Sjoyce mcintosh 	return (B_FALSE);
999cb174861Sjoyce mcintosh }
10005fd03bc0SGordon Ross 
1001cb174861Sjoyce mcintosh /*
10025fd03bc0SGordon Ross  * smb_set_open_attributes
1003037cac00Sjoyce mcintosh  *
1004037cac00Sjoyce mcintosh  * Last write time:
1005037cac00Sjoyce mcintosh  * - If the last_write time specified in the open params is not 0 or -1,
1006037cac00Sjoyce mcintosh  *   use it as file's mtime. This will be considered an explicitly set
1007037cac00Sjoyce mcintosh  *   timestamps, not reset by subsequent writes.
1008037cac00Sjoyce mcintosh  *
10095fd03bc0SGordon Ross  * DOS attributes
10105fd03bc0SGordon Ross  * - If we created_readonly, we now store the real DOS attributes
10115fd03bc0SGordon Ross  *   (including the readonly bit) so subsequent opens will see it.
1012037cac00Sjoyce mcintosh  *
10135fd03bc0SGordon Ross  * Both are stored "pending" rather than in the file system.
1014037cac00Sjoyce mcintosh  *
1015037cac00Sjoyce mcintosh  * Returns: errno
1016037cac00Sjoyce mcintosh  */
1017037cac00Sjoyce mcintosh static int
10185fd03bc0SGordon Ross smb_set_open_attributes(smb_request_t *sr, smb_ofile_t *of)
1019037cac00Sjoyce mcintosh {
10205fd03bc0SGordon Ross 	smb_attr_t	attr;
1021148c5f43SAlan Wright 	smb_arg_open_t	*op = &sr->sr_open;
1022037cac00Sjoyce mcintosh 	smb_node_t	*node = of->f_node;
10235fd03bc0SGordon Ross 	int		rc = 0;
1024037cac00Sjoyce mcintosh 
1025037cac00Sjoyce mcintosh 	bzero(&attr, sizeof (smb_attr_t));
10265fd03bc0SGordon Ross 
10275fd03bc0SGordon Ross 	if (op->created_readonly) {
10285fd03bc0SGordon Ross 		attr.sa_dosattr = op->dattr | FILE_ATTRIBUTE_READONLY;
10295fd03bc0SGordon Ross 		attr.sa_mask |= SMB_AT_DOSATTR;
10305fd03bc0SGordon Ross 	}
1031037cac00Sjoyce mcintosh 
1032037cac00Sjoyce mcintosh 	if ((op->mtime.tv_sec != 0) && (op->mtime.tv_sec != UINT_MAX)) {
1033037cac00Sjoyce mcintosh 		attr.sa_vattr.va_mtime = op->mtime;
10345fd03bc0SGordon Ross 		attr.sa_mask |= SMB_AT_MTIME;
1035037cac00Sjoyce mcintosh 	}
1036037cac00Sjoyce mcintosh 
10375fd03bc0SGordon Ross 	/*
10385fd03bc0SGordon Ross 	 * Used to have code here to set mtime, ctime, atime
10395fd03bc0SGordon Ross 	 * when the open op->create_disposition is any of:
10405fd03bc0SGordon Ross 	 * FILE_SUPERSEDE, FILE_OVERWRITE_IF, FILE_OVERWRITE.
10415fd03bc0SGordon Ross 	 * We know that in those cases we will have set the
10425fd03bc0SGordon Ross 	 * file size, in which case the file system will
10435fd03bc0SGordon Ross 	 * update those times, so we don't have to.
10445fd03bc0SGordon Ross 	 *
10455fd03bc0SGordon Ross 	 * However, keep track of the fact that we modified
10465fd03bc0SGordon Ross 	 * the file via this handle, so we can do the evil,
10475fd03bc0SGordon Ross 	 * gratuitious mtime update on close that Windows
10485fd03bc0SGordon Ross 	 * clients appear to expect.
10495fd03bc0SGordon Ross 	 */
10505fd03bc0SGordon Ross 	if (op->action_taken == SMB_OACT_TRUNCATED)
10515fd03bc0SGordon Ross 		of->f_written = B_TRUE;
1052037cac00Sjoyce mcintosh 
10535fd03bc0SGordon Ross 	if (attr.sa_mask != 0)
10545fd03bc0SGordon Ross 		rc = smb_node_setattr(sr, node, of->f_cr, of, &attr);
1055037cac00Sjoyce mcintosh 
1056037cac00Sjoyce mcintosh 	return (rc);
1057037cac00Sjoyce mcintosh }
1058037cac00Sjoyce mcintosh 
1059037cac00Sjoyce mcintosh /*
10608b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * This function is used to delete a newly created object (file or
10618b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * directory) if an error occurs after creation of the object.
1062da6c28aaSamw  */
10638b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States static void
10648b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_delete_new_object(smb_request_t *sr)
1065da6c28aaSamw {
1066148c5f43SAlan Wright 	smb_arg_open_t	*op = &sr->sr_open;
10678b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	smb_fqi_t	*fqi = &(op->fqi);
10688b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t	flags = 0;
10698b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
10708b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (SMB_TREE_IS_CASEINSENSITIVE(sr))
10718b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		flags |= SMB_IGNORE_CASE;
10728b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (SMB_TREE_SUPPORTS_CATIA(sr))
10738b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		flags |= SMB_CATIA;
10748b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
10758b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (op->create_options & FILE_DIRECTORY_FILE)
1076eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		(void) smb_fsop_rmdir(sr, sr->user_cr, fqi->fq_dnode,
1077eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		    fqi->fq_last_comp, flags);
10788b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	else
1079eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		(void) smb_fsop_remove(sr, sr->user_cr, fqi->fq_dnode,
1080eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		    fqi->fq_last_comp, flags);
1081eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States }
1082