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