smb_common_open.c revision 6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2e
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
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 *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * or http://www.opensolaris.org/os/licensing.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
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 *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Use is subject to license terms.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#pragma ident "%Z%%M% %I% %E% SMI"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This module provides the common open functionality to the various
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * open and create SMB interface functions.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/smb_incl.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/smb_fsops.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/mlsvc.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/nterror.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/ntstatus.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/smbinfo.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <sys/fcntl.h>
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as#include <sys/nbmlock.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbvolatile uint32_t smb_fids = 0;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
7b59d02d2a384be9a08087b14defadd214b3c1ddjbstatic uint32_t smb_open_subr(smb_request_t *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbextern uint32_t smb_is_executable(char *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbstatic uint32_t smb_open_subr(smb_request_t *);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This macro is used to delete a newly created object
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * if any error happens after creation of object.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#define SMB_DEL_NEWOBJ(obj) \
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (created) { \
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (is_dir) \
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) smb_fsop_rmdir(sr, sr->user_cr, \
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw obj.dir_snode, obj.last_comp, 0); \
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw else \
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) smb_fsop_remove(sr, sr->user_cr, \
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw obj.dir_snode, obj.last_comp, 0); \
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_access_generic_to_file
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Search MSDN for IoCreateFile to see following mapping.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * GENERIC_READ STANDARD_RIGHTS_READ, FILE_READ_DATA,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * FILE_READ_ATTRIBUTES and FILE_READ_EA
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * GENERIC_WRITE STANDARD_RIGHTS_WRITE, FILE_WRITE_DATA,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * FILE_WRITE_ATTRIBUTES, FILE_WRITE_EA, and FILE_APPEND_DATA
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * GENERIC_EXECUTE STANDARD_RIGHTS_EXECUTE, SYNCHRONIZE, and FILE_EXECUTE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwuint32_t
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_access_generic_to_file(uint32_t desired_access)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint32_t access = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (desired_access & GENERIC_ALL)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (FILE_ALL_ACCESS & ~SYNCHRONIZE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (desired_access & GENERIC_EXECUTE) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw desired_access &= ~GENERIC_EXECUTE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw access |= (STANDARD_RIGHTS_EXECUTE |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SYNCHRONIZE | FILE_EXECUTE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (desired_access & GENERIC_WRITE) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw desired_access &= ~GENERIC_WRITE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw access |= (FILE_GENERIC_WRITE & ~SYNCHRONIZE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (desired_access & GENERIC_READ) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw desired_access &= ~GENERIC_READ;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw access |= FILE_GENERIC_READ;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (access | desired_access);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_omode_to_amask
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
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 */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwuint32_t
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_omode_to_amask(uint32_t desired_access)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (desired_access & SMB_DA_ACCESS_MASK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_DA_ACCESS_READ:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (FILE_GENERIC_READ);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_DA_ACCESS_WRITE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (FILE_GENERIC_WRITE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_DA_ACCESS_READ_WRITE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (FILE_GENERIC_READ | FILE_GENERIC_WRITE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_DA_ACCESS_EXECUTE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (FILE_GENERIC_EXECUTE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* invalid open mode */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return ((uint32_t)SMB_INVALID_AMASK);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_denymode_to_sharemode
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This function converts deny modes used by Open and Open AndX
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * commands to share access bits used by NT Create AndX command.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwuint32_t
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_denymode_to_sharemode(uint32_t desired_access, char *fname)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (desired_access & SMB_DA_SHARE_MASK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_DA_SHARE_COMPATIBILITY:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (smb_is_executable(fname))
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (FILE_SHARE_READ | FILE_SHARE_WRITE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((desired_access &
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_DA_ACCESS_MASK) == SMB_DA_ACCESS_READ)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (FILE_SHARE_READ);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw else
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (FILE_SHARE_NONE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_DA_SHARE_EXCLUSIVE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (FILE_SHARE_NONE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_DA_SHARE_DENY_WRITE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (FILE_SHARE_READ);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_DA_SHARE_DENY_READ:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (FILE_SHARE_WRITE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_DA_SHARE_DENY_NONE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (FILE_SHARE_READ | FILE_SHARE_WRITE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* invalid deny mode */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return ((uint32_t)SMB_INVALID_SHAREMODE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_ofun_to_crdisposition
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
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.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwuint32_t
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_ofun_to_crdisposition(uint16_t ofun)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw static int ofun_cr_map[3][2] =
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw { -1, FILE_CREATE },
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw { FILE_OPEN, FILE_OPEN_IF },
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw { FILE_OVERWRITE, FILE_OVERWRITE_IF }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw };
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int row = ofun & SMB_OFUN_OPEN_MASK;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int col = (ofun & SMB_OFUN_CREATE_MASK) >> 4;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (row == 3)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return ((uint32_t)SMB_INVALID_CRDISPOSITION);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (ofun_cr_map[row][col]);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
7b59d02d2a384be9a08087b14defadd214b3c1ddjb/*
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.
7b59d02d2a384be9a08087b14defadd214b3c1ddjb */
7b59d02d2a384be9a08087b14defadd214b3c1ddjbuint32_t
7b59d02d2a384be9a08087b14defadd214b3c1ddjbsmb_common_open(smb_request_t *sr)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb{
7b59d02d2a384be9a08087b14defadd214b3c1ddjb uint32_t status = NT_STATUS_SUCCESS;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb int count;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
7b59d02d2a384be9a08087b14defadd214b3c1ddjb for (count = 0; count <= 4; count++) {
7b59d02d2a384be9a08087b14defadd214b3c1ddjb if (count)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb delay(MSEC_TO_TICK(400));
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb status = smb_open_subr(sr);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (status != NT_STATUS_SHARING_VIOLATION)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb break;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb }
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (status == NT_STATUS_SHARING_VIOLATION) {
7b59d02d2a384be9a08087b14defadd214b3c1ddjb smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
7b59d02d2a384be9a08087b14defadd214b3c1ddjb ERRDOS, ERROR_SHARING_VIOLATION);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb }
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (status);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb}
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_open_subr
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
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 *
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 * basis.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
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 *
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.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
7b59d02d2a384be9a08087b14defadd214b3c1ddjbstatic uint32_t
7b59d02d2a384be9a08087b14defadd214b3c1ddjbsmb_open_subr(smb_request_t *sr)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int created = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct smb_node *node = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct smb_node *dnode = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct smb_node *cur_node;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct open_param *op = &sr->arg.open;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct smb_ofile *of;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_attr_t new_attr;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int pathlen;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int max_requested = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint32_t max_allowed;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw unsigned int granted_oplock;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint32_t status = NT_STATUS_SUCCESS;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int is_dir;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_error_t err;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb int is_stream = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int lookup_flags = SMB_FOLLOW_LINKS;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint32_t daccess;
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as uint32_t share_access = op->share_access;
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as uint32_t uniq_fid;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw is_dir = (op->create_options & FILE_DIRECTORY_FILE) ? 1 : 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (is_dir) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
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 */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((op->create_disposition != FILE_CREATE) &&
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (op->create_disposition != FILE_OPEN_IF) &&
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (op->create_disposition != FILE_OPEN)) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ERRDOS, ERROR_INVALID_ACCESS);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_INVALID_PARAMETER);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (op->desired_access & MAXIMUM_ALLOWED) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw max_requested = 1;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->desired_access &= ~MAXIMUM_ALLOWED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->desired_access = smb_access_generic_to_file(op->desired_access);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (sr->session->s_file_cnt >= SMB_SESSION_OFILE_MAX) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(sr->uid_user);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw cmn_err(CE_NOTE, "smbd[%s\\%s]: %s", sr->uid_user->u_domain,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw sr->uid_user->u_name,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw xlate_nt_status(NT_STATUS_TOO_MANY_OPENED_FILES));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_TOO_MANY_OPENED_FILES,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ERRDOS, ERROR_TOO_MANY_OPEN_FILES);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_TOO_MANY_OPENED_FILES);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* This must be NULL at this point */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw sr->fid_ofile = NULL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->devstate = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (sr->tid_tree->t_res_type & STYPE_MASK) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case STYPE_DISKTREE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case STYPE_IPC:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * No further processing for IPC, we need to either
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * raise an exception or return success here.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
7b59d02d2a384be9a08087b14defadd214b3c1ddjb if ((status = smb_rpc_open(sr)) != NT_STATUS_SUCCESS)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb smbsr_error(sr, status, 0, 0);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (status);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw default:
7b59d02d2a384be9a08087b14defadd214b3c1ddjb smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE,
7b59d02d2a384be9a08087b14defadd214b3c1ddjb ERRDOS, ERROR_BAD_DEV_TYPE);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_BAD_DEVICE_TYPE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((pathlen = strlen(op->fqi.path)) >= MAXPATHLEN) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, 0, ERRSRV, ERRfilespecs);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_NAME_TOO_LONG);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Some clients pass null file names; NT interprets this as "\".
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (pathlen == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->fqi.path = "\\";
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw pathlen = 1;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->fqi.srch_attr = op->fqi.srch_attr;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((status = smb_validate_object_name(op->fqi.path, is_dir)) != 0) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, status, ERRDOS, ERROR_INVALID_NAME);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (status);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw cur_node = op->fqi.dir_snode ?
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->fqi.dir_snode : sr->tid_tree->t_snode;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc = smb_pathname_reduce(sr, sr->user_cr, op->fqi.path,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw sr->tid_tree->t_snode, cur_node, &op->fqi.dir_snode,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->fqi.last_comp)) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_errno(sr, rc);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (sr->smb_error.status);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
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 */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw daccess = op->desired_access & ~FILE_READ_ATTRIBUTES;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (daccess == DELETE)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lookup_flags &= ~SMB_FOLLOW_LINKS;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smb_fsop_lookup_name(sr, kcred, lookup_flags,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw sr->tid_tree->t_snode, op->fqi.dir_snode, op->fqi.last_comp,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw &op->fqi.last_snode, &op->fqi.last_attr);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->fqi.last_comp_was_found = 1;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) strcpy(op->fqi.last_comp_od,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->fqi.last_snode->od_name);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else if (rc == ENOENT) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->fqi.last_comp_was_found = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->fqi.last_snode = NULL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(op->fqi.dir_snode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NULL_FQI_NODES(op->fqi);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_errno(sr, rc);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (sr->smb_error.status);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as /*
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
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * VFS share reservation mechanism (accessed via smb_fsop_shrlock()).
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as */
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as uniq_fid = SMB_UNIQ_FID();
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (op->fqi.last_comp_was_found) {
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas if ((op->fqi.last_attr.sa_vattr.va_type != VREG) &&
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas (op->fqi.last_attr.sa_vattr.va_type != VDIR) &&
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas (op->fqi.last_attr.sa_vattr.va_type != VLNK)) {
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas smb_node_release(op->fqi.last_snode);
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas smb_node_release(op->fqi.dir_snode);
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas SMB_NULL_FQI_NODES(op->fqi);
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas ERRnoaccess);
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas return (NT_STATUS_ACCESS_DENIED);
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas }
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw node = op->fqi.last_snode;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw dnode = op->fqi.dir_snode;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as /*
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * Enter critical region for share reservations.
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * (See comments above smb_fsop_shrlock().)
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as */
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rw_enter(&node->n_share_lock, RW_WRITER);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
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 */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((op->create_options & FILE_NON_DIRECTORY_FILE) &&
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (op->fqi.last_attr.sa_vattr.va_type == VDIR)) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rw_exit(&node->n_share_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NULL_FQI_NODES(op->fqi);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_FILE_IS_A_DIRECTORY,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ERRDOS, ERROR_ACCESS_DENIED);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_FILE_IS_A_DIRECTORY);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (op->fqi.last_attr.sa_vattr.va_type == VDIR) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((sr->smb_com == SMB_COM_OPEN_ANDX) ||
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (sr->smb_com == SMB_COM_OPEN)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Directories cannot be opened
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * with the above commands
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rw_exit(&node->n_share_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NULL_FQI_NODES(op->fqi);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_FILE_IS_A_DIRECTORY,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ERRDOS, ERROR_ACCESS_DENIED);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_FILE_IS_A_DIRECTORY);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else if (op->my_flags & MYF_MUST_BE_DIRECTORY) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rw_exit(&node->n_share_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NULL_FQI_NODES(op->fqi);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_NOT_A_DIRECTORY,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ERRDOS, ERROR_DIRECTORY);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_NOT_A_DIRECTORY);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * No more open should be accepted when "Delete on close"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * flag is set.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rw_exit(&node->n_share_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NULL_FQI_NODES(op->fqi);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_DELETE_PENDING,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ERRDOS, ERROR_ACCESS_DENIED);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_DELETE_PENDING);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Specified file already exists so the operation should fail.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (op->create_disposition == FILE_CREATE) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rw_exit(&node->n_share_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NULL_FQI_NODES(op->fqi);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_OBJECT_NAME_COLLISION,
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as ERRDOS, ERROR_ALREADY_EXISTS);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_OBJECT_NAME_COLLISION);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Windows seems to check read-only access before file
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * sharing check.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (NODE_IS_READONLY(node)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Files data only */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (node->attr.sa_vattr.va_type != VDIR) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (op->desired_access & (FILE_WRITE_DATA |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw FILE_APPEND_DATA)) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rw_exit(&node->n_share_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NULL_FQI_NODES(op->fqi);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as ERRDOS, ERRnoaccess);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_ACCESS_DENIED);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as /*
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * The following check removes the need to check share
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * reservations again when a truncate is done.
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as */
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as if ((op->create_disposition == FILE_SUPERSEDE) ||
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as (op->create_disposition == FILE_OVERWRITE_IF) ||
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as (op->create_disposition == FILE_OVERWRITE)) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as if (!(op->desired_access &
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as (FILE_WRITE_DATA | FILE_APPEND_DATA))) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rw_exit(&node->n_share_lock);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_node_release(node);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_node_release(dnode);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as SMB_NULL_FQI_NODES(op->fqi);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as ERRDOS, ERRnoaccess);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_ACCESS_DENIED);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as }
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as }
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as status = smb_fsop_shrlock(sr->user_cr, node, uniq_fid,
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as op->desired_access, share_access);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (status == NT_STATUS_SHARING_VIOLATION) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rw_exit(&node->n_share_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NULL_FQI_NODES(op->fqi);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (status);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw status = smb_fsop_access(sr, sr->user_cr, node,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->desired_access);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (status != NT_STATUS_SUCCESS) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rw_exit(&node->n_share_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NULL_FQI_NODES(op->fqi);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (status == NT_STATUS_PRIVILEGE_NOT_HELD) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, status,
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as ERRDOS, ERROR_PRIVILEGE_NOT_HELD);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (status);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as ERRDOS, ERROR_ACCESS_DENIED);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_ACCESS_DENIED);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Break the oplock before share checks. If another client
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * has the file open, this will force a flush or close,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * which may affect the outcome of any share checking.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (OPLOCKS_IN_FORCE(node)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw status = smb_break_oplock(sr, node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (status != NT_STATUS_SUCCESS) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rw_exit(&node->n_share_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NULL_FQI_NODES(op->fqi);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, status,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ERRDOS, ERROR_VC_DISCONNECTED);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (status);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (op->create_disposition) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case FILE_SUPERSEDE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case FILE_OVERWRITE_IF:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case FILE_OVERWRITE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (node->attr.sa_vattr.va_type == VDIR) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rw_exit(&node->n_share_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NULL_FQI_NODES(op->fqi);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as ERRDOS, ERROR_ACCESS_DENIED);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_ACCESS_DENIED);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (node->attr.sa_vattr.va_size != op->dsize) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw node->flags &= ~NODE_FLAGS_SET_SIZE;
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as bzero(&new_attr, sizeof (new_attr));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw new_attr.sa_vattr.va_size = op->dsize;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw new_attr.sa_mask = SMB_AT_SIZE;
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rc = smb_fsop_setattr(sr, sr->user_cr,
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as node, &new_attr, &op->fqi.last_attr);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as if (rc) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_fsop_unshrlock(sr->user_cr, node,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb uniq_fid);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rw_exit(&node->n_share_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NULL_FQI_NODES(op->fqi);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_errno(sr, rc);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (sr->smb_error.status);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as op->dsize = op->fqi.last_attr.sa_vattr.va_size;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If file is being replaced,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * we should remove existing streams
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (SMB_IS_STREAM(node) == 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) smb_fsop_remove_streams(sr, sr->user_cr,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->action_taken = SMB_OACT_TRUNCATED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw default:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * FILE_OPEN or FILE_OPEN_IF.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->action_taken = SMB_OACT_OPENED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Last component was not found. */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw dnode = op->fqi.dir_snode;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
7b59d02d2a384be9a08087b14defadd214b3c1ddjb if (is_dir == 0)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb is_stream = smb_stream_parse_name(op->fqi.path,
7b59d02d2a384be9a08087b14defadd214b3c1ddjb NULL, NULL);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((op->create_disposition == FILE_OPEN) ||
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (op->create_disposition == FILE_OVERWRITE)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NULL_FQI_NODES(op->fqi);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb ERRDOS, ERROR_FILE_NOT_FOUND);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_OBJECT_NAME_NOT_FOUND);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * lock the parent dir node in case another create
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * request to the same parent directory comes in.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_rwx_rwenter(&dnode->n_lock, RW_WRITER);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw bzero(&new_attr, sizeof (new_attr));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (is_dir == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw new_attr.sa_vattr.va_type = VREG;
7b59d02d2a384be9a08087b14defadd214b3c1ddjb new_attr.sa_vattr.va_mode = is_stream ? S_IRUSR :
7b59d02d2a384be9a08087b14defadd214b3c1ddjb S_IRUSR | S_IRGRP | S_IROTH |
7b59d02d2a384be9a08087b14defadd214b3c1ddjb S_IWUSR | S_IWGRP | S_IWOTH;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw new_attr.sa_mask = SMB_AT_TYPE | SMB_AT_MODE;
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas if (op->dsize) {
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas new_attr.sa_vattr.va_size = op->dsize;
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas new_attr.sa_mask |= SMB_AT_SIZE;
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as }
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smb_fsop_create(sr, sr->user_cr, dnode,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->fqi.last_comp, &new_attr,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw &op->fqi.last_snode, &op->fqi.last_attr);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_rwx_rwexit(&dnode->n_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NULL_FQI_NODES(op->fqi);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_errno(sr, rc);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (sr->smb_error.status);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas /*
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas * A problem with setting the readonly bit at
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas * create time is that this bit will prevent
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas * writes to the file from the same fid (which
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas * should be allowed).
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas *
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas * The solution is to set the bit at close time.
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas * Meanwhile, to prevent racing opens from being
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas * able to write to the file, set share reservations
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas * to prevent write and delete access.
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas */
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas if (op->dattr & SMB_FA_READONLY)
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as share_access &= ~(FILE_SHARE_WRITE |
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as FILE_SHARE_DELETE);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as node = op->fqi.last_snode;
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rw_enter(&node->n_share_lock, RW_WRITER);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb status = smb_fsop_shrlock(sr->user_cr, node, uniq_fid,
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb op->desired_access, share_access);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as if (status == NT_STATUS_SHARING_VIOLATION) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rw_exit(&node->n_share_lock);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_node_release(node);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_node_release(dnode);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as SMB_NULL_FQI_NODES(op->fqi);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as return (status);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as }
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas op->fqi.last_attr = node->attr;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->dattr |= SMB_FA_DIRECTORY;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw new_attr.sa_vattr.va_type = VDIR;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw new_attr.sa_vattr.va_mode = 0777;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw new_attr.sa_mask = SMB_AT_TYPE | SMB_AT_MODE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smb_fsop_mkdir(sr, sr->user_cr, dnode,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->fqi.last_comp, &new_attr,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw &op->fqi.last_snode, &op->fqi.last_attr);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_rwx_rwexit(&dnode->n_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NULL_FQI_NODES(op->fqi);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_errno(sr, rc);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (sr->smb_error.status);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as node = op->fqi.last_snode;
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rw_enter(&node->n_share_lock, RW_WRITER);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw created = 1;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->action_taken = SMB_OACT_CREATED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (max_requested) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_fsop_eaccess(sr, sr->user_cr, node, &max_allowed);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->desired_access |= max_allowed;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
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.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw of = smb_ofile_open(sr->tid_tree, node, sr->smb_pid, op->desired_access,
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as op->create_options, share_access, SMB_FTYPE_DISK, NULL, 0,
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as uniq_fid, &err);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (of == NULL) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_DEL_NEWOBJ(op->fqi);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rw_exit(&node->n_share_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (created)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_rwx_rwexit(&dnode->n_lock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NULL_FQI_NODES(op->fqi);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, err.status, err.errcls, err.errcode);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (err.status);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Propagate the write-through mode from the open params
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to the node: see the notes in the function header.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * IR #102318 Mirroring may force synchronous
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * writes regardless of what we specify here.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (sr->sr_cfg->skc_sync_enable ||
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb (op->create_options & FILE_WRITE_THROUGH))
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw node->flags |= NODE_FLAGS_WRITE_THROUGH;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->fileid = op->fqi.last_attr.sa_vattr.va_nodeid;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (op->fqi.last_attr.sa_vattr.va_type == VDIR) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* We don't oplock directories */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->my_flags &= ~MYF_OPLOCK_MASK;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->dsize = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw status = smb_acquire_oplock(sr, of, op->my_flags,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw &granted_oplock);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->my_flags &= ~MYF_OPLOCK_MASK;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (status != NT_STATUS_SUCCESS) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rw_exit(&node->n_share_lock);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as /*
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * smb_fsop_unshrlock() and smb_fsop_close()
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * are called from smb_ofile_close()
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) smb_ofile_close(of, 0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_ofile_release(of);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (created)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_rwx_rwexit(&dnode->n_lock);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NULL_FQI_NODES(op->fqi);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smbsr_error(sr, status,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ERRDOS, ERROR_SHARING_VIOLATION);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (status);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->my_flags |= granted_oplock;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->dsize = op->fqi.last_attr.sa_vattr.va_size;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (created) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw node->flags |= NODE_FLAGS_CREATED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Clients may set the DOS readonly bit on create but they
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * expect subsequent write operations on the open fid to
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas * succeed. Thus the DOS readonly bit is not set until
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas * the file is closed. The NODE_CREATED_READONLY flag
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * will act as the indicator to set the DOS readonly bit on
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * close.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (op->dattr & SMB_FA_READONLY) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw node->flags |= NODE_CREATED_READONLY;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->dattr &= ~SMB_FA_READONLY;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_set_dosattr(node, op->dattr | SMB_FA_ARCHIVE);
55bf511df53aad0fdb7eb3fa349f0308cc05234cas if (op->utime.tv_sec == 0 || op->utime.tv_sec == UINT_MAX)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) microtime(&op->utime);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_set_time(node, NULL, &op->utime, 0, 0, SMB_AT_MTIME);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) smb_sync_fsattr(sr, sr->user_cr, node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If we reach here, it means that file already exists
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and if create disposition is one of: FILE_SUPERSEDE,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * FILE_OVERWRITE_IF, or FILE_OVERWRITE it
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * means that client wants to overwrite (or truncate)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the existing file. So we should overwrite the dos
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * attributes of destination file with the dos attributes
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * of source file.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (op->create_disposition) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case FILE_SUPERSEDE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case FILE_OVERWRITE_IF:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case FILE_OVERWRITE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_set_dosattr(node,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->dattr | SMB_FA_ARCHIVE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) smb_sync_fsattr(sr, sr->user_cr, node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->utime = *smb_node_get_crtime(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->dattr = smb_node_get_dosattr(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Set up the file type in open_param for the response
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->ftype = SMB_FTYPE_DISK;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw sr->smb_fid = of->f_fid;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw sr->fid_ofile = of;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as rw_exit(&node->n_share_lock);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as if (created)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_rwx_rwexit(&dnode->n_lock);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NULL_FQI_NODES(op->fqi);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NT_STATUS_SUCCESS);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_validate_object_name
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
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 *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Returns NT status codes.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwuint32_t
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_validate_object_name(char *path, unsigned int ftype)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *filename;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (path == 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (ftype)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (smb_validate_dirname(path));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Basename with backslashes.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((filename = strrchr(path, '\\')) != 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ++filename;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw else
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw filename = path;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (strlen(filename) == 5 &&
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mts_isdigit(filename[3]) &&
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw filename[4] == ':') {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NT_STATUS_OBJECT_NAME_INVALID);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_preset_delete_on_close
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
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 *
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.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwvoid
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_preset_delete_on_close(smb_ofile_t *file)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_enter(&file->f_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw file->f_flags |= SMB_OFLAGS_SET_DELETE_ON_CLOSE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw mutex_exit(&file->f_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}