xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_common_open.c (revision eb1d736b1c19f6abeee90c921a9320b67fedd016)
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  */
21da6c28aaSamw /*
227f667e74Sjose borrego  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23da6c28aaSamw  * Use is subject to license terms.
24da6c28aaSamw  */
25da6c28aaSamw 
26da6c28aaSamw /*
27da6c28aaSamw  * This module provides the common open functionality to the various
28da6c28aaSamw  * open and create SMB interface functions.
29da6c28aaSamw  */
30da6c28aaSamw 
31da6c28aaSamw #include <smbsrv/smb_incl.h>
32da6c28aaSamw #include <smbsrv/smb_fsops.h>
33da6c28aaSamw #include <smbsrv/nterror.h>
34da6c28aaSamw #include <smbsrv/ntstatus.h>
35da6c28aaSamw #include <smbsrv/smbinfo.h>
36da6c28aaSamw #include <sys/fcntl.h>
37dc20a302Sas200622 #include <sys/nbmlock.h>
38da6c28aaSamw 
39faa1795aSjb150015 volatile uint32_t smb_fids = 0;
407b59d02dSjb150015 
417b59d02dSjb150015 static uint32_t smb_open_subr(smb_request_t *);
42faa1795aSjb150015 extern uint32_t smb_is_executable(char *);
438b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States static void smb_delete_new_object(smb_request_t *);
44da6c28aaSamw 
45*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States static char *smb_pathname_strdup(smb_request_t *, const char *);
46*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States static char *smb_pathname_strcat(char *, const char *);
47*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 
48da6c28aaSamw /*
49da6c28aaSamw  * smb_access_generic_to_file
50da6c28aaSamw  *
51da6c28aaSamw  * Search MSDN for IoCreateFile to see following mapping.
52da6c28aaSamw  *
53da6c28aaSamw  * GENERIC_READ		STANDARD_RIGHTS_READ, FILE_READ_DATA,
54da6c28aaSamw  *			FILE_READ_ATTRIBUTES and FILE_READ_EA
55da6c28aaSamw  *
56da6c28aaSamw  * GENERIC_WRITE	STANDARD_RIGHTS_WRITE, FILE_WRITE_DATA,
57da6c28aaSamw  *               FILE_WRITE_ATTRIBUTES, FILE_WRITE_EA, and FILE_APPEND_DATA
58da6c28aaSamw  *
59da6c28aaSamw  * GENERIC_EXECUTE	STANDARD_RIGHTS_EXECUTE, SYNCHRONIZE, and FILE_EXECUTE.
60da6c28aaSamw  */
61da6c28aaSamw uint32_t
62da6c28aaSamw smb_access_generic_to_file(uint32_t desired_access)
63da6c28aaSamw {
64da6c28aaSamw 	uint32_t access = 0;
65da6c28aaSamw 
66da6c28aaSamw 	if (desired_access & GENERIC_ALL)
67da6c28aaSamw 		return (FILE_ALL_ACCESS & ~SYNCHRONIZE);
68da6c28aaSamw 
69da6c28aaSamw 	if (desired_access & GENERIC_EXECUTE) {
70da6c28aaSamw 		desired_access &= ~GENERIC_EXECUTE;
71da6c28aaSamw 		access |= (STANDARD_RIGHTS_EXECUTE |
72da6c28aaSamw 		    SYNCHRONIZE | FILE_EXECUTE);
73da6c28aaSamw 	}
74da6c28aaSamw 
75da6c28aaSamw 	if (desired_access & GENERIC_WRITE) {
76da6c28aaSamw 		desired_access &= ~GENERIC_WRITE;
77da6c28aaSamw 		access |= (FILE_GENERIC_WRITE & ~SYNCHRONIZE);
78da6c28aaSamw 	}
79da6c28aaSamw 
80da6c28aaSamw 	if (desired_access & GENERIC_READ) {
81da6c28aaSamw 		desired_access &= ~GENERIC_READ;
82da6c28aaSamw 		access |= FILE_GENERIC_READ;
83da6c28aaSamw 	}
84da6c28aaSamw 
85da6c28aaSamw 	return (access | desired_access);
86da6c28aaSamw }
87da6c28aaSamw 
88da6c28aaSamw /*
89da6c28aaSamw  * smb_omode_to_amask
90da6c28aaSamw  *
91da6c28aaSamw  * This function converts open modes used by Open and Open AndX
92da6c28aaSamw  * commands to desired access bits used by NT Create AndX command.
93da6c28aaSamw  */
94da6c28aaSamw uint32_t
95da6c28aaSamw smb_omode_to_amask(uint32_t desired_access)
96da6c28aaSamw {
97da6c28aaSamw 	switch (desired_access & SMB_DA_ACCESS_MASK) {
98da6c28aaSamw 	case SMB_DA_ACCESS_READ:
99da6c28aaSamw 		return (FILE_GENERIC_READ);
100da6c28aaSamw 
101da6c28aaSamw 	case SMB_DA_ACCESS_WRITE:
102da6c28aaSamw 		return (FILE_GENERIC_WRITE);
103da6c28aaSamw 
104da6c28aaSamw 	case SMB_DA_ACCESS_READ_WRITE:
105da6c28aaSamw 		return (FILE_GENERIC_READ | FILE_GENERIC_WRITE);
106da6c28aaSamw 
107da6c28aaSamw 	case SMB_DA_ACCESS_EXECUTE:
108da6c28aaSamw 		return (FILE_GENERIC_EXECUTE);
109da6c28aaSamw 
1102c2961f8Sjose borrego 	default:
1112c2961f8Sjose borrego 		return (FILE_GENERIC_ALL);
1122c2961f8Sjose borrego 	}
113da6c28aaSamw }
114da6c28aaSamw 
115da6c28aaSamw /*
116da6c28aaSamw  * smb_denymode_to_sharemode
117da6c28aaSamw  *
118da6c28aaSamw  * This function converts deny modes used by Open and Open AndX
119da6c28aaSamw  * commands to share access bits used by NT Create AndX command.
120da6c28aaSamw  */
121da6c28aaSamw uint32_t
122da6c28aaSamw smb_denymode_to_sharemode(uint32_t desired_access, char *fname)
123da6c28aaSamw {
124da6c28aaSamw 	switch (desired_access & SMB_DA_SHARE_MASK) {
125da6c28aaSamw 	case SMB_DA_SHARE_COMPATIBILITY:
126da6c28aaSamw 		if (smb_is_executable(fname))
127da6c28aaSamw 			return (FILE_SHARE_READ | FILE_SHARE_WRITE);
128c8ec8eeaSjose borrego 
129c8ec8eeaSjose borrego 		return (FILE_SHARE_ALL);
130da6c28aaSamw 
131da6c28aaSamw 	case SMB_DA_SHARE_EXCLUSIVE:
132da6c28aaSamw 		return (FILE_SHARE_NONE);
133da6c28aaSamw 
134da6c28aaSamw 	case SMB_DA_SHARE_DENY_WRITE:
135da6c28aaSamw 		return (FILE_SHARE_READ);
136da6c28aaSamw 
137da6c28aaSamw 	case SMB_DA_SHARE_DENY_READ:
138da6c28aaSamw 		return (FILE_SHARE_WRITE);
139da6c28aaSamw 
140da6c28aaSamw 	case SMB_DA_SHARE_DENY_NONE:
1412c2961f8Sjose borrego 	default:
142da6c28aaSamw 		return (FILE_SHARE_READ | FILE_SHARE_WRITE);
143da6c28aaSamw 	}
144da6c28aaSamw }
145da6c28aaSamw 
146da6c28aaSamw /*
147da6c28aaSamw  * smb_ofun_to_crdisposition
148da6c28aaSamw  *
149da6c28aaSamw  * This function converts open function values used by Open and Open AndX
150da6c28aaSamw  * commands to create disposition values used by NT Create AndX command.
151da6c28aaSamw  */
152da6c28aaSamw uint32_t
153da6c28aaSamw smb_ofun_to_crdisposition(uint16_t  ofun)
154da6c28aaSamw {
155da6c28aaSamw 	static int ofun_cr_map[3][2] =
156da6c28aaSamw 	{
157da6c28aaSamw 		{ -1,			FILE_CREATE },
158da6c28aaSamw 		{ FILE_OPEN,		FILE_OPEN_IF },
159da6c28aaSamw 		{ FILE_OVERWRITE,	FILE_OVERWRITE_IF }
160da6c28aaSamw 	};
161da6c28aaSamw 
162da6c28aaSamw 	int row = ofun & SMB_OFUN_OPEN_MASK;
163da6c28aaSamw 	int col = (ofun & SMB_OFUN_CREATE_MASK) >> 4;
164da6c28aaSamw 
165da6c28aaSamw 	if (row == 3)
1662c2961f8Sjose borrego 		return (FILE_MAXIMUM_DISPOSITION + 1);
167da6c28aaSamw 
168da6c28aaSamw 	return (ofun_cr_map[row][col]);
169da6c28aaSamw }
170da6c28aaSamw 
171da6c28aaSamw /*
1727b59d02dSjb150015  * Retry opens to avoid spurious sharing violations, due to timing
1737b59d02dSjb150015  * issues between closes and opens.  The client that already has the
1747b59d02dSjb150015  * file open may be in the process of closing it.
1757b59d02dSjb150015  */
1767b59d02dSjb150015 uint32_t
1777b59d02dSjb150015 smb_common_open(smb_request_t *sr)
1787b59d02dSjb150015 {
1797b59d02dSjb150015 	uint32_t status = NT_STATUS_SUCCESS;
1807b59d02dSjb150015 	int count;
1817b59d02dSjb150015 
1827b59d02dSjb150015 	for (count = 0; count <= 4; count++) {
1837b59d02dSjb150015 		if (count)
1847b59d02dSjb150015 			delay(MSEC_TO_TICK(400));
1857b59d02dSjb150015 
186faa1795aSjb150015 		status = smb_open_subr(sr);
187faa1795aSjb150015 		if (status != NT_STATUS_SHARING_VIOLATION)
1887b59d02dSjb150015 			break;
1897b59d02dSjb150015 	}
1907b59d02dSjb150015 
191faa1795aSjb150015 	if (status == NT_STATUS_SHARING_VIOLATION) {
1927b59d02dSjb150015 		smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
1937b59d02dSjb150015 		    ERRDOS, ERROR_SHARING_VIOLATION);
1947b59d02dSjb150015 	}
1957b59d02dSjb150015 
1962c2961f8Sjose borrego 	if (status == NT_STATUS_NO_SUCH_FILE) {
1972c2961f8Sjose borrego 		smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND,
1982c2961f8Sjose borrego 		    ERRDOS, ERROR_FILE_NOT_FOUND);
1992c2961f8Sjose borrego 	}
2002c2961f8Sjose borrego 
2017b59d02dSjb150015 	return (status);
2027b59d02dSjb150015 }
2037b59d02dSjb150015 
2047b59d02dSjb150015 /*
205da6c28aaSamw  * smb_open_subr
206da6c28aaSamw  *
207da6c28aaSamw  * Notes on write-through behaviour. It looks like pre-LM0.12 versions
208da6c28aaSamw  * of the protocol specify the write-through mode when a file is opened,
209da6c28aaSamw  * (SmbOpen, SmbOpenAndX) so the write calls (SmbWrite, SmbWriteAndClose,
210da6c28aaSamw  * SmbWriteAndUnlock) don't need to contain a write-through flag.
211da6c28aaSamw  *
212da6c28aaSamw  * With LM0.12, the open calls (SmbCreateAndX, SmbNtTransactCreate)
213da6c28aaSamw  * don't indicate which write-through mode to use. Instead the write
214da6c28aaSamw  * calls (SmbWriteAndX, SmbWriteRaw) specify the mode on a per call
215da6c28aaSamw  * basis.
216da6c28aaSamw  *
217da6c28aaSamw  * We don't care which open call was used to get us here, we just need
218da6c28aaSamw  * to ensure that the write-through mode flag is copied from the open
219da6c28aaSamw  * parameters to the node. We test the omode write-through flag in all
220da6c28aaSamw  * write functions.
221da6c28aaSamw  *
222da6c28aaSamw  * This function will return NT status codes but it also raises errors,
223da6c28aaSamw  * in which case it won't return to the caller. Be careful how you
224da6c28aaSamw  * handle things in here.
2258c10a865Sas200622  *
2268c10a865Sas200622  * The following rules apply when processing a file open request:
2278c10a865Sas200622  *
2288c10a865Sas200622  * - Oplocks must be broken prior to share checking to prevent open
2298c10a865Sas200622  * starvation due to batch oplocks.  Checking share reservations first
2308c10a865Sas200622  * could potentially result in unnecessary open failures due to
2318c10a865Sas200622  * open/close batching on the client.
2328c10a865Sas200622  *
2338c10a865Sas200622  * - Share checks must take place prior to access checks for correct
2348c10a865Sas200622  * Windows semantics and to prevent unnecessary NFS delegation recalls.
2358c10a865Sas200622  *
2368c10a865Sas200622  * - Oplocks must be acquired after open to ensure the correct
2378c10a865Sas200622  * synchronization with NFS delegation and FEM installation.
238c8ec8eeaSjose borrego  *
239c8ec8eeaSjose borrego  *
240c8ec8eeaSjose borrego  * DOS readonly bit rules
241c8ec8eeaSjose borrego  *
242c8ec8eeaSjose borrego  * 1. The creator of a readonly file can write to/modify the size of the file
243c8ec8eeaSjose borrego  * using the original create fid, even though the file will appear as readonly
244c8ec8eeaSjose borrego  * to all other fids and via a CIFS getattr call.
245c8ec8eeaSjose borrego  *
246c8ec8eeaSjose borrego  * 2. A setinfo operation (using either an open fid or a path) to set/unset
247c8ec8eeaSjose borrego  * readonly will be successful regardless of whether a creator of a readonly
248c8ec8eeaSjose borrego  * file has an open fid (and has the special privilege mentioned in #1,
249c8ec8eeaSjose borrego  * above).  I.e., the creator of a readonly fid holding that fid will no longer
250c8ec8eeaSjose borrego  * have a special privilege.
251c8ec8eeaSjose borrego  *
252c8ec8eeaSjose borrego  * 3. The DOS readonly bit affects only data and some metadata.
253c8ec8eeaSjose borrego  * The following metadata can be changed regardless of the readonly bit:
254c8ec8eeaSjose borrego  * 	- security descriptors
255c8ec8eeaSjose borrego  *	- DOS attributes
256c8ec8eeaSjose borrego  *	- timestamps
257c8ec8eeaSjose borrego  *
258c8ec8eeaSjose borrego  * In the current implementation, the file size cannot be changed (except for
259c8ec8eeaSjose borrego  * the exceptions in #1 and #2, above).
2602c1b14e5Sjose borrego  *
2612c1b14e5Sjose borrego  *
2622c1b14e5Sjose borrego  * DOS attribute rules
2632c1b14e5Sjose borrego  *
2642c1b14e5Sjose borrego  * These rules are specific to creating / opening files and directories.
2652c1b14e5Sjose borrego  * How the attribute value (specifically ZERO or FILE_ATTRIBUTE_NORMAL)
2662c1b14e5Sjose borrego  * should be interpreted may differ in other requests.
2672c1b14e5Sjose borrego  *
2682c1b14e5Sjose borrego  * - An attribute value equal to ZERO or FILE_ATTRIBUTE_NORMAL means that the
2692c1b14e5Sjose borrego  *   file's attributes should be cleared.
2702c1b14e5Sjose borrego  * - If FILE_ATTRIBUTE_NORMAL is specified with any other attributes,
2712c1b14e5Sjose borrego  *   FILE_ATTRIBUTE_NORMAL is ignored.
2722c1b14e5Sjose borrego  *
2732c1b14e5Sjose borrego  * 1. Creating a new file
2742c1b14e5Sjose borrego  * - The request attributes + FILE_ATTRIBUTE_ARCHIVE are applied to the file.
2752c1b14e5Sjose borrego  *
2762c1b14e5Sjose borrego  * 2. Creating a new directory
2772c1b14e5Sjose borrego  * - The request attributes + FILE_ATTRIBUTE_DIRECTORY are applied to the file.
2782c1b14e5Sjose borrego  * - FILE_ATTRIBUTE_ARCHIVE does not get set.
2792c1b14e5Sjose borrego  *
2802c1b14e5Sjose borrego  * 3. Overwriting an existing file
2812c1b14e5Sjose borrego  * - the request attributes are used as search attributes. If the existing
2822c1b14e5Sjose borrego  *   file does not meet the search criteria access is denied.
2832c1b14e5Sjose borrego  * - otherwise, applies attributes + FILE_ATTRIBUTE_ARCHIVE.
2842c1b14e5Sjose borrego  *
2852c1b14e5Sjose borrego  * 4. Opening an existing file or directory
2862c1b14e5Sjose borrego  *    The request attributes are ignored.
287da6c28aaSamw  */
2887b59d02dSjb150015 static uint32_t
2897b59d02dSjb150015 smb_open_subr(smb_request_t *sr)
290da6c28aaSamw {
291*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	boolean_t	created = B_FALSE;
292*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	boolean_t	last_comp_found = B_FALSE;
2932c2961f8Sjose borrego 	smb_node_t	*node = NULL;
2942c2961f8Sjose borrego 	smb_node_t	*dnode = NULL;
295*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	smb_node_t	*cur_node = NULL;
2962c2961f8Sjose borrego 	open_param_t	*op = &sr->arg.open;
297da6c28aaSamw 	int		rc;
2982c2961f8Sjose borrego 	smb_ofile_t	*of;
299da6c28aaSamw 	smb_attr_t	new_attr;
300da6c28aaSamw 	int		pathlen;
301da6c28aaSamw 	int		max_requested = 0;
302da6c28aaSamw 	uint32_t	max_allowed;
303da6c28aaSamw 	uint32_t	status = NT_STATUS_SUCCESS;
304da6c28aaSamw 	int		is_dir;
305da6c28aaSamw 	smb_error_t	err;
3062c2961f8Sjose borrego 	boolean_t	is_stream = B_FALSE;
307da6c28aaSamw 	int		lookup_flags = SMB_FOLLOW_LINKS;
308da6c28aaSamw 	uint32_t	daccess;
309dc20a302Sas200622 	uint32_t	uniq_fid;
310*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	smb_pathname_t	*pn = &op->fqi.fq_path;
311da6c28aaSamw 
312da6c28aaSamw 	is_dir = (op->create_options & FILE_DIRECTORY_FILE) ? 1 : 0;
313da6c28aaSamw 
314da6c28aaSamw 	if (is_dir) {
315da6c28aaSamw 		/*
3167b59d02dSjb150015 		 * The object being created or opened is a directory,
3177b59d02dSjb150015 		 * and the Disposition parameter must be one of
3187b59d02dSjb150015 		 * FILE_CREATE, FILE_OPEN, or FILE_OPEN_IF
319da6c28aaSamw 		 */
320da6c28aaSamw 		if ((op->create_disposition != FILE_CREATE) &&
321da6c28aaSamw 		    (op->create_disposition != FILE_OPEN_IF) &&
322da6c28aaSamw 		    (op->create_disposition != FILE_OPEN)) {
323dc20a302Sas200622 			smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
324da6c28aaSamw 			    ERRDOS, ERROR_INVALID_ACCESS);
3257b59d02dSjb150015 			return (NT_STATUS_INVALID_PARAMETER);
326da6c28aaSamw 		}
327da6c28aaSamw 	}
328da6c28aaSamw 
329da6c28aaSamw 	if (op->desired_access & MAXIMUM_ALLOWED) {
330da6c28aaSamw 		max_requested = 1;
331da6c28aaSamw 		op->desired_access &= ~MAXIMUM_ALLOWED;
332da6c28aaSamw 	}
333da6c28aaSamw 	op->desired_access = smb_access_generic_to_file(op->desired_access);
334da6c28aaSamw 
335da6c28aaSamw 	if (sr->session->s_file_cnt >= SMB_SESSION_OFILE_MAX) {
336da6c28aaSamw 		ASSERT(sr->uid_user);
337da6c28aaSamw 		cmn_err(CE_NOTE, "smbd[%s\\%s]: %s", sr->uid_user->u_domain,
338da6c28aaSamw 		    sr->uid_user->u_name,
339da6c28aaSamw 		    xlate_nt_status(NT_STATUS_TOO_MANY_OPENED_FILES));
340da6c28aaSamw 
341dc20a302Sas200622 		smbsr_error(sr, NT_STATUS_TOO_MANY_OPENED_FILES,
342da6c28aaSamw 		    ERRDOS, ERROR_TOO_MANY_OPEN_FILES);
3437b59d02dSjb150015 		return (NT_STATUS_TOO_MANY_OPENED_FILES);
344da6c28aaSamw 	}
345da6c28aaSamw 
346da6c28aaSamw 	/* This must be NULL at this point */
347da6c28aaSamw 	sr->fid_ofile = NULL;
348da6c28aaSamw 
349da6c28aaSamw 	op->devstate = 0;
350da6c28aaSamw 
351da6c28aaSamw 	switch (sr->tid_tree->t_res_type & STYPE_MASK) {
352da6c28aaSamw 	case STYPE_DISKTREE:
353da6c28aaSamw 		break;
354da6c28aaSamw 
355da6c28aaSamw 	case STYPE_IPC:
356da6c28aaSamw 		/*
357da6c28aaSamw 		 * No further processing for IPC, we need to either
358da6c28aaSamw 		 * raise an exception or return success here.
359da6c28aaSamw 		 */
3603db3f65cSamw 		if ((status = smb_opipe_open(sr)) != NT_STATUS_SUCCESS)
3617b59d02dSjb150015 			smbsr_error(sr, status, 0, 0);
3627b59d02dSjb150015 		return (status);
363da6c28aaSamw 
364da6c28aaSamw 	default:
3657b59d02dSjb150015 		smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE,
3667b59d02dSjb150015 		    ERRDOS, ERROR_BAD_DEV_TYPE);
3677b59d02dSjb150015 		return (NT_STATUS_BAD_DEVICE_TYPE);
368da6c28aaSamw 	}
369da6c28aaSamw 
370*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	if ((pathlen = strlen(pn->pn_path)) >= MAXPATHLEN) {
371dc20a302Sas200622 		smbsr_error(sr, 0, ERRSRV, ERRfilespecs);
3727b59d02dSjb150015 		return (NT_STATUS_NAME_TOO_LONG);
373da6c28aaSamw 	}
374da6c28aaSamw 
375da6c28aaSamw 	/*
376da6c28aaSamw 	 * Some clients pass null file names; NT interprets this as "\".
377da6c28aaSamw 	 */
378da6c28aaSamw 	if (pathlen == 0) {
379*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		pn->pn_path = "\\";
380da6c28aaSamw 		pathlen = 1;
381da6c28aaSamw 	}
382da6c28aaSamw 
383*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	smb_pathname_setup(sr, pn);
384da6c28aaSamw 
385*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (is_dir)
386*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		status = smb_validate_dirname(pn->pn_path);
387*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	else
388*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		status = smb_validate_object_name(pn);
389*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 
390*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (status != NT_STATUS_SUCCESS) {
391dc20a302Sas200622 		smbsr_error(sr, status, ERRDOS, ERROR_INVALID_NAME);
3927b59d02dSjb150015 		return (status);
393da6c28aaSamw 	}
394da6c28aaSamw 
395*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	cur_node = op->fqi.fq_dnode ?
396*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	    op->fqi.fq_dnode : sr->tid_tree->t_snode;
397da6c28aaSamw 
398*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	/*
399*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	 * if no path or filename are specified the stream should be
400*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	 * created on cur_node
401*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	 */
402*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (!is_dir && !pn->pn_pname && !pn->pn_fname && pn->pn_sname) {
403*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 
404*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		/* can't currently create a stream on the tree root */
405*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		if (cur_node == sr->tid_tree->t_snode) {
406*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
407*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			    ERROR_ACCESS_DENIED);
408*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			return (NT_STATUS_ACCESS_DENIED);
409*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		}
410*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 
411*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		(void) snprintf(op->fqi.fq_last_comp,
412*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		    sizeof (op->fqi.fq_last_comp),
413*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		    "%s%s", cur_node->od_name, pn->pn_sname);
414*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 
415*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		op->fqi.fq_dnode = cur_node->dir_snode;
416*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		smb_node_ref(op->fqi.fq_dnode);
417*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	} else {
418*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		if (rc = smb_pathname_reduce(sr, sr->user_cr, pn->pn_path,
419*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		    sr->tid_tree->t_snode, cur_node, &op->fqi.fq_dnode,
420*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		    op->fqi.fq_last_comp)) {
421dc20a302Sas200622 			smbsr_errno(sr, rc);
4227b59d02dSjb150015 			return (sr->smb_error.status);
423da6c28aaSamw 		}
424*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	}
425da6c28aaSamw 
426da6c28aaSamw 	/*
427da6c28aaSamw 	 * If the access mask has only DELETE set (ignore
428da6c28aaSamw 	 * FILE_READ_ATTRIBUTES), then assume that this
429da6c28aaSamw 	 * is a request to delete the link (if a link)
430da6c28aaSamw 	 * and do not follow links.  Otherwise, follow
431da6c28aaSamw 	 * the link to the target.
432da6c28aaSamw 	 */
433da6c28aaSamw 	daccess = op->desired_access & ~FILE_READ_ATTRIBUTES;
434da6c28aaSamw 
435da6c28aaSamw 	if (daccess == DELETE)
436da6c28aaSamw 		lookup_flags &= ~SMB_FOLLOW_LINKS;
437da6c28aaSamw 
438da6c28aaSamw 	rc = smb_fsop_lookup_name(sr, kcred, lookup_flags,
439*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	    sr->tid_tree->t_snode, op->fqi.fq_dnode, op->fqi.fq_last_comp,
440*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	    &op->fqi.fq_fnode, &op->fqi.fq_fattr);
441da6c28aaSamw 
442da6c28aaSamw 	if (rc == 0) {
443*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		last_comp_found = B_TRUE;
444*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		(void) strcpy(op->fqi.fq_od_name,
445*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		    op->fqi.fq_fnode->od_name);
446da6c28aaSamw 	} else if (rc == ENOENT) {
447*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		last_comp_found = B_FALSE;
448*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		op->fqi.fq_fnode = NULL;
449da6c28aaSamw 		rc = 0;
450da6c28aaSamw 	} else {
451*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		smb_node_release(op->fqi.fq_dnode);
452da6c28aaSamw 		SMB_NULL_FQI_NODES(op->fqi);
453dc20a302Sas200622 		smbsr_errno(sr, rc);
4547b59d02dSjb150015 		return (sr->smb_error.status);
455da6c28aaSamw 	}
456da6c28aaSamw 
457dc20a302Sas200622 	/*
458dc20a302Sas200622 	 * The uniq_fid is a CIFS-server-wide unique identifier for an ofile
459dc20a302Sas200622 	 * which is used to uniquely identify open instances for the
460c8ec8eeaSjose borrego 	 * VFS share reservation and POSIX locks.
461dc20a302Sas200622 	 */
462dc20a302Sas200622 
463dc20a302Sas200622 	uniq_fid = SMB_UNIQ_FID();
464dc20a302Sas200622 
465*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (last_comp_found) {
4666537f381Sas200622 
467*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		if ((op->fqi.fq_fattr.sa_vattr.va_type != VREG) &&
468*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		    (op->fqi.fq_fattr.sa_vattr.va_type != VDIR) &&
469*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		    (op->fqi.fq_fattr.sa_vattr.va_type != VLNK)) {
4706537f381Sas200622 
471*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			smb_node_release(op->fqi.fq_fnode);
472*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			smb_node_release(op->fqi.fq_dnode);
4736537f381Sas200622 			SMB_NULL_FQI_NODES(op->fqi);
4746537f381Sas200622 			smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
4756537f381Sas200622 			    ERRnoaccess);
4766537f381Sas200622 			return (NT_STATUS_ACCESS_DENIED);
4776537f381Sas200622 		}
4786537f381Sas200622 
479*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		node = op->fqi.fq_fnode;
480*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		dnode = op->fqi.fq_dnode;
481da6c28aaSamw 
482da6c28aaSamw 		/*
4832c1b14e5Sjose borrego 		 * Reject this request if either:
4842c1b14e5Sjose borrego 		 * - the target IS a directory and the client requires that
4852c1b14e5Sjose borrego 		 *   it must NOT be (required by Lotus Notes)
4862c1b14e5Sjose borrego 		 * - the target is NOT a directory and client requires that
4872c1b14e5Sjose borrego 		 *   it MUST be.
488da6c28aaSamw 		 */
489*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		if (op->fqi.fq_fattr.sa_vattr.va_type == VDIR) {
4902c1b14e5Sjose borrego 			if (op->create_options & FILE_NON_DIRECTORY_FILE) {
491da6c28aaSamw 				smb_node_release(node);
492da6c28aaSamw 				smb_node_release(dnode);
493da6c28aaSamw 				SMB_NULL_FQI_NODES(op->fqi);
494dc20a302Sas200622 				smbsr_error(sr, NT_STATUS_FILE_IS_A_DIRECTORY,
495da6c28aaSamw 				    ERRDOS, ERROR_ACCESS_DENIED);
4967b59d02dSjb150015 				return (NT_STATUS_FILE_IS_A_DIRECTORY);
497da6c28aaSamw 			}
4982c1b14e5Sjose borrego 		} else {
4992c1b14e5Sjose borrego 			if ((op->create_options & FILE_DIRECTORY_FILE) ||
5002c2961f8Sjose borrego 			    (op->nt_flags & NT_CREATE_FLAG_OPEN_TARGET_DIR)) {
501da6c28aaSamw 				smb_node_release(node);
502da6c28aaSamw 				smb_node_release(dnode);
503da6c28aaSamw 				SMB_NULL_FQI_NODES(op->fqi);
504dc20a302Sas200622 				smbsr_error(sr, NT_STATUS_NOT_A_DIRECTORY,
505da6c28aaSamw 				    ERRDOS, ERROR_DIRECTORY);
5067b59d02dSjb150015 				return (NT_STATUS_NOT_A_DIRECTORY);
507da6c28aaSamw 			}
5082c1b14e5Sjose borrego 		}
509da6c28aaSamw 
510da6c28aaSamw 		/*
511da6c28aaSamw 		 * No more open should be accepted when "Delete on close"
512da6c28aaSamw 		 * flag is set.
513da6c28aaSamw 		 */
514da6c28aaSamw 		if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
515da6c28aaSamw 			smb_node_release(node);
516da6c28aaSamw 			smb_node_release(dnode);
517da6c28aaSamw 			SMB_NULL_FQI_NODES(op->fqi);
518dc20a302Sas200622 			smbsr_error(sr, NT_STATUS_DELETE_PENDING,
519da6c28aaSamw 			    ERRDOS, ERROR_ACCESS_DENIED);
5207b59d02dSjb150015 			return (NT_STATUS_DELETE_PENDING);
521da6c28aaSamw 		}
522da6c28aaSamw 
523da6c28aaSamw 		/*
524da6c28aaSamw 		 * Specified file already exists so the operation should fail.
525da6c28aaSamw 		 */
526da6c28aaSamw 		if (op->create_disposition == FILE_CREATE) {
527da6c28aaSamw 			smb_node_release(node);
528da6c28aaSamw 			smb_node_release(dnode);
529da6c28aaSamw 			SMB_NULL_FQI_NODES(op->fqi);
530dc20a302Sas200622 			smbsr_error(sr, NT_STATUS_OBJECT_NAME_COLLISION,
531b89a8333Snatalie li - Sun Microsystems - Irvine United States 			    ERRDOS, ERROR_FILE_EXISTS);
5327b59d02dSjb150015 			return (NT_STATUS_OBJECT_NAME_COLLISION);
533da6c28aaSamw 		}
534da6c28aaSamw 
535da6c28aaSamw 		/*
536da6c28aaSamw 		 * Windows seems to check read-only access before file
537da6c28aaSamw 		 * sharing check.
538c8ec8eeaSjose borrego 		 *
539c8ec8eeaSjose borrego 		 * Check to see if the file is currently readonly (irrespective
540c8ec8eeaSjose borrego 		 * of whether this open will make it readonly).
541da6c28aaSamw 		 */
542c8ec8eeaSjose borrego 		if (SMB_PATHFILE_IS_READONLY(sr, node)) {
543da6c28aaSamw 			/* Files data only */
544da6c28aaSamw 			if (node->attr.sa_vattr.va_type != VDIR) {
545da6c28aaSamw 				if (op->desired_access & (FILE_WRITE_DATA |
546da6c28aaSamw 				    FILE_APPEND_DATA)) {
547da6c28aaSamw 					smb_node_release(node);
548da6c28aaSamw 					smb_node_release(dnode);
549da6c28aaSamw 					SMB_NULL_FQI_NODES(op->fqi);
550dc20a302Sas200622 					smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
551dc20a302Sas200622 					    ERRDOS, ERRnoaccess);
5527b59d02dSjb150015 					return (NT_STATUS_ACCESS_DENIED);
553da6c28aaSamw 				}
554da6c28aaSamw 			}
555da6c28aaSamw 		}
556da6c28aaSamw 
5578c10a865Sas200622 		if (smb_oplock_conflict(node, sr->session, op))
558fc724630SAlan Wright 			(void) smb_oplock_break(node, sr->session, B_FALSE);
5598c10a865Sas200622 
5602c2961f8Sjose borrego 		smb_node_wrlock(node);
561dc20a302Sas200622 
562dc20a302Sas200622 		if ((op->create_disposition == FILE_SUPERSEDE) ||
563dc20a302Sas200622 		    (op->create_disposition == FILE_OVERWRITE_IF) ||
564dc20a302Sas200622 		    (op->create_disposition == FILE_OVERWRITE)) {
565dc20a302Sas200622 
5662c1b14e5Sjose borrego 			if ((!(op->desired_access &
5678c10a865Sas200622 			    (FILE_WRITE_DATA | FILE_APPEND_DATA |
5682c1b14e5Sjose borrego 			    FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA))) ||
5697f667e74Sjose borrego 			    (!smb_sattr_check(node->attr.sa_dosattr,
5702c2961f8Sjose borrego 			    op->dattr))) {
5712c2961f8Sjose borrego 				smb_node_unlock(node);
572dc20a302Sas200622 				smb_node_release(node);
573dc20a302Sas200622 				smb_node_release(dnode);
574dc20a302Sas200622 				SMB_NULL_FQI_NODES(op->fqi);
575dc20a302Sas200622 				smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
576dc20a302Sas200622 				    ERRDOS, ERRnoaccess);
5777b59d02dSjb150015 				return (NT_STATUS_ACCESS_DENIED);
578dc20a302Sas200622 			}
579dc20a302Sas200622 		}
580dc20a302Sas200622 
581dc20a302Sas200622 		status = smb_fsop_shrlock(sr->user_cr, node, uniq_fid,
582c8ec8eeaSjose borrego 		    op->desired_access, op->share_access);
583dc20a302Sas200622 
584da6c28aaSamw 		if (status == NT_STATUS_SHARING_VIOLATION) {
5852c2961f8Sjose borrego 			smb_node_unlock(node);
586da6c28aaSamw 			smb_node_release(node);
587da6c28aaSamw 			smb_node_release(dnode);
588da6c28aaSamw 			SMB_NULL_FQI_NODES(op->fqi);
589da6c28aaSamw 			return (status);
590da6c28aaSamw 		}
591da6c28aaSamw 
592da6c28aaSamw 		status = smb_fsop_access(sr, sr->user_cr, node,
593da6c28aaSamw 		    op->desired_access);
594da6c28aaSamw 
595da6c28aaSamw 		if (status != NT_STATUS_SUCCESS) {
596dc20a302Sas200622 			smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
597dc20a302Sas200622 
5982c2961f8Sjose borrego 			smb_node_unlock(node);
599da6c28aaSamw 			smb_node_release(node);
600da6c28aaSamw 			smb_node_release(dnode);
601da6c28aaSamw 			SMB_NULL_FQI_NODES(op->fqi);
602dc20a302Sas200622 
603da6c28aaSamw 			if (status == NT_STATUS_PRIVILEGE_NOT_HELD) {
604dc20a302Sas200622 				smbsr_error(sr, status,
605dc20a302Sas200622 				    ERRDOS, ERROR_PRIVILEGE_NOT_HELD);
6067b59d02dSjb150015 				return (status);
607da6c28aaSamw 			} else {
608dc20a302Sas200622 				smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
609dc20a302Sas200622 				    ERRDOS, ERROR_ACCESS_DENIED);
6107b59d02dSjb150015 				return (NT_STATUS_ACCESS_DENIED);
611da6c28aaSamw 			}
612da6c28aaSamw 		}
613da6c28aaSamw 
614da6c28aaSamw 		switch (op->create_disposition) {
615da6c28aaSamw 		case FILE_SUPERSEDE:
616da6c28aaSamw 		case FILE_OVERWRITE_IF:
617da6c28aaSamw 		case FILE_OVERWRITE:
618da6c28aaSamw 			if (node->attr.sa_vattr.va_type == VDIR) {
619dc20a302Sas200622 				smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
6202c2961f8Sjose borrego 				smb_node_unlock(node);
621da6c28aaSamw 				smb_node_release(node);
622da6c28aaSamw 				smb_node_release(dnode);
623da6c28aaSamw 				SMB_NULL_FQI_NODES(op->fqi);
624dc20a302Sas200622 				smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
625dc20a302Sas200622 				    ERRDOS, ERROR_ACCESS_DENIED);
6267b59d02dSjb150015 				return (NT_STATUS_ACCESS_DENIED);
627da6c28aaSamw 			}
628da6c28aaSamw 
629da6c28aaSamw 			if (node->attr.sa_vattr.va_size != op->dsize) {
630da6c28aaSamw 				node->flags &= ~NODE_FLAGS_SET_SIZE;
631dc20a302Sas200622 				bzero(&new_attr, sizeof (new_attr));
632da6c28aaSamw 				new_attr.sa_vattr.va_size = op->dsize;
633da6c28aaSamw 				new_attr.sa_mask = SMB_AT_SIZE;
634dc20a302Sas200622 
635dc20a302Sas200622 				rc = smb_fsop_setattr(sr, sr->user_cr,
636*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 				    node, &new_attr, &op->fqi.fq_fattr);
637dc20a302Sas200622 
638dc20a302Sas200622 				if (rc) {
639faa1795aSjb150015 					smb_fsop_unshrlock(sr->user_cr, node,
640faa1795aSjb150015 					    uniq_fid);
6412c2961f8Sjose borrego 					smb_node_unlock(node);
642da6c28aaSamw 					smb_node_release(node);
643da6c28aaSamw 					smb_node_release(dnode);
644da6c28aaSamw 					SMB_NULL_FQI_NODES(op->fqi);
645dc20a302Sas200622 					smbsr_errno(sr, rc);
6467b59d02dSjb150015 					return (sr->smb_error.status);
647da6c28aaSamw 				}
648da6c28aaSamw 
649*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 				op->dsize = op->fqi.fq_fattr.sa_vattr.va_size;
650da6c28aaSamw 			}
651da6c28aaSamw 
6522c1b14e5Sjose borrego 			op->dattr |= FILE_ATTRIBUTE_ARCHIVE;
6532c1b14e5Sjose borrego 			if (op->dattr & FILE_ATTRIBUTE_READONLY) {
6542c1b14e5Sjose borrego 				op->created_readonly = B_TRUE;
6552c1b14e5Sjose borrego 				op->dattr &= ~FILE_ATTRIBUTE_READONLY;
6562c1b14e5Sjose borrego 			}
6572c1b14e5Sjose borrego 
6582c1b14e5Sjose borrego 			smb_node_set_dosattr(node, op->dattr);
6592c1b14e5Sjose borrego 			(void) smb_sync_fsattr(sr, sr->user_cr, node);
6602c1b14e5Sjose borrego 
661da6c28aaSamw 			/*
662da6c28aaSamw 			 * If file is being replaced,
663da6c28aaSamw 			 * we should remove existing streams
664da6c28aaSamw 			 */
665*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			if (SMB_IS_STREAM(node) == 0) {
666*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 				if (smb_fsop_remove_streams(sr, sr->user_cr,
667*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 				    node) != 0) {
668*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 					smb_fsop_unshrlock(sr->user_cr, node,
669*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 					    uniq_fid);
670*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 					smb_node_unlock(node);
671*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 					smb_node_release(node);
672*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 					smb_node_release(dnode);
673*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 					SMB_NULL_FQI_NODES(op->fqi);
674*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 					return (sr->smb_error.status);
675*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 				}
676*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			}
677da6c28aaSamw 
678da6c28aaSamw 			op->action_taken = SMB_OACT_TRUNCATED;
679da6c28aaSamw 			break;
680da6c28aaSamw 
681da6c28aaSamw 		default:
682da6c28aaSamw 			/*
683da6c28aaSamw 			 * FILE_OPEN or FILE_OPEN_IF.
684da6c28aaSamw 			 */
685da6c28aaSamw 			op->action_taken = SMB_OACT_OPENED;
686da6c28aaSamw 			break;
687da6c28aaSamw 		}
688da6c28aaSamw 	} else {
689da6c28aaSamw 		/* Last component was not found. */
690*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		dnode = op->fqi.fq_dnode;
691da6c28aaSamw 
6927b59d02dSjb150015 		if (is_dir == 0)
693*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			is_stream = smb_is_stream_name(pn->pn_path);
6947b59d02dSjb150015 
695da6c28aaSamw 		if ((op->create_disposition == FILE_OPEN) ||
696da6c28aaSamw 		    (op->create_disposition == FILE_OVERWRITE)) {
697da6c28aaSamw 			smb_node_release(dnode);
698da6c28aaSamw 			SMB_NULL_FQI_NODES(op->fqi);
699dc20a302Sas200622 			smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND,
700da6c28aaSamw 			    ERRDOS, ERROR_FILE_NOT_FOUND);
7017b59d02dSjb150015 			return (NT_STATUS_OBJECT_NAME_NOT_FOUND);
702da6c28aaSamw 		}
703da6c28aaSamw 
7042c2961f8Sjose borrego 		if ((is_dir == 0) && (!is_stream) &&
705*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		    smb_is_invalid_filename(op->fqi.fq_last_comp)) {
7062c2961f8Sjose borrego 			smb_node_release(dnode);
7072c2961f8Sjose borrego 			SMB_NULL_FQI_NODES(op->fqi);
7082c2961f8Sjose borrego 			smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
7092c2961f8Sjose borrego 			    ERRDOS, ERROR_INVALID_NAME);
7102c2961f8Sjose borrego 			return (NT_STATUS_OBJECT_NAME_INVALID);
7112c2961f8Sjose borrego 		}
7122c2961f8Sjose borrego 
713da6c28aaSamw 		/*
714da6c28aaSamw 		 * lock the parent dir node in case another create
715da6c28aaSamw 		 * request to the same parent directory comes in.
716da6c28aaSamw 		 */
7172c2961f8Sjose borrego 		smb_node_wrlock(dnode);
718da6c28aaSamw 
719da6c28aaSamw 		bzero(&new_attr, sizeof (new_attr));
7202c1b14e5Sjose borrego 		new_attr.sa_dosattr = op->dattr;
7212c1b14e5Sjose borrego 		new_attr.sa_mask |= SMB_AT_DOSATTR;
722c8ec8eeaSjose borrego 
723c8ec8eeaSjose borrego 		/*
724c8ec8eeaSjose borrego 		 * A file created with the readonly bit should not
725c8ec8eeaSjose borrego 		 * stop the creator writing to the file until it is
726c8ec8eeaSjose borrego 		 * closed.  Although the readonly bit will not be set
727c8ec8eeaSjose borrego 		 * on the file until it is closed, it will be accounted
728c8ec8eeaSjose borrego 		 * for on other fids and on queries based on the node
729c8ec8eeaSjose borrego 		 * state.
730c8ec8eeaSjose borrego 		 */
731c8ec8eeaSjose borrego 		if (op->dattr & FILE_ATTRIBUTE_READONLY)
7322c1b14e5Sjose borrego 			new_attr.sa_dosattr &= ~FILE_ATTRIBUTE_READONLY;
733c8ec8eeaSjose borrego 
734c8ec8eeaSjose borrego 
735c8ec8eeaSjose borrego 		if ((op->crtime.tv_sec != 0) &&
736c8ec8eeaSjose borrego 		    (op->crtime.tv_sec != UINT_MAX)) {
737c8ec8eeaSjose borrego 
738c8ec8eeaSjose borrego 			new_attr.sa_mask |= SMB_AT_CRTIME;
739c8ec8eeaSjose borrego 			new_attr.sa_crtime = op->crtime;
740c8ec8eeaSjose borrego 		}
741c8ec8eeaSjose borrego 
742da6c28aaSamw 		if (is_dir == 0) {
7432c1b14e5Sjose borrego 			new_attr.sa_dosattr |= FILE_ATTRIBUTE_ARCHIVE;
744da6c28aaSamw 			new_attr.sa_vattr.va_type = VREG;
7457b59d02dSjb150015 			new_attr.sa_vattr.va_mode = is_stream ? S_IRUSR :
7467b59d02dSjb150015 			    S_IRUSR | S_IRGRP | S_IROTH |
7477b59d02dSjb150015 			    S_IWUSR | S_IWGRP | S_IWOTH;
748c8ec8eeaSjose borrego 			new_attr.sa_mask |= SMB_AT_TYPE | SMB_AT_MODE;
749dc20a302Sas200622 
7506537f381Sas200622 			if (op->dsize) {
7516537f381Sas200622 				new_attr.sa_vattr.va_size = op->dsize;
7526537f381Sas200622 				new_attr.sa_mask |= SMB_AT_SIZE;
753dc20a302Sas200622 			}
754dc20a302Sas200622 
755da6c28aaSamw 			rc = smb_fsop_create(sr, sr->user_cr, dnode,
756*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			    op->fqi.fq_last_comp, &new_attr,
757*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			    &op->fqi.fq_fnode, &op->fqi.fq_fattr);
758dc20a302Sas200622 
759da6c28aaSamw 			if (rc != 0) {
7602c2961f8Sjose borrego 				smb_node_unlock(dnode);
761da6c28aaSamw 				smb_node_release(dnode);
762da6c28aaSamw 				SMB_NULL_FQI_NODES(op->fqi);
763dc20a302Sas200622 				smbsr_errno(sr, rc);
7647b59d02dSjb150015 				return (sr->smb_error.status);
765da6c28aaSamw 			}
766da6c28aaSamw 
767*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			node = op->fqi.fq_fnode;
768dc20a302Sas200622 
769*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			op->fqi.fq_fattr = node->attr;
770c8ec8eeaSjose borrego 
7712c2961f8Sjose borrego 			smb_node_wrlock(node);
772dc20a302Sas200622 
773faa1795aSjb150015 			status = smb_fsop_shrlock(sr->user_cr, node, uniq_fid,
774c8ec8eeaSjose borrego 			    op->desired_access, op->share_access);
775dc20a302Sas200622 
776dc20a302Sas200622 			if (status == NT_STATUS_SHARING_VIOLATION) {
7772c2961f8Sjose borrego 				smb_node_unlock(node);
7788b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 				if (created)
7798b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 					smb_delete_new_object(sr);
780dc20a302Sas200622 				smb_node_release(node);
7812c2961f8Sjose borrego 				smb_node_unlock(dnode);
782dc20a302Sas200622 				smb_node_release(dnode);
783dc20a302Sas200622 				SMB_NULL_FQI_NODES(op->fqi);
784dc20a302Sas200622 				return (status);
785dc20a302Sas200622 			}
786da6c28aaSamw 		} else {
7873db3f65cSamw 			op->dattr |= FILE_ATTRIBUTE_DIRECTORY;
788da6c28aaSamw 			new_attr.sa_vattr.va_type = VDIR;
789da6c28aaSamw 			new_attr.sa_vattr.va_mode = 0777;
790c8ec8eeaSjose borrego 			new_attr.sa_mask |= SMB_AT_TYPE | SMB_AT_MODE;
791c8ec8eeaSjose borrego 
792da6c28aaSamw 			rc = smb_fsop_mkdir(sr, sr->user_cr, dnode,
793*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			    op->fqi.fq_last_comp, &new_attr,
794*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			    &op->fqi.fq_fnode, &op->fqi.fq_fattr);
795da6c28aaSamw 			if (rc != 0) {
7962c2961f8Sjose borrego 				smb_node_unlock(dnode);
797da6c28aaSamw 				smb_node_release(dnode);
798da6c28aaSamw 				SMB_NULL_FQI_NODES(op->fqi);
799dc20a302Sas200622 				smbsr_errno(sr, rc);
8007b59d02dSjb150015 				return (sr->smb_error.status);
801da6c28aaSamw 			}
802dc20a302Sas200622 
803*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			node = op->fqi.fq_fnode;
8042c2961f8Sjose borrego 			smb_node_wrlock(node);
805da6c28aaSamw 		}
806da6c28aaSamw 
807*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		created = B_TRUE;
808da6c28aaSamw 		op->action_taken = SMB_OACT_CREATED;
809c8ec8eeaSjose borrego 		node->flags |= NODE_FLAGS_CREATED;
810c8ec8eeaSjose borrego 
811c8ec8eeaSjose borrego 		if (op->dattr & FILE_ATTRIBUTE_READONLY) {
812c8ec8eeaSjose borrego 			op->created_readonly = B_TRUE;
813c8ec8eeaSjose borrego 			op->dattr &= ~FILE_ATTRIBUTE_READONLY;
814c8ec8eeaSjose borrego 		}
815c8ec8eeaSjose borrego 	}
816c8ec8eeaSjose borrego 
817c8ec8eeaSjose borrego 	op->dattr = smb_node_get_dosattr(node);
818c8ec8eeaSjose borrego 
8192c1b14e5Sjose borrego 	if (max_requested) {
8202c1b14e5Sjose borrego 		smb_fsop_eaccess(sr, sr->user_cr, node, &max_allowed);
8212c1b14e5Sjose borrego 		op->desired_access |= max_allowed;
8222c1b14e5Sjose borrego 	}
8232c1b14e5Sjose borrego 
8242c1b14e5Sjose borrego 	/*
8252c1b14e5Sjose borrego 	 * if last_write time was in request and is not 0 or -1,
8262c1b14e5Sjose borrego 	 * use it as file's mtime
8272c1b14e5Sjose borrego 	 */
8282c1b14e5Sjose borrego 	if ((op->mtime.tv_sec != 0) && (op->mtime.tv_sec != UINT_MAX)) {
8292c1b14e5Sjose borrego 		smb_node_set_time(node, NULL, &op->mtime, NULL, NULL,
8302c1b14e5Sjose borrego 		    SMB_AT_MTIME);
8312c1b14e5Sjose borrego 		(void) smb_sync_fsattr(sr, sr->user_cr, node);
8322c1b14e5Sjose borrego 	}
8332c1b14e5Sjose borrego 
834c8ec8eeaSjose borrego 	of = smb_ofile_open(sr->tid_tree, node, sr->smb_pid, op, SMB_FTYPE_DISK,
835c8ec8eeaSjose borrego 	    uniq_fid, &err);
836da6c28aaSamw 
837da6c28aaSamw 	if (of == NULL) {
838dc20a302Sas200622 		smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
8398b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		if (created)
8408b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 			smb_delete_new_object(sr);
8412c2961f8Sjose borrego 		smb_node_unlock(node);
842da6c28aaSamw 		smb_node_release(node);
843da6c28aaSamw 		if (created)
8442c2961f8Sjose borrego 			smb_node_unlock(dnode);
845da6c28aaSamw 		smb_node_release(dnode);
846da6c28aaSamw 		SMB_NULL_FQI_NODES(op->fqi);
847dc20a302Sas200622 		smbsr_error(sr, err.status, err.errcls, err.errcode);
8487b59d02dSjb150015 		return (err.status);
849da6c28aaSamw 	}
850da6c28aaSamw 
8518b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_tree_is_connected(sr->tid_tree)) {
8528b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		smb_ofile_close(of, 0);
8538b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		smb_ofile_release(of);
8548b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		if (created)
8558b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 			smb_delete_new_object(sr);
8568b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		smb_node_unlock(node);
8578b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		smb_node_release(node);
8588b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		if (created)
8598b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 			smb_node_unlock(dnode);
8608b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		smb_node_release(dnode);
8618b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		SMB_NULL_FQI_NODES(op->fqi);
8628b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		smbsr_error(sr, 0, ERRSRV, ERRinvnid);
8638b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		return (NT_STATUS_UNSUCCESSFUL);
8648b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	}
8658b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
8668c10a865Sas200622 	/*
8678c10a865Sas200622 	 * Propagate the write-through mode from the open params
8688c10a865Sas200622 	 * to the node: see the notes in the function header.
8698c10a865Sas200622 	 */
8708c10a865Sas200622 	if (sr->sr_cfg->skc_sync_enable ||
8718c10a865Sas200622 	    (op->create_options & FILE_WRITE_THROUGH))
8728c10a865Sas200622 		node->flags |= NODE_FLAGS_WRITE_THROUGH;
8738c10a865Sas200622 
874*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	op->fileid = op->fqi.fq_fattr.sa_vattr.va_nodeid;
8758c10a865Sas200622 
876da6c28aaSamw 	/*
877da6c28aaSamw 	 * Set up the file type in open_param for the response
878da6c28aaSamw 	 */
879da6c28aaSamw 	op->ftype = SMB_FTYPE_DISK;
880da6c28aaSamw 	sr->smb_fid = of->f_fid;
881da6c28aaSamw 	sr->fid_ofile = of;
882da6c28aaSamw 
8832c2961f8Sjose borrego 	smb_node_unlock(node);
884dc20a302Sas200622 	if (created)
8852c2961f8Sjose borrego 		smb_node_unlock(dnode);
8862c2961f8Sjose borrego 
887*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (op->fqi.fq_fattr.sa_vattr.va_type == VREG) {
8882c2961f8Sjose borrego 		smb_oplock_acquire(node, of, op);
889*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		op->dsize = op->fqi.fq_fattr.sa_vattr.va_size;
8902c2961f8Sjose borrego 	} else { /* VDIR or VLNK */
8912c2961f8Sjose borrego 		op->op_oplock_level = SMB_OPLOCK_NONE;
8922c2961f8Sjose borrego 		op->dsize = 0;
8932c2961f8Sjose borrego 	}
894dc20a302Sas200622 
8958b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	smb_node_release(node);
896da6c28aaSamw 	smb_node_release(dnode);
897da6c28aaSamw 	SMB_NULL_FQI_NODES(op->fqi);
898da6c28aaSamw 
899da6c28aaSamw 	return (NT_STATUS_SUCCESS);
900da6c28aaSamw }
901da6c28aaSamw 
902da6c28aaSamw /*
903da6c28aaSamw  * smb_validate_object_name
904da6c28aaSamw  *
9058d7e4166Sjose borrego  * Very basic file name validation.
9068d7e4166Sjose borrego  * For filenames, we check for names of the form "AAAn:". Names that
9078d7e4166Sjose borrego  * contain three characters, a single digit and a colon (:) are reserved
9088d7e4166Sjose borrego  * as DOS device names, i.e. "COM1:".
9098d7e4166Sjose borrego  * Stream name validation is handed off to smb_validate_stream_name
910da6c28aaSamw  *
911da6c28aaSamw  * Returns NT status codes.
912da6c28aaSamw  */
913da6c28aaSamw uint32_t
914*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States smb_validate_object_name(smb_pathname_t *pn)
915da6c28aaSamw {
916*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (pn->pn_fname &&
917*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	    strlen(pn->pn_fname) == 5 &&
918*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	    mts_isdigit(pn->pn_fname[3]) &&
919*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	    pn->pn_fname[4] == ':') {
920da6c28aaSamw 		return (NT_STATUS_OBJECT_NAME_INVALID);
921da6c28aaSamw 	}
922da6c28aaSamw 
923*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (pn->pn_sname)
924*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		return (smb_validate_stream_name(pn));
9258d7e4166Sjose borrego 
926*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	return (NT_STATUS_SUCCESS);
927da6c28aaSamw }
928da6c28aaSamw 
9298b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
930da6c28aaSamw /*
9318b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * This function is used to delete a newly created object (file or
9328b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  * directory) if an error occurs after creation of the object.
933da6c28aaSamw  */
9348b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States static void
9358b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_delete_new_object(smb_request_t *sr)
936da6c28aaSamw {
9378b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	open_param_t	*op = &sr->arg.open;
9388b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	smb_fqi_t	*fqi = &(op->fqi);
9398b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t	flags = 0;
9408b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
9418b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (SMB_TREE_IS_CASEINSENSITIVE(sr))
9428b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		flags |= SMB_IGNORE_CASE;
9438b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (SMB_TREE_SUPPORTS_CATIA(sr))
9448b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		flags |= SMB_CATIA;
9458b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
9468b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (op->create_options & FILE_DIRECTORY_FILE)
947*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		(void) smb_fsop_rmdir(sr, sr->user_cr, fqi->fq_dnode,
948*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		    fqi->fq_last_comp, flags);
9498b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	else
950*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		(void) smb_fsop_remove(sr, sr->user_cr, fqi->fq_dnode,
951*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		    fqi->fq_last_comp, flags);
952*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States }
953*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 
954*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States /*
955*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * smb_pathname_setup
956*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * Parse path: pname/fname:sname:stype
957*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  *
958*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * Elements of the smb_pathname_t structure are allocated using
959*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * smbsr_malloc and will thus be free'd when the sr is destroyed.
960*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  *
961*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * Eliminate duplicate slashes in pn->pn_path.
962*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * Populate pn structure elements with the individual elements
963*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * of pn->pn_path. pn->pn_sname will contain the whole stream name
964*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * including the stream type and preceding colon: :sname:%DATA
965*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * pn_stype will point to the stream type within pn_sname.
966*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  *
967*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * If any element is missing the pointer in pn will be NULL.
968*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  */
969*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States void
970*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_setup(smb_request_t *sr, smb_pathname_t *pn)
971*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States {
972*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	char *pname, *fname, *sname;
973*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	int len;
974*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 
975*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	(void) strcanon(pn->pn_path, "/\\");
976*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 
977*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	pname = pn->pn_path;
978*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	fname = strrchr(pn->pn_path, '\\');
979*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 
980*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (fname) {
981*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		if (fname == pname)
982*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			pname = NULL;
983*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		else {
984*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			*fname = '\0';
985*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			pn->pn_pname =
986*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			    smb_pathname_strdup(sr, pname);
987*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 			*fname = '\\';
988*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		}
989*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		++fname;
990*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	} else {
991*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		fname = pname;
992*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		pn->pn_pname = NULL;
993*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	}
994*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 
995*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_is_stream_name(fname)) {
996*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		pn->pn_fname =
997*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		    smb_pathname_strdup(sr, fname);
998*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		return;
999*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	}
1000*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 
1001*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	/* sname can't be NULL smb_is_stream_name checks this */
1002*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	sname = strchr(fname, ':');
1003*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (sname == fname)
1004*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		fname = NULL;
1005*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	else {
1006*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		*sname = '\0';
1007*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		pn->pn_fname =
1008*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		    smb_pathname_strdup(sr, fname);
1009*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		*sname = ':';
1010*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	}
1011*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 
1012*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	pn->pn_sname = smb_pathname_strdup(sr, sname);
1013*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	pn->pn_stype = strchr(pn->pn_sname + 1, ':');
1014*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (pn->pn_stype) {
1015*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		(void) utf8_strupr(pn->pn_stype);
1016*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	} else {
1017*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		len = strlen(pn->pn_sname);
1018*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		pn->pn_sname = smb_pathname_strcat(pn->pn_sname, ":$DATA");
1019*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		pn->pn_stype = pn->pn_sname + len;
1020*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	}
1021*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	++pn->pn_stype;
1022*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States }
1023*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 
1024*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States /*
1025*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * smb_pathname_strdup
1026*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  *
1027*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * Duplicate NULL terminated string s.
1028*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * The new string buffer is allocated using smbsr_malloc and
1029*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * will thus be free'd when the sr is destroyed.
1030*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  */
1031*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States static char *
1032*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_strdup(smb_request_t *sr, const char *s)
1033*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States {
1034*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	char *s2;
1035*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	size_t n;
1036*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 
1037*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	n = strlen(s) + 1;
1038*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	s2 = (char *)smbsr_malloc(&sr->request_storage, n);
1039*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	(void) strlcpy(s2, s, n);
1040*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	return (s2);
1041*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States }
1042*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 
1043*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States /*
1044*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * smb_pathname_strcat
1045*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  *
1046*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * Reallocate NULL terminated string s1 to accommodate
1047*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * concatenating  NULL terminated string s2.
1048*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * Append s2 and return resulting NULL terminated string.
1049*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  *
1050*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * The string buffer is reallocated using smbsr_realloc
1051*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  * and will thus be free'd when the sr is destroyed.
1052*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States  */
1053*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States static char *
1054*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_strcat(char *s1, const char *s2)
1055*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States {
1056*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	size_t n;
1057*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 
1058*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	n = strlen(s1) + strlen(s2) + 1;
1059*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	s1 = smbsr_realloc(s1, n);
1060*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	(void) strlcat(s1, s2, n);
1061*eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	return (s1);
1062da6c28aaSamw }
1063