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