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