xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_common_open.c (revision d5e8e65e99a4ed37bbb4a0deff5a670d982f91c1)
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 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * This module provides the common open functionality to the various
30  * open and create SMB interface functions.
31  */
32 
33 #include <smbsrv/smb_incl.h>
34 #include <smbsrv/smb_fsops.h>
35 #include <smbsrv/mlsvc.h>
36 #include <smbsrv/nterror.h>
37 #include <smbsrv/ntstatus.h>
38 #include <smbsrv/smbinfo.h>
39 #include <sys/fcntl.h>
40 #include <sys/nbmlock.h>
41 
42 extern uint32_t smb_is_executable(char *);
43 
44 static uint32_t smb_open_subr(smb_request_t *);
45 
46 /*
47  * The default stability mode is to perform the write-through
48  * behaviour requested by the client.
49  */
50 int smb_stable_mode = 0;
51 
52 
53 /*
54  * This macro is used to delete a newly created object
55  * if any error happens after creation of object.
56  */
57 #define	SMB_DEL_NEWOBJ(obj) \
58 	if (created) {							\
59 		if (is_dir)						\
60 			(void) smb_fsop_rmdir(sr, sr->user_cr,		\
61 			    obj.dir_snode, obj.last_comp, 0);		\
62 		else							\
63 			(void) smb_fsop_remove(sr, sr->user_cr,		\
64 			    obj.dir_snode, obj.last_comp, 0);		\
65 	}
66 
67 /*
68  * smb_set_stability
69  *
70  * Set the default stability mode. Normal (mode is zero) means perform
71  * the write-through behaviour requested by the client. Synchronous
72  * (mode is non-zero) means journal everything regardless of the write
73  * through behaviour requested by the client.
74  */
75 void
76 smb_set_stability(int mode)
77 {
78 	smb_stable_mode = mode;
79 }
80 
81 /*
82  * smb_access_generic_to_file
83  *
84  * Search MSDN for IoCreateFile to see following mapping.
85  *
86  * GENERIC_READ		STANDARD_RIGHTS_READ, FILE_READ_DATA,
87  *			FILE_READ_ATTRIBUTES and FILE_READ_EA
88  *
89  * GENERIC_WRITE	STANDARD_RIGHTS_WRITE, FILE_WRITE_DATA,
90  *               FILE_WRITE_ATTRIBUTES, FILE_WRITE_EA, and FILE_APPEND_DATA
91  *
92  * GENERIC_EXECUTE	STANDARD_RIGHTS_EXECUTE, SYNCHRONIZE, and FILE_EXECUTE.
93  */
94 uint32_t
95 smb_access_generic_to_file(uint32_t desired_access)
96 {
97 	uint32_t access = 0;
98 
99 	if (desired_access & GENERIC_ALL)
100 		return (FILE_ALL_ACCESS & ~SYNCHRONIZE);
101 
102 	if (desired_access & GENERIC_EXECUTE) {
103 		desired_access &= ~GENERIC_EXECUTE;
104 		access |= (STANDARD_RIGHTS_EXECUTE |
105 		    SYNCHRONIZE | FILE_EXECUTE);
106 	}
107 
108 	if (desired_access & GENERIC_WRITE) {
109 		desired_access &= ~GENERIC_WRITE;
110 		access |= (FILE_GENERIC_WRITE & ~SYNCHRONIZE);
111 	}
112 
113 	if (desired_access & GENERIC_READ) {
114 		desired_access &= ~GENERIC_READ;
115 		access |= FILE_GENERIC_READ;
116 	}
117 
118 	return (access | desired_access);
119 }
120 
121 /*
122  * smb_omode_to_amask
123  *
124  * This function converts open modes used by Open and Open AndX
125  * commands to desired access bits used by NT Create AndX command.
126  */
127 uint32_t
128 smb_omode_to_amask(uint32_t desired_access)
129 {
130 	switch (desired_access & SMB_DA_ACCESS_MASK) {
131 	case SMB_DA_ACCESS_READ:
132 		return (FILE_GENERIC_READ);
133 
134 	case SMB_DA_ACCESS_WRITE:
135 		return (FILE_GENERIC_WRITE);
136 
137 	case SMB_DA_ACCESS_READ_WRITE:
138 		return (FILE_GENERIC_READ | FILE_GENERIC_WRITE);
139 
140 	case SMB_DA_ACCESS_EXECUTE:
141 		return (FILE_GENERIC_EXECUTE);
142 	}
143 
144 	/* invalid open mode */
145 	return ((uint32_t)SMB_INVALID_AMASK);
146 }
147 
148 /*
149  * smb_denymode_to_sharemode
150  *
151  * This function converts deny modes used by Open and Open AndX
152  * commands to share access bits used by NT Create AndX command.
153  */
154 uint32_t
155 smb_denymode_to_sharemode(uint32_t desired_access, char *fname)
156 {
157 	switch (desired_access & SMB_DA_SHARE_MASK) {
158 	case SMB_DA_SHARE_COMPATIBILITY:
159 		if (smb_is_executable(fname))
160 			return (FILE_SHARE_READ | FILE_SHARE_WRITE);
161 		else {
162 			if ((desired_access &
163 			    SMB_DA_ACCESS_MASK) == SMB_DA_ACCESS_READ)
164 				return (FILE_SHARE_READ);
165 			else
166 				return (FILE_SHARE_NONE);
167 		}
168 
169 	case SMB_DA_SHARE_EXCLUSIVE:
170 		return (FILE_SHARE_NONE);
171 
172 	case SMB_DA_SHARE_DENY_WRITE:
173 		return (FILE_SHARE_READ);
174 
175 	case SMB_DA_SHARE_DENY_READ:
176 		return (FILE_SHARE_WRITE);
177 
178 	case SMB_DA_SHARE_DENY_NONE:
179 		return (FILE_SHARE_READ | FILE_SHARE_WRITE);
180 	}
181 
182 	/* invalid deny mode */
183 	return ((uint32_t)SMB_INVALID_SHAREMODE);
184 }
185 
186 /*
187  * smb_ofun_to_crdisposition
188  *
189  * This function converts open function values used by Open and Open AndX
190  * commands to create disposition values used by NT Create AndX command.
191  */
192 uint32_t
193 smb_ofun_to_crdisposition(uint16_t  ofun)
194 {
195 	static int ofun_cr_map[3][2] =
196 	{
197 		{ -1,			FILE_CREATE },
198 		{ FILE_OPEN,		FILE_OPEN_IF },
199 		{ FILE_OVERWRITE,	FILE_OVERWRITE_IF }
200 	};
201 
202 	int row = ofun & SMB_OFUN_OPEN_MASK;
203 	int col = (ofun & SMB_OFUN_CREATE_MASK) >> 4;
204 
205 	if (row == 3)
206 		return ((uint32_t)SMB_INVALID_CRDISPOSITION);
207 
208 	return (ofun_cr_map[row][col]);
209 }
210 
211 /*
212  * Retry opens to avoid spurious sharing violations, due to timing
213  * issues between closes and opens.  The client that already has the
214  * file open may be in the process of closing it.
215  */
216 uint32_t
217 smb_common_open(smb_request_t *sr)
218 {
219 	uint32_t status = NT_STATUS_SUCCESS;
220 	int count;
221 
222 	for (count = 0; count <= 4; count++) {
223 		if (count)
224 			delay(MSEC_TO_TICK(400));
225 
226 		if ((status = smb_open_subr(sr)) == NT_STATUS_SUCCESS)
227 			break;
228 	}
229 
230 	switch (status) {
231 	case NT_STATUS_SUCCESS:
232 		break;
233 
234 	case NT_STATUS_SHARING_VIOLATION:
235 		smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
236 		    ERRDOS, ERROR_SHARING_VIOLATION);
237 		break;
238 
239 	default:
240 		/* Error already set. */
241 		break;
242 	}
243 
244 	return (status);
245 }
246 
247 /*
248  * smb_open_subr
249  *
250  * Notes on write-through behaviour. It looks like pre-LM0.12 versions
251  * of the protocol specify the write-through mode when a file is opened,
252  * (SmbOpen, SmbOpenAndX) so the write calls (SmbWrite, SmbWriteAndClose,
253  * SmbWriteAndUnlock) don't need to contain a write-through flag.
254  *
255  * With LM0.12, the open calls (SmbCreateAndX, SmbNtTransactCreate)
256  * don't indicate which write-through mode to use. Instead the write
257  * calls (SmbWriteAndX, SmbWriteRaw) specify the mode on a per call
258  * basis.
259  *
260  * We don't care which open call was used to get us here, we just need
261  * to ensure that the write-through mode flag is copied from the open
262  * parameters to the node. We test the omode write-through flag in all
263  * write functions.
264  *
265  * This function will return NT status codes but it also raises errors,
266  * in which case it won't return to the caller. Be careful how you
267  * handle things in here.
268  */
269 
270 static uint32_t
271 smb_open_subr(smb_request_t *sr)
272 {
273 	int			created = 0;
274 	struct smb_node		*node = 0;
275 	struct smb_node		*dnode = 0;
276 	struct smb_node		*cur_node;
277 	struct open_param	*op = &sr->arg.open;
278 	int			rc;
279 	struct smb_ofile	*of;
280 	smb_attr_t		new_attr;
281 	int			pathlen;
282 	int			max_requested = 0;
283 	uint32_t		max_allowed;
284 	unsigned int		granted_oplock;
285 	uint32_t		status = NT_STATUS_SUCCESS;
286 	int			is_dir;
287 	smb_error_t		err;
288 	int			is_stream = 0;
289 	int			lookup_flags = SMB_FOLLOW_LINKS;
290 	uint32_t		daccess;
291 	uint32_t		share_access = op->share_access;
292 	uint32_t		uniq_fid;
293 
294 	is_dir = (op->create_options & FILE_DIRECTORY_FILE) ? 1 : 0;
295 
296 	if (is_dir) {
297 		/*
298 		 * The object being created or opened is a directory,
299 		 * and the Disposition parameter must be one of
300 		 * FILE_CREATE, FILE_OPEN, or FILE_OPEN_IF
301 		 */
302 		if ((op->create_disposition != FILE_CREATE) &&
303 		    (op->create_disposition != FILE_OPEN_IF) &&
304 		    (op->create_disposition != FILE_OPEN)) {
305 			smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
306 			    ERRDOS, ERROR_INVALID_ACCESS);
307 			return (NT_STATUS_INVALID_PARAMETER);
308 		}
309 	}
310 
311 	if (op->desired_access & MAXIMUM_ALLOWED) {
312 		max_requested = 1;
313 		op->desired_access &= ~MAXIMUM_ALLOWED;
314 	}
315 	op->desired_access = smb_access_generic_to_file(op->desired_access);
316 
317 	if (sr->session->s_file_cnt >= SMB_SESSION_OFILE_MAX) {
318 		ASSERT(sr->uid_user);
319 		cmn_err(CE_NOTE, "smbd[%s\\%s]: %s", sr->uid_user->u_domain,
320 		    sr->uid_user->u_name,
321 		    xlate_nt_status(NT_STATUS_TOO_MANY_OPENED_FILES));
322 
323 		smbsr_error(sr, NT_STATUS_TOO_MANY_OPENED_FILES,
324 		    ERRDOS, ERROR_TOO_MANY_OPEN_FILES);
325 		return (NT_STATUS_TOO_MANY_OPENED_FILES);
326 	}
327 
328 	/* This must be NULL at this point */
329 	sr->fid_ofile = NULL;
330 
331 	op->devstate = 0;
332 
333 	switch (sr->tid_tree->t_res_type & STYPE_MASK) {
334 	case STYPE_DISKTREE:
335 		break;
336 
337 	case STYPE_IPC:
338 		/*
339 		 * No further processing for IPC, we need to either
340 		 * raise an exception or return success here.
341 		 */
342 		if ((status = smb_rpc_open(sr)) != NT_STATUS_SUCCESS)
343 			smbsr_error(sr, status, 0, 0);
344 		return (status);
345 
346 	default:
347 		smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE,
348 		    ERRDOS, ERROR_BAD_DEV_TYPE);
349 		return (NT_STATUS_BAD_DEVICE_TYPE);
350 	}
351 
352 	if ((pathlen = strlen(op->fqi.path)) >= MAXPATHLEN) {
353 		smbsr_error(sr, 0, ERRSRV, ERRfilespecs);
354 		return (NT_STATUS_NAME_TOO_LONG);
355 	}
356 
357 	/*
358 	 * Some clients pass null file names; NT interprets this as "\".
359 	 */
360 	if (pathlen == 0) {
361 		op->fqi.path = "\\";
362 		pathlen = 1;
363 	}
364 
365 	op->fqi.srch_attr = op->fqi.srch_attr;
366 
367 	if ((status = smb_validate_object_name(op->fqi.path, is_dir)) != 0) {
368 		smbsr_error(sr, status, ERRDOS, ERROR_INVALID_NAME);
369 		return (status);
370 	}
371 
372 	cur_node = op->fqi.dir_snode ?
373 	    op->fqi.dir_snode : sr->tid_tree->t_snode;
374 
375 	if (rc = smb_pathname_reduce(sr, sr->user_cr, op->fqi.path,
376 	    sr->tid_tree->t_snode, cur_node, &op->fqi.dir_snode,
377 	    op->fqi.last_comp)) {
378 		smbsr_errno(sr, rc);
379 		return (sr->smb_error.status);
380 	}
381 
382 	/*
383 	 * If the access mask has only DELETE set (ignore
384 	 * FILE_READ_ATTRIBUTES), then assume that this
385 	 * is a request to delete the link (if a link)
386 	 * and do not follow links.  Otherwise, follow
387 	 * the link to the target.
388 	 */
389 
390 	daccess = op->desired_access & ~FILE_READ_ATTRIBUTES;
391 
392 	if (daccess == DELETE)
393 		lookup_flags &= ~SMB_FOLLOW_LINKS;
394 
395 	rc = smb_fsop_lookup_name(sr, kcred, lookup_flags,
396 	    sr->tid_tree->t_snode, op->fqi.dir_snode, op->fqi.last_comp,
397 	    &op->fqi.last_snode, &op->fqi.last_attr);
398 
399 	if (rc == 0) {
400 		op->fqi.last_comp_was_found = 1;
401 		(void) strcpy(op->fqi.last_comp_od,
402 		    op->fqi.last_snode->od_name);
403 	} else if (rc == ENOENT) {
404 		op->fqi.last_comp_was_found = 0;
405 		op->fqi.last_snode = NULL;
406 		rc = 0;
407 	} else {
408 		smb_node_release(op->fqi.dir_snode);
409 		SMB_NULL_FQI_NODES(op->fqi);
410 		smbsr_errno(sr, rc);
411 		return (sr->smb_error.status);
412 	}
413 
414 	/*
415 	 * The uniq_fid is a CIFS-server-wide unique identifier for an ofile
416 	 * which is used to uniquely identify open instances for the
417 	 * VFS share reservation mechanism (accessed via smb_fsop_shrlock()).
418 	 */
419 
420 	uniq_fid = SMB_UNIQ_FID();
421 
422 	if (op->fqi.last_comp_was_found) {
423 		node = op->fqi.last_snode;
424 		dnode = op->fqi.dir_snode;
425 
426 		/*
427 		 * Enter critical region for share reservations.
428 		 * (See comments above smb_fsop_shrlock().)
429 		 */
430 
431 		rw_enter(&node->n_share_lock, RW_WRITER);
432 
433 		/*
434 		 * Reject this request if the target is a directory
435 		 * and the client has specified that it must not be
436 		 * a directory (required by Lotus Notes).
437 		 */
438 		if ((op->create_options & FILE_NON_DIRECTORY_FILE) &&
439 		    (op->fqi.last_attr.sa_vattr.va_type == VDIR)) {
440 			rw_exit(&node->n_share_lock);
441 			smb_node_release(node);
442 			smb_node_release(dnode);
443 			SMB_NULL_FQI_NODES(op->fqi);
444 			smbsr_error(sr, NT_STATUS_FILE_IS_A_DIRECTORY,
445 			    ERRDOS, ERROR_ACCESS_DENIED);
446 			return (NT_STATUS_FILE_IS_A_DIRECTORY);
447 		}
448 
449 		if (op->fqi.last_attr.sa_vattr.va_type == VDIR) {
450 			if ((sr->smb_com == SMB_COM_OPEN_ANDX) ||
451 			    (sr->smb_com == SMB_COM_OPEN)) {
452 				/*
453 				 * Directories cannot be opened
454 				 * with the above commands
455 				 */
456 				rw_exit(&node->n_share_lock);
457 				smb_node_release(node);
458 				smb_node_release(dnode);
459 				SMB_NULL_FQI_NODES(op->fqi);
460 				smbsr_error(sr, NT_STATUS_FILE_IS_A_DIRECTORY,
461 				    ERRDOS, ERROR_ACCESS_DENIED);
462 				return (NT_STATUS_FILE_IS_A_DIRECTORY);
463 			}
464 		} else if (op->my_flags & MYF_MUST_BE_DIRECTORY) {
465 			rw_exit(&node->n_share_lock);
466 			smb_node_release(node);
467 			smb_node_release(dnode);
468 			SMB_NULL_FQI_NODES(op->fqi);
469 			smbsr_error(sr, NT_STATUS_NOT_A_DIRECTORY,
470 			    ERRDOS, ERROR_DIRECTORY);
471 			return (NT_STATUS_NOT_A_DIRECTORY);
472 		}
473 
474 		/*
475 		 * No more open should be accepted when "Delete on close"
476 		 * flag is set.
477 		 */
478 		if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
479 			rw_exit(&node->n_share_lock);
480 			smb_node_release(node);
481 			smb_node_release(dnode);
482 			SMB_NULL_FQI_NODES(op->fqi);
483 			smbsr_error(sr, NT_STATUS_DELETE_PENDING,
484 			    ERRDOS, ERROR_ACCESS_DENIED);
485 			return (NT_STATUS_DELETE_PENDING);
486 		}
487 
488 		/*
489 		 * Specified file already exists so the operation should fail.
490 		 */
491 		if (op->create_disposition == FILE_CREATE) {
492 			rw_exit(&node->n_share_lock);
493 			smb_node_release(node);
494 			smb_node_release(dnode);
495 			SMB_NULL_FQI_NODES(op->fqi);
496 			smbsr_error(sr, NT_STATUS_OBJECT_NAME_COLLISION,
497 			    ERRDOS, ERROR_ALREADY_EXISTS);
498 			return (NT_STATUS_OBJECT_NAME_COLLISION);
499 		}
500 
501 		/*
502 		 * Windows seems to check read-only access before file
503 		 * sharing check.
504 		 */
505 		if (NODE_IS_READONLY(node)) {
506 			/* Files data only */
507 			if (node->attr.sa_vattr.va_type != VDIR) {
508 				if (op->desired_access & (FILE_WRITE_DATA |
509 				    FILE_APPEND_DATA)) {
510 					rw_exit(&node->n_share_lock);
511 					smb_node_release(node);
512 					smb_node_release(dnode);
513 					SMB_NULL_FQI_NODES(op->fqi);
514 					smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
515 					    ERRDOS, ERRnoaccess);
516 					return (NT_STATUS_ACCESS_DENIED);
517 				}
518 			}
519 		}
520 
521 		/*
522 		 * The following check removes the need to check share
523 		 * reservations again when a truncate is done.
524 		 */
525 
526 		if ((op->create_disposition == FILE_SUPERSEDE) ||
527 		    (op->create_disposition == FILE_OVERWRITE_IF) ||
528 		    (op->create_disposition == FILE_OVERWRITE)) {
529 
530 			if (!(op->desired_access &
531 			    (FILE_WRITE_DATA | FILE_APPEND_DATA))) {
532 				rw_exit(&node->n_share_lock);
533 				smb_node_release(node);
534 				smb_node_release(dnode);
535 				SMB_NULL_FQI_NODES(op->fqi);
536 				smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
537 				    ERRDOS, ERRnoaccess);
538 				return (NT_STATUS_ACCESS_DENIED);
539 			}
540 		}
541 
542 		status = smb_fsop_shrlock(sr->user_cr, node, uniq_fid,
543 		    op->desired_access, share_access);
544 
545 		if (status == NT_STATUS_SHARING_VIOLATION) {
546 			rw_exit(&node->n_share_lock);
547 			smb_node_release(node);
548 			smb_node_release(dnode);
549 			SMB_NULL_FQI_NODES(op->fqi);
550 			return (status);
551 		}
552 
553 		status = smb_fsop_access(sr, sr->user_cr, node,
554 		    op->desired_access);
555 
556 		if (status != NT_STATUS_SUCCESS) {
557 			smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
558 
559 			rw_exit(&node->n_share_lock);
560 			smb_node_release(node);
561 			smb_node_release(dnode);
562 			SMB_NULL_FQI_NODES(op->fqi);
563 
564 			if (status == NT_STATUS_PRIVILEGE_NOT_HELD) {
565 				smbsr_error(sr, status,
566 				    ERRDOS, ERROR_PRIVILEGE_NOT_HELD);
567 				return (status);
568 			} else {
569 				smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
570 				    ERRDOS, ERROR_ACCESS_DENIED);
571 				return (NT_STATUS_ACCESS_DENIED);
572 			}
573 		}
574 
575 		/*
576 		 * Break the oplock before share checks. If another client
577 		 * has the file open, this will force a flush or close,
578 		 * which may affect the outcome of any share checking.
579 		 */
580 
581 		if (OPLOCKS_IN_FORCE(node)) {
582 			status = smb_break_oplock(sr, node);
583 
584 			if (status != NT_STATUS_SUCCESS) {
585 				rw_exit(&node->n_share_lock);
586 				smb_node_release(node);
587 				smb_node_release(dnode);
588 				SMB_NULL_FQI_NODES(op->fqi);
589 				smbsr_error(sr, status,
590 				    ERRDOS, ERROR_VC_DISCONNECTED);
591 				return (status);
592 			}
593 		}
594 
595 		switch (op->create_disposition) {
596 		case FILE_SUPERSEDE:
597 		case FILE_OVERWRITE_IF:
598 		case FILE_OVERWRITE:
599 			if (node->attr.sa_vattr.va_type == VDIR) {
600 				smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
601 				rw_exit(&node->n_share_lock);
602 				smb_node_release(node);
603 				smb_node_release(dnode);
604 				SMB_NULL_FQI_NODES(op->fqi);
605 				smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
606 				    ERRDOS, ERROR_ACCESS_DENIED);
607 				return (NT_STATUS_ACCESS_DENIED);
608 			}
609 
610 			if (node->attr.sa_vattr.va_size != op->dsize) {
611 				node->flags &= ~NODE_FLAGS_SET_SIZE;
612 				bzero(&new_attr, sizeof (new_attr));
613 				new_attr.sa_vattr.va_size = op->dsize;
614 				new_attr.sa_mask = SMB_AT_SIZE;
615 
616 				rc = smb_fsop_setattr(sr, sr->user_cr,
617 				    node, &new_attr, &op->fqi.last_attr);
618 
619 				if (rc) {
620 					smb_fsop_unshrlock(sr->user_cr,
621 					    node, uniq_fid);
622 					rw_exit(&node->n_share_lock);
623 					smb_node_release(node);
624 					smb_node_release(dnode);
625 					SMB_NULL_FQI_NODES(op->fqi);
626 					smbsr_errno(sr, rc);
627 					return (sr->smb_error.status);
628 				}
629 
630 				op->dsize = op->fqi.last_attr.sa_vattr.va_size;
631 			}
632 
633 			/*
634 			 * If file is being replaced,
635 			 * we should remove existing streams
636 			 */
637 			if (SMB_IS_STREAM(node) == 0)
638 				(void) smb_fsop_remove_streams(sr, sr->user_cr,
639 				    node);
640 
641 			op->action_taken = SMB_OACT_TRUNCATED;
642 			break;
643 
644 		default:
645 			/*
646 			 * FILE_OPEN or FILE_OPEN_IF.
647 			 */
648 			op->action_taken = SMB_OACT_OPENED;
649 			break;
650 		}
651 	} else {
652 
653 		/* Last component was not found. */
654 		dnode = op->fqi.dir_snode;
655 
656 		if (is_dir == 0)
657 			is_stream = smb_stream_parse_name(op->fqi.path,
658 			    NULL, NULL);
659 
660 		if ((op->create_disposition == FILE_OPEN) ||
661 		    (op->create_disposition == FILE_OVERWRITE)) {
662 			smb_node_release(dnode);
663 			SMB_NULL_FQI_NODES(op->fqi);
664 
665 			/*
666 			 * The requested file not found so the operation should
667 			 * fail with these two dispositions
668 			 */
669 			if (is_stream)
670 				smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND,
671 				    ERRDOS, ERROR_FILE_NOT_FOUND);
672 			else
673 				smbsr_error(sr, 0, ERRDOS, ERRbadfile);
674 
675 			return (NT_STATUS_OBJECT_NAME_NOT_FOUND);
676 		}
677 
678 		/*
679 		 * lock the parent dir node in case another create
680 		 * request to the same parent directory comes in.
681 		 */
682 		smb_rwx_rwenter(&dnode->n_lock, RW_WRITER);
683 
684 		bzero(&new_attr, sizeof (new_attr));
685 		if (is_dir == 0) {
686 			new_attr.sa_vattr.va_type = VREG;
687 			new_attr.sa_vattr.va_mode = is_stream ? S_IRUSR :
688 			    S_IRUSR | S_IRGRP | S_IROTH |
689 			    S_IWUSR | S_IWGRP | S_IWOTH;
690 			new_attr.sa_mask = SMB_AT_TYPE | SMB_AT_MODE;
691 
692 			/*
693 			 * A problem with setting the readonly bit at
694 			 * create time is that this bit will prevent
695 			 * writes to the file from the same fid (which
696 			 * should be allowed).
697 			 *
698 			 * The solution is to set the bit at close time.
699 			 * Meanwhile, to prevent racing opens from being
700 			 * able to write to the file, the bit is set at
701 			 * create time until share reservations can be set
702 			 * to prevent write and delete access.  At that point,
703 			 * the bit can be turned off until close (so as to
704 			 * allow writes from the same fid to the file).
705 			 */
706 
707 			if (op->dattr & SMB_FA_READONLY) {
708 				new_attr.sa_dosattr = FILE_ATTRIBUTE_READONLY;
709 				new_attr.sa_mask |= SMB_AT_DOSATTR;
710 			}
711 
712 			rc = smb_fsop_create(sr, sr->user_cr, dnode,
713 			    op->fqi.last_comp, &new_attr,
714 			    &op->fqi.last_snode, &op->fqi.last_attr);
715 
716 			if (rc != 0) {
717 				smb_rwx_rwexit(&dnode->n_lock);
718 				smb_node_release(dnode);
719 				SMB_NULL_FQI_NODES(op->fqi);
720 				smbsr_errno(sr, rc);
721 				return (sr->smb_error.status);
722 			}
723 
724 			if (op->dattr & SMB_FA_READONLY) {
725 				share_access &= ~(FILE_SHARE_WRITE |
726 				    FILE_SHARE_DELETE);
727 			}
728 
729 			node = op->fqi.last_snode;
730 
731 			rw_enter(&node->n_share_lock, RW_WRITER);
732 
733 			status = smb_fsop_shrlock(sr->user_cr, node,
734 			    uniq_fid, op->desired_access,
735 			    share_access);
736 
737 			if (status == NT_STATUS_SHARING_VIOLATION) {
738 				rw_exit(&node->n_share_lock);
739 				smb_node_release(node);
740 				smb_node_release(dnode);
741 				SMB_NULL_FQI_NODES(op->fqi);
742 				return (status);
743 			}
744 
745 			new_attr = op->fqi.last_attr;
746 			new_attr.sa_mask = 0;
747 
748 			if (op->dattr & SMB_FA_READONLY) {
749 				new_attr.sa_dosattr &= ~FILE_ATTRIBUTE_READONLY;
750 				new_attr.sa_mask |= SMB_AT_DOSATTR;
751 			}
752 
753 			if (op->dsize) {
754 				new_attr.sa_vattr.va_size = op->dsize;
755 				new_attr.sa_mask |= SMB_AT_SIZE;
756 			}
757 
758 			if (new_attr.sa_mask) {
759 				node->attr = new_attr;
760 				node->what = new_attr.sa_mask;
761 				rc = smb_sync_fsattr(sr, sr->user_cr, node);
762 
763 				if (rc != 0) {
764 					smb_fsop_unshrlock(sr->user_cr, node,
765 					    uniq_fid);
766 
767 					rw_exit(&node->n_share_lock);
768 					smb_node_release(node);
769 					(void) smb_fsop_remove(sr, sr->user_cr,
770 					    dnode, op->fqi.last_comp, 0);
771 					smb_rwx_rwexit(&dnode->n_lock);
772 					smb_node_release(dnode);
773 					SMB_NULL_FQI_NODES(op->fqi);
774 					smbsr_errno(sr, rc);
775 					return (sr->smb_error.status);
776 				} else {
777 					op->fqi.last_attr = node->attr;
778 				}
779 			}
780 
781 		} else {
782 			op->dattr |= SMB_FA_DIRECTORY;
783 			new_attr.sa_vattr.va_type = VDIR;
784 			new_attr.sa_vattr.va_mode = 0777;
785 			new_attr.sa_mask = SMB_AT_TYPE | SMB_AT_MODE;
786 			rc = smb_fsop_mkdir(sr, sr->user_cr, dnode,
787 			    op->fqi.last_comp, &new_attr,
788 			    &op->fqi.last_snode, &op->fqi.last_attr);
789 			if (rc != 0) {
790 				smb_rwx_rwexit(&dnode->n_lock);
791 				smb_node_release(dnode);
792 				SMB_NULL_FQI_NODES(op->fqi);
793 				smbsr_errno(sr, rc);
794 				return (sr->smb_error.status);
795 			}
796 
797 			node = op->fqi.last_snode;
798 			rw_enter(&node->n_share_lock, RW_WRITER);
799 		}
800 
801 		created = 1;
802 		op->action_taken = SMB_OACT_CREATED;
803 	}
804 
805 	if ((op->fqi.last_attr.sa_vattr.va_type != VREG) &&
806 	    (op->fqi.last_attr.sa_vattr.va_type != VDIR) &&
807 	    (op->fqi.last_attr.sa_vattr.va_type != VLNK)) {
808 		/* not allowed to do this */
809 
810 		smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
811 
812 		SMB_DEL_NEWOBJ(op->fqi);
813 		rw_exit(&node->n_share_lock);
814 		smb_node_release(node);
815 		if (created)
816 			smb_rwx_rwexit(&dnode->n_lock);
817 		smb_node_release(dnode);
818 		SMB_NULL_FQI_NODES(op->fqi);
819 		smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
820 		return (NT_STATUS_ACCESS_DENIED);
821 	}
822 
823 	if (max_requested) {
824 		smb_fsop_eaccess(sr, sr->user_cr, node, &max_allowed);
825 		op->desired_access |= max_allowed;
826 	}
827 
828 	/*
829 	 * smb_ofile_open() will copy node to of->node.  Hence
830 	 * the hold on node (i.e. op->fqi.last_snode) will be "transferred"
831 	 * to the "of" structure.
832 	 */
833 
834 	of = smb_ofile_open(sr->tid_tree, node, sr->smb_pid, op->desired_access,
835 	    op->create_options, share_access, SMB_FTYPE_DISK, NULL, 0,
836 	    uniq_fid, &err);
837 
838 	if (of == NULL) {
839 		smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
840 
841 		SMB_DEL_NEWOBJ(op->fqi);
842 		rw_exit(&node->n_share_lock);
843 		smb_node_release(node);
844 		if (created)
845 			smb_rwx_rwexit(&dnode->n_lock);
846 		smb_node_release(dnode);
847 		SMB_NULL_FQI_NODES(op->fqi);
848 		smbsr_error(sr, err.status, err.errcls, err.errcode);
849 		return (err.status);
850 	}
851 
852 	/*
853 	 * Propagate the write-through mode from the open params
854 	 * to the node: see the notes in the function header.
855 	 *
856 	 * IR #102318 Mirroring may force synchronous
857 	 * writes regardless of what we specify here.
858 	 */
859 	if (smb_stable_mode || (op->create_options & FILE_WRITE_THROUGH))
860 		node->flags |= NODE_FLAGS_WRITE_THROUGH;
861 
862 	op->fileid = op->fqi.last_attr.sa_vattr.va_nodeid;
863 
864 	if (op->fqi.last_attr.sa_vattr.va_type == VDIR) {
865 		/* We don't oplock directories */
866 		op->my_flags &= ~MYF_OPLOCK_MASK;
867 		op->dsize = 0;
868 	} else {
869 		status = smb_acquire_oplock(sr, of, op->my_flags,
870 		    &granted_oplock);
871 		op->my_flags &= ~MYF_OPLOCK_MASK;
872 
873 		if (status != NT_STATUS_SUCCESS) {
874 			rw_exit(&node->n_share_lock);
875 			/*
876 			 * smb_fsop_unshrlock() and smb_fsop_close()
877 			 * are called from smb_ofile_close()
878 			 */
879 			(void) smb_ofile_close(of, 0);
880 			smb_ofile_release(of);
881 			if (created)
882 				smb_rwx_rwexit(&dnode->n_lock);
883 
884 			smb_node_release(dnode);
885 			SMB_NULL_FQI_NODES(op->fqi);
886 
887 			smbsr_error(sr, status,
888 			    ERRDOS, ERROR_SHARING_VIOLATION);
889 			return (status);
890 		}
891 
892 		op->my_flags |= granted_oplock;
893 		op->dsize = op->fqi.last_attr.sa_vattr.va_size;
894 	}
895 
896 	if (created) {
897 		node->flags |= NODE_FLAGS_CREATED;
898 		/*
899 		 * Clients may set the DOS readonly bit on create but they
900 		 * expect subsequent write operations on the open fid to
901 		 * succeed.  Thus the DOS readonly bit is not set permanently
902 		 * until the file is closed.  The NODE_CREATED_READONLY flag
903 		 * will act as the indicator to set the DOS readonly bit on
904 		 * close.
905 		 *	Above, the readonly bit is set on create, share
906 		 * reservations are set, and then the bit is unset.
907 		 * These actions allow writes to the open fid to succeed
908 		 * until the file is closed while preventing write access
909 		 * from other opens while this fid is active.
910 		 */
911 		if (op->dattr & SMB_FA_READONLY) {
912 			node->flags |= NODE_CREATED_READONLY;
913 			op->dattr &= ~SMB_FA_READONLY;
914 		}
915 		smb_node_set_dosattr(node, op->dattr | SMB_FA_ARCHIVE);
916 		if (op->utime.tv_sec == 0 || op->utime.tv_sec == UINT_MAX)
917 			(void) microtime(&op->utime);
918 		smb_node_set_time(node, NULL, &op->utime, 0, 0, SMB_AT_MTIME);
919 		(void) smb_sync_fsattr(sr, sr->user_cr, node);
920 	} else {
921 		/*
922 		 * If we reach here, it means that file already exists
923 		 * and if create disposition is one of: FILE_SUPERSEDE,
924 		 * FILE_OVERWRITE_IF, or FILE_OVERWRITE it
925 		 * means that client wants to overwrite (or truncate)
926 		 * the existing file. So we should overwrite the dos
927 		 * attributes of destination file with the dos attributes
928 		 * of source file.
929 		 */
930 
931 		switch (op->create_disposition) {
932 		case FILE_SUPERSEDE:
933 		case FILE_OVERWRITE_IF:
934 		case FILE_OVERWRITE:
935 			smb_node_set_dosattr(node,
936 			    op->dattr | SMB_FA_ARCHIVE);
937 			(void) smb_sync_fsattr(sr, sr->user_cr, node);
938 		}
939 		op->utime = *smb_node_get_crtime(node);
940 		op->dattr = smb_node_get_dosattr(node);
941 	}
942 
943 	/*
944 	 * Set up the file type in open_param for the response
945 	 */
946 	op->ftype = SMB_FTYPE_DISK;
947 	sr->smb_fid = of->f_fid;
948 	sr->fid_ofile = of;
949 
950 	rw_exit(&node->n_share_lock);
951 
952 	if (created)
953 		smb_rwx_rwexit(&dnode->n_lock);
954 
955 	smb_node_release(dnode);
956 	SMB_NULL_FQI_NODES(op->fqi);
957 
958 	return (NT_STATUS_SUCCESS);
959 }
960 
961 /*
962  * smb_validate_object_name
963  *
964  * Very basic file name validation. Directory validation is handed off
965  * to smb_validate_dirname. For filenames, we check for names of the
966  * form "AAAn:". Names that contain three characters, a single digit
967  * and a colon (:) are reserved as DOS device names, i.e. "COM1:".
968  *
969  * Returns NT status codes.
970  */
971 uint32_t
972 smb_validate_object_name(char *path, unsigned int ftype)
973 {
974 	char *filename;
975 
976 	if (path == 0)
977 		return (0);
978 
979 	if (ftype)
980 		return (smb_validate_dirname(path));
981 
982 	/*
983 	 * Basename with backslashes.
984 	 */
985 	if ((filename = strrchr(path, '\\')) != 0)
986 		++filename;
987 	else
988 		filename = path;
989 
990 	if (strlen(filename) == 5 &&
991 	    mts_isdigit(filename[3]) &&
992 	    filename[4] == ':') {
993 		return (NT_STATUS_OBJECT_NAME_INVALID);
994 	}
995 
996 	return (0);
997 }
998 
999 /*
1000  * smb_preset_delete_on_close
1001  *
1002  * Set the DeleteOnClose flag on the smb file. When the file is closed,
1003  * the flag will be transferred to the smb node, which will commit the
1004  * delete operation and inhibit subsequent open requests.
1005  *
1006  * When DeleteOnClose is set on an smb_node, the common open code will
1007  * reject subsequent open requests for the file. Observation of Windows
1008  * 2000 indicates that subsequent opens should be allowed (assuming
1009  * there would be no sharing violation) until the file is closed using
1010  * the fid on which the DeleteOnClose was requested.
1011  */
1012 void
1013 smb_preset_delete_on_close(smb_ofile_t *file)
1014 {
1015 	mutex_enter(&file->f_mutex);
1016 	file->f_flags |= SMB_OFLAGS_SET_DELETE_ON_CLOSE;
1017 	mutex_exit(&file->f_mutex);
1018 }
1019