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