smb_common_open.c revision c8ec8eea9849cac239663c46be8a7f5d2ba7ca00
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
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Use is subject to license terms.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego#pragma ident "@(#)smb_common_open.c 1.13 08/08/08 SMI"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This module provides the common open functionality to the various
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * open and create SMB interface functions.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This macro is used to delete a newly created object
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * if any error happens after creation of object.
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 /* invalid open mode */
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 /* invalid deny mode */
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.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This function will return NT status codes but it also raises errors,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * in which case it won't return to the caller. Be careful how you
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * handle things in here.
8c10a8659ac31335ed870a1711c0182623f72fd6as * The following rules apply when processing a file open request:
8c10a8659ac31335ed870a1711c0182623f72fd6as * - Oplocks must be broken prior to share checking to prevent open
8c10a8659ac31335ed870a1711c0182623f72fd6as * starvation due to batch oplocks. Checking share reservations first
8c10a8659ac31335ed870a1711c0182623f72fd6as * could potentially result in unnecessary open failures due to
8c10a8659ac31335ed870a1711c0182623f72fd6as * open/close batching on the client.
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.
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).
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw is_dir = (op->create_options & FILE_DIRECTORY_FILE) ? 1 : 0;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * The object being created or opened is a directory,
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * and the Disposition parameter must be one of
7b59d02d2a384be9a08087b14defadd214b3c1ddjb * FILE_CREATE, FILE_OPEN, or FILE_OPEN_IF
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->desired_access = smb_access_generic_to_file(op->desired_access);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw cmn_err(CE_NOTE, "smbd[%s\\%s]: %s", sr->uid_user->u_domain,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* This must be NULL at this point */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * No further processing for IPC, we need to either
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * raise an exception or return success here.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Some clients pass null file names; NT interprets this as "\".
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (pathlen == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((status = smb_validate_object_name(op->fqi.path, is_dir)) != 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc = smb_pathname_reduce(sr, sr->user_cr, op->fqi.path,
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.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw sr->tid_tree->t_snode, op->fqi.dir_snode, op->fqi.last_comp,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc == 0) {
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.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Reject this request if the target is a directory
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and the client has specified that it must not be
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * a directory (required by Lotus Notes).
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Directories cannot be opened
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * with the above commands
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 */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If file is being replaced,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * we should remove existing streams
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * FILE_OPEN or FILE_OPEN_IF.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Last component was not found. */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * lock the parent dir node in case another create
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * request to the same parent directory comes in.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * A file created with the readonly bit should not
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * stop the creator writing to the file until it is
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * closed. Although the readonly bit will not be set
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * on the file until it is closed, it will be accounted
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * for on other fids and on queries based on the node
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (is_dir == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != 0) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * If we reach here, it means that the file already exists.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * If create disposition is one of FILE_SUPERSEDE,
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * FILE_OVERWRITE_IF, or FILE_OVERWRITE, the client wants to
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * overwrite or truncate the existing file and we have to
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * replace the destination file's DOS attributes with those
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * from the source file.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_ofile_open() will copy node to of->node. Hence
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the hold on node (i.e. op->fqi.last_snode) will be "transferred"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to the "of" structure.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego of = smb_ofile_open(sr->tid_tree, node, sr->smb_pid, op, SMB_FTYPE_DISK,
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * smb_fsop_unshrlock() and smb_fsop_close()
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * are called from smb_ofile_close()
8c10a8659ac31335ed870a1711c0182623f72fd6as } else { /* VDIR or VLNK */
8c10a8659ac31335ed870a1711c0182623f72fd6as * Propagate the write-through mode from the open params
8c10a8659ac31335ed870a1711c0182623f72fd6as * to the node: see the notes in the function header.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Set up the file type in open_param for the response
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_validate_object_name
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Very basic file name validation. Directory validation is handed off
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to smb_validate_dirname. For filenames, we check for names of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * form "AAAn:". Names that contain three characters, a single digit
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and a colon (:) are reserved as DOS device names, i.e. "COM1:".
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns NT status codes.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Basename with backslashes.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_preset_delete_on_close
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Set the DeleteOnClose flag on the smb file. When the file is closed,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the flag will be transferred to the smb node, which will commit the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * delete operation and inhibit subsequent open requests.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * When DeleteOnClose is set on an smb_node, the common open code will
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * reject subsequent open requests for the file. Observation of Windows
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * 2000 indicates that subsequent opens should be allowed (assuming
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * there would be no sharing violation) until the file is closed using
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the fid on which the DeleteOnClose was requested.