da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The contents of this file are subject to the terms of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Common Development and Distribution License (the "License").
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You may not use this file except in compliance with the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * When distributing Covered Code, include this CDDL HEADER in each
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If applicable, add the following below this CDDL HEADER, with the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fields enclosed by brackets "[]" replaced with your own identifying
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * information: Portions Copyright [yyyy] [name of copyright owner]
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This module provides the common open functionality to the various
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * open and create SMB interface functions.
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#define SMB_UNIQ_FID() atomic_inc_32_nv(&smb_fids)
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United Statesstatic void smb_delete_new_object(smb_request_t *);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Rossstatic int smb_set_open_attributes(smb_request_t *, smb_ofile_t *);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintoshstatic void smb_open_oplock_break(smb_request_t *, smb_node_t *);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintoshstatic boolean_t smb_open_attr_only(smb_arg_open_t *);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintoshstatic boolean_t smb_open_overwrite(smb_arg_open_t *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_access_generic_to_file
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Search MSDN for IoCreateFile to see following mapping.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * GENERIC_READ STANDARD_RIGHTS_READ, FILE_READ_DATA,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * FILE_READ_ATTRIBUTES and FILE_READ_EA
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * GENERIC_WRITE STANDARD_RIGHTS_WRITE, FILE_WRITE_DATA,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * FILE_WRITE_ATTRIBUTES, FILE_WRITE_EA, and FILE_APPEND_DATA
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * GENERIC_EXECUTE STANDARD_RIGHTS_EXECUTE, SYNCHRONIZE, and FILE_EXECUTE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_omode_to_amask
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This function converts open modes used by Open and Open AndX
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * commands to desired access bits used by NT Create AndX command.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_denymode_to_sharemode
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This function converts deny modes used by Open and Open AndX
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * commands to share access bits used by NT Create AndX command.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_denymode_to_sharemode(uint32_t desired_access, char *fname)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_ofun_to_crdisposition
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This function converts open function values used by Open and Open AndX
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * commands to create disposition values used by NT Create AndX command.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * Retry opens to avoid spurious sharing violations, due to timing
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * issues between closes and opens. The client that already has the
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * file open may be in the process of closing it.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_open_subr
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Notes on write-through behaviour. It looks like pre-LM0.12 versions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * of the protocol specify the write-through mode when a file is opened,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * (SmbOpen, SmbOpenAndX) so the write calls (SmbWrite, SmbWriteAndClose,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * SmbWriteAndUnlock) don't need to contain a write-through flag.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * With LM0.12, the open calls (SmbCreateAndX, SmbNtTransactCreate)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * don't indicate which write-through mode to use. Instead the write
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * calls (SmbWriteAndX, SmbWriteRaw) specify the mode on a per call
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * We don't care which open call was used to get us here, we just need
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to ensure that the write-through mode flag is copied from the open
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * parameters to the node. We test the omode write-through flag in all
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * write functions.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * This function returns NT status codes.
8c10a8659ac31335ed870a1711c0182623f72fd6as * The following rules apply when processing a file open request:
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * - Oplocks must be broken prior to share checking as the break may
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * cause other clients to close the file, which would affect sharing
8c10a8659ac31335ed870a1711c0182623f72fd6as * - Share checks must take place prior to access checks for correct
8c10a8659ac31335ed870a1711c0182623f72fd6as * Windows semantics and to prevent unnecessary NFS delegation recalls.
8c10a8659ac31335ed870a1711c0182623f72fd6as * - Oplocks must be acquired after open to ensure the correct
8c10a8659ac31335ed870a1711c0182623f72fd6as * synchronization with NFS delegation and FEM installation.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * DOS readonly bit rules
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * 1. The creator of a readonly file can write to/modify the size of the file
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * using the original create fid, even though the file will appear as readonly
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * to all other fids and via a CIFS getattr call.
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * The readonly bit therefore cannot be set in the filesystem until the file
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * is closed (smb_ofile_close). It is accounted for via ofile and node flags.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * 2. A setinfo operation (using either an open fid or a path) to set/unset
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * readonly will be successful regardless of whether a creator of a readonly
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * file has an open fid (and has the special privilege mentioned in #1,
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * above). I.e., the creator of a readonly fid holding that fid will no longer
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * have a special privilege.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * 3. The DOS readonly bit affects only data and some metadata.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * The following metadata can be changed regardless of the readonly bit:
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * - security descriptors
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * - DOS attributes
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * - timestamps
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * In the current implementation, the file size cannot be changed (except for
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * the exceptions in #1 and #2, above).
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * DOS attribute rules
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * These rules are specific to creating / opening files and directories.
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * How the attribute value (specifically ZERO or FILE_ATTRIBUTE_NORMAL)
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * should be interpreted may differ in other requests.
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * - An attribute value equal to ZERO or FILE_ATTRIBUTE_NORMAL means that the
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * file's attributes should be cleared.
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * - If FILE_ATTRIBUTE_NORMAL is specified with any other attributes,
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * FILE_ATTRIBUTE_NORMAL is ignored.
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * 1. Creating a new file
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * - The request attributes + FILE_ATTRIBUTE_ARCHIVE are applied to the file.
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * 2. Creating a new directory
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * - The request attributes + FILE_ATTRIBUTE_DIRECTORY are applied to the file.
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * - FILE_ATTRIBUTE_ARCHIVE does not get set.
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * 3. Overwriting an existing file
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * - the request attributes are used as search attributes. If the existing
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * file does not meet the search criteria access is denied.
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * - otherwise, applies attributes + FILE_ATTRIBUTE_ARCHIVE.
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * 4. Opening an existing file or directory
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * The request attributes are ignored.
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States boolean_t created = B_FALSE;
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States boolean_t last_comp_found = B_FALSE;
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_t *cur_node = NULL;
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_t *pn = &op->fqi.fq_path;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw is_dir = (op->create_options & FILE_DIRECTORY_FILE) ? 1 : 0;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * If the object being created or opened is a directory
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * the Disposition parameter must be one of FILE_CREATE,
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * FILE_OPEN, or FILE_OPEN_IF
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->desired_access = smb_access_generic_to_file(op->desired_access);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh cmn_err(CE_NOTE, "smbsrv[%s\\%s]: TOO_MANY_OPENED_FILES",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* This must be NULL at this point */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Security descriptors for pipes are not implemented,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * so just setup a reasonable access mask.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross op->desired_access = (READ_CONTROL | SYNCHRONIZE |
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Limit the number of open pipe instances.
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh if ((rc = smb_threshold_enter(&sv->sv_opipe_ct)) != 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * No further processing for IPC, we need to either
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * raise an exception or return success here.
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States cur_node = op->fqi.fq_dnode ?
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States op->fqi.fq_dnode : sr->tid_tree->t_snode;
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States /*
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States * if no path or filename are specified the stream should be
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States * created on cur_node
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States */
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States if (!is_dir && !pn->pn_pname && !pn->pn_fname && pn->pn_sname) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States /*
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * Can't currently handle a stream on the tree root.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * If a stream is being opened return "not found", otherwise
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * return "access denied".
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States */
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States if (cur_node == sr->tid_tree->t_snode) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (op->create_disposition == FILE_OPEN) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return (NT_STATUS_OBJECT_NAME_NOT_FOUND);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States return (NT_STATUS_ACCESS_DENIED);
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States }
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States (void) snprintf(op->fqi.fq_last_comp,
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States sizeof (op->fqi.fq_last_comp),
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States "%s%s", cur_node->od_name, pn->pn_sname);
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_ref(op->fqi.fq_dnode);
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States } else {
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross rc = smb_pathname_reduce(sr, sr->user_cr, pn->pn_path,
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States sr->tid_tree->t_snode, cur_node, &op->fqi.fq_dnode,
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If the access mask has only DELETE set (ignore
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * FILE_READ_ATTRIBUTES), then assume that this
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * is a request to delete the link (if a link)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and do not follow links. Otherwise, follow
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the link to the target.
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh if ((op->desired_access & ~FILE_READ_ATTRIBUTES) == DELETE)
8622ec4569457733001d4982ef7f5b44427069beGordon Ross rc = smb_fsop_lookup_name(sr, zone_kcred(), lookup_flags,
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States sr->tid_tree->t_snode, op->fqi.fq_dnode, op->fqi.fq_last_comp,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc == 0) {
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States last_comp_found = B_TRUE;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Need the DOS attributes below, where we
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * check the search attributes (sattr).
8622ec4569457733001d4982ef7f5b44427069beGordon Ross rc = smb_node_getattr(sr, op->fqi.fq_fnode, zone_kcred(),
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States last_comp_found = B_FALSE;
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States op->fqi.fq_fnode = NULL;
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(op->fqi.fq_dnode);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * The uniq_fid is a CIFS-server-wide unique identifier for an ofile
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * which is used to uniquely identify open instances for the
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * VFS share reservation and POSIX locks.
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States if (last_comp_found) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States node = op->fqi.fq_fnode;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States dnode = op->fqi.fq_dnode;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (!smb_node_is_file(node) && !smb_node_is_dir(node) &&
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States !smb_node_is_symlink(node)) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(node);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(dnode);
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * Reject this request if either:
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * - the target IS a directory and the client requires that
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * it must NOT be (required by Lotus Notes)
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * - the target is NOT a directory and client requires that
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * it MUST be.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (smb_node_is_dir(node)) {
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego if (op->create_options & FILE_NON_DIRECTORY_FILE) {
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego if ((op->create_options & FILE_DIRECTORY_FILE) ||
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego (op->nt_flags & NT_CREATE_FLAG_OPEN_TARGET_DIR)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * No more open should be accepted when "Delete on close"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * flag is set.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Specified file already exists so the operation should fail.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Windows seems to check read-only access before file
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * sharing check.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Check to see if the file is currently readonly (irrespective
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * of whether this open will make it readonly).
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Files data only */
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk if (!smb_sattr_check(op->fqi.fq_fattr.sa_dosattr,
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk /* MS-FSA 2.1.5.1.2 */
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk if ((op->create_disposition == FILE_OVERWRITE_IF) ||
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* SMB1 specific? NT_STATUS_PRIVILEGE_NOT_HELD */
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk smb_fsop_eaccess(sr, sr->user_cr, node, &max_allowed);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * According to MS "dochelp" mail in Mar 2015, any handle
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * on which read or write access is granted implicitly
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * gets "read attributes", even if it was not requested.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * This avoids unexpected access failures later that
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * would happen if these were not granted.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if ((op->desired_access & FILE_DATA_ALL) != 0) {
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk * Oplock break is done prior to sharing checks as the break
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk * may cause other clients to close the file which would
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk * affect the sharing checks. This may block, so set the
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk * file opening count before oplock stuff.
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk * Check for sharing violations
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk status = smb_fsop_shrlock(sr->user_cr, node, uniq_fid,
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk * Go ahead with modifications as necessary.
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh /* Don't apply readonly bit until smb_ofile_close */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Truncate the file data here.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * We set alloc_size = op->dsize later,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * after we have an ofile. See:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * smb_set_open_attributes
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh new_attr.sa_mask = SMB_AT_DOSATTR | SMB_AT_SIZE;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh rc = smb_fsop_setattr(sr, sr->user_cr, node, &new_attr);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * If file is being replaced, remove existing streams
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States if (SMB_IS_STREAM(node) == 0) {
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States smb_fsop_unshrlock(sr->user_cr, node,
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States uniq_fid);
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_unlock(node);
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(node);
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(dnode);
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States }
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * FILE_OPEN or FILE_OPEN_IF.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Ignore any user-specified alloc_size for
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * existing files, to avoid truncation in
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * smb_set_open_attributes
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Last component was not found. */
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States dnode = op->fqi.fq_dnode;
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States is_stream = smb_is_stream_name(pn->pn_path);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (pn->pn_fname && smb_is_invalid_filename(pn->pn_fname)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * lock the parent dir node in case another create
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * request to the same parent directory comes in.
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh /* Don't apply readonly bit until smb_ofile_close */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (is_dir == 0) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * We set alloc_size = op->dsize later,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * after we have an ofile. See:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * smb_set_open_attributes
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh op->fqi.fq_last_comp, &new_attr, &op->fqi.fq_fnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != 0) {
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States node = op->fqi.fq_fnode;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh op->fqi.fq_last_comp, &new_attr, &op->fqi.fq_fnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != 0) {
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States node = op->fqi.fq_fnode;
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States created = B_TRUE;
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk smb_fsop_eaccess(sr, sr->user_cr, node, &max_allowed);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * We created created this object (we own it) so
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * grant read/write attributes on this handle,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * even if that was not requested. This avoids
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * unexpected access failures later that would
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * happen if these were not granted.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross of = smb_ofile_open(sr, node, op, SMB_FTYPE_DISK, uniq_fid,
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * We might have blocked in smb_ofile_open long enough so a
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * tree disconnect might have happened. In that case, we've
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * just added an ofile to a tree that's disconnecting, and
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * need to undo that to avoid interfering with tear-down of
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross * the tree connection.
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * This MUST be done after ofile creation, so that explicitly
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * set timestamps can be remembered on the ofile, and the
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * readonly flag will be stored "pending" on the node.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if ((rc = smb_set_open_attributes(sr, of)) != 0) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * We've already done access checks above,
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * and want this call to succeed even when
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * !(desired_access & FILE_READ_ATTRIBUTES),
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * so pass kcred here.
8622ec4569457733001d4982ef7f5b44427069beGordon Ross rc = smb_node_getattr(sr, node, zone_kcred(), of,
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * smb_fsop_unshrlock is a no-op if node is a directory
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * smb_fsop_unshrlock is done in smb_ofile_close
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States if (created)
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States smb_delete_new_object(sr);
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_unlock(node);
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(node);
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States if (created)
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_unlock(dnode);
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(dnode);
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States }
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States
8c10a8659ac31335ed870a1711c0182623f72fd6as * Propagate the write-through mode from the open params
8c10a8659ac31335ed870a1711c0182623f72fd6as * to the node: see the notes in the function header.
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * Set up the fileid and dosattr in open_param for response
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States op->fileid = op->fqi.fq_fattr.sa_vattr.va_nodeid;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Set up the file type in open_param for the response
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (smb_node_is_file(node)) {
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States op->dsize = op->fqi.fq_fattr.sa_vattr.va_size;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States } else {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States /* directory or symlink */
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(node);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * smb_open_oplock_break
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * If the node has an ofile opened with share access none,
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * (smb_node_share_check = FALSE) only break BATCH oplock.
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * If overwriting, break to SMB_OPLOCK_NONE, else
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * If opening for anything other than attribute access,
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * break oplock to LEVEL_II.
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintoshsmb_open_oplock_break(smb_request_t *sr, smb_node_t *node)
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * smb_open_attr_only
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * Determine if file is being opened for attribute access only.
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * This is used to determine whether it is necessary to break
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * existing oplocks on the file.
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh if (((op->desired_access & ~(FILE_READ_ATTRIBUTES |
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk FILE_WRITE_ATTRIBUTES | SYNCHRONIZE | READ_CONTROL)) == 0) &&
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh (op->create_disposition != FILE_SUPERSEDE) &&
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh (op->create_disposition != FILE_OVERWRITE)) {
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh if ((op->create_disposition == FILE_SUPERSEDE) ||
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh (op->create_disposition == FILE_OVERWRITE_IF) ||
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh (op->create_disposition == FILE_OVERWRITE)) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * smb_set_open_attributes
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * Last write time:
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * - If the last_write time specified in the open params is not 0 or -1,
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * use it as file's mtime. This will be considered an explicitly set
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * timestamps, not reset by subsequent writes.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * DOS attributes
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * - If we created_readonly, we now store the real DOS attributes
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * (including the readonly bit) so subsequent opens will see it.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Both are stored "pending" rather than in the file system.
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * Returns: errno
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Rosssmb_set_open_attributes(smb_request_t *sr, smb_ofile_t *of)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr.sa_dosattr = op->dattr | FILE_ATTRIBUTE_READONLY;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh if ((op->mtime.tv_sec != 0) && (op->mtime.tv_sec != UINT_MAX)) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Used to have code here to set mtime, ctime, atime
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * when the open op->create_disposition is any of:
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * FILE_SUPERSEDE, FILE_OVERWRITE_IF, FILE_OVERWRITE.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * We know that in those cases we will have set the
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * file size, in which case the file system will
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * update those times, so we don't have to.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * However, keep track of the fact that we modified
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * the file via this handle, so we can do the evil,
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * gratuitious mtime update on close that Windows
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * clients appear to expect.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross rc = smb_node_setattr(sr, node, of->f_cr, of, &attr);
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States * This function is used to delete a newly created object (file or
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States * directory) if an error occurs after creation of the object.
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United Statesstatic void
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United Statessmb_delete_new_object(smb_request_t *sr)
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States smb_fqi_t *fqi = &(op->fqi);
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States uint32_t flags = 0;
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States if (SMB_TREE_IS_CASEINSENSITIVE(sr))
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States flags |= SMB_IGNORE_CASE;
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States if (SMB_TREE_SUPPORTS_CATIA(sr))
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States flags |= SMB_CATIA;
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States if (op->create_options & FILE_DIRECTORY_FILE)
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States (void) smb_fsop_rmdir(sr, sr->user_cr, fqi->fq_dnode,
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States fqi->fq_last_comp, flags);
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States else
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States (void) smb_fsop_remove(sr, sr->user_cr, fqi->fq_dnode,
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States fqi->fq_last_comp, flags);