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