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 */
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
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 */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This module provides the common open functionality to the various
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * open and create SMB interface functions.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#include <sys/types.h>
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#include <sys/cmn_err.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <sys/fcntl.h>
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as#include <sys/nbmlock.h>
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#include <smbsrv/string.h>
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#include <smbsrv/smb_kproto.h>
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#include <smbsrv/smb_fsops.h>
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#include <smbsrv/smbinfo.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Rossstatic volatile uint32_t smb_fids = 0;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#define SMB_UNIQ_FID() atomic_inc_32_nv(&smb_fids)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
7b59d02d2a384be9a08087b14defadd214b3c1ddjbstatic uint32_t smb_open_subr(smb_request_t *);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbextern uint32_t smb_is_executable(char *);
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
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 */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Rossstatic uint32_t
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_access_generic_to_file(uint32_t desired_access)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross 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
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego default:
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego return (FILE_GENERIC_ALL);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego }
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);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego return (FILE_SHARE_ALL);
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:
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego default:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (FILE_SHARE_READ | FILE_SHARE_WRITE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
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)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego return (FILE_MAXIMUM_DISPOSITION + 1);
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{
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright smb_arg_open_t *parg;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown uint32_t status = NT_STATUS_SUCCESS;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown int count;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown parg = kmem_alloc(sizeof (*parg), KM_SLEEP);
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown bcopy(&sr->arg.open, parg, sizeof (*parg));
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
7b59d02d2a384be9a08087b14defadd214b3c1ddjb for (count = 0; count <= 4; count++) {
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown if (count != 0)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb delay(MSEC_TO_TICK(400));
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb status = smb_open_subr(sr);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb if (status != NT_STATUS_SHARING_VIOLATION)
7b59d02d2a384be9a08087b14defadd214b3c1ddjb break;
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown bcopy(parg, &sr->arg.open, sizeof (*parg));
7b59d02d2a384be9a08087b14defadd214b3c1ddjb }
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (status == NT_STATUS_NO_SUCH_FILE)
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown kmem_free(parg, sizeof (*parg));
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 *
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * This function returns NT status codes.
8c10a8659ac31335ed870a1711c0182623f72fd6as *
8c10a8659ac31335ed870a1711c0182623f72fd6as * The following rules apply when processing a file open request:
8c10a8659ac31335ed870a1711c0182623f72fd6as *
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
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * checks.
8c10a8659ac31335ed870a1711c0182623f72fd6as *
8c10a8659ac31335ed870a1711c0182623f72fd6as * - Share checks must take place prior to access checks for correct
8c10a8659ac31335ed870a1711c0182623f72fd6as * Windows semantics and to prevent unnecessary NFS delegation recalls.
8c10a8659ac31335ed870a1711c0182623f72fd6as *
8c10a8659ac31335ed870a1711c0182623f72fd6as * - Oplocks must be acquired after open to ensure the correct
8c10a8659ac31335ed870a1711c0182623f72fd6as * synchronization with NFS delegation and FEM installation.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego *
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * DOS readonly bit rules
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego *
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 *
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 *
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 *
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 *
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego *
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * DOS attribute rules
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego *
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 *
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 *
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * 1. Creating a new file
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * - The request attributes + FILE_ATTRIBUTE_ARCHIVE are applied to the file.
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego *
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 *
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 *
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * 4. Opening an existing file or directory
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego * The request attributes are ignored.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
7b59d02d2a384be9a08087b14defadd214b3c1ddjbstatic uint32_t
7b59d02d2a384be9a08087b14defadd214b3c1ddjbsmb_open_subr(smb_request_t *sr)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
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;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_t *node = NULL;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_t *dnode = NULL;
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_t *cur_node = NULL;
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright smb_arg_open_t *op = &sr->sr_open;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego int rc;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_ofile_t *of;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_attr_t new_attr;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego int max_requested = 0;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint32_t max_allowed;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint32_t status = NT_STATUS_SUCCESS;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego int is_dir;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_error_t err;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego boolean_t is_stream = B_FALSE;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego int lookup_flags = SMB_FOLLOW_LINKS;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint32_t uniq_fid;
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_t *pn = &op->fqi.fq_path;
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh smb_server_t *sv = sr->sr_server;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw is_dir = (op->create_options & FILE_DIRECTORY_FILE) ? 1 : 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh /*
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
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (is_dir) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((op->create_disposition != FILE_CREATE) &&
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (op->create_disposition != FILE_OPEN_IF) &&
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (op->create_disposition != FILE_OPEN)) {
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);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh cmn_err(CE_NOTE, "smbsrv[%s\\%s]: TOO_MANY_OPENED_FILES",
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright sr->uid_user->u_domain, sr->uid_user->u_name);
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:
f96bd5c800e73e351b0b6e4bd7f00b578dad29bbAlan Wright case STYPE_PRINTQ:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case STYPE_IPC:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Security descriptors for pipes are not implemented,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * so just setup a reasonable access mask.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross op->desired_access = (READ_CONTROL | SYNCHRONIZE |
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross FILE_READ_DATA | FILE_READ_ATTRIBUTES |
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross FILE_WRITE_DATA | FILE_APPEND_DATA);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Limit the number of open pipe instances.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh if ((rc = smb_threshold_enter(&sv->sv_opipe_ct)) != 0) {
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh status = RPC_NT_SERVER_TOO_BUSY;
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh return (status);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh }
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * No further processing for IPC, we need to either
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * raise an exception or return success here.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross uniq_fid = SMB_UNIQ_FID();
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross status = smb_opipe_open(sr, uniq_fid);
856399cf160942495309c59ac7a9541834573cd3Gordon Ross smb_threshold_exit(&sv->sv_opipe_ct);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (status);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw default:
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_BAD_DEVICE_TYPE);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier smb_pathname_init(sr, pn, pn->pn_path);
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier if (!smb_pathname_validate(sr, pn))
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier return (sr->smb_error.status);
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier
b24e356b384ccc80805e7150979de2373d44347cPeer Dampmann if (strlen(pn->pn_path) >= SMB_MAXPATHLEN) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (NT_STATUS_OBJECT_PATH_INVALID);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier if (is_dir) {
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier if (!smb_validate_dirname(sr, pn))
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier return (sr->smb_error.status);
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier } else {
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier if (!smb_validate_object_name(sr, pn))
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier return (sr->smb_error.status);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
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;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
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
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown op->fqi.fq_dnode = cur_node->n_dnode;
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,
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross op->fqi.fq_last_comp);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross if (rc != 0) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (smb_errno2status(rc));
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States }
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 */
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh if ((op->desired_access & ~FILE_READ_ATTRIBUTES) == DELETE)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lookup_flags &= ~SMB_FOLLOW_LINKS;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
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,
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh &op->fqi.fq_fnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc == 0) {
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States last_comp_found = B_TRUE;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross /*
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Need the DOS attributes below, where we
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * check the search attributes (sattr).
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross op->fqi.fq_fattr.sa_mask = SMB_AT_DOSATTR;
8622ec4569457733001d4982ef7f5b44427069beGordon Ross rc = smb_node_getattr(sr, op->fqi.fq_fnode, zone_kcred(),
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross NULL, &op->fqi.fq_fattr);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh if (rc != 0) {
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_node_release(op->fqi.fq_fnode);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_node_release(op->fqi.fq_dnode);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (NT_STATUS_INTERNAL_ERROR);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else if (rc == ENOENT) {
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;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(op->fqi.fq_dnode);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (smb_errno2status(rc));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
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
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * VFS share reservation and POSIX locks.
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as */
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as uniq_fid = SMB_UNIQ_FID();
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States if (last_comp_found) {
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas
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;
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas
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);
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas return (NT_STATUS_ACCESS_DENIED);
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas }
6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2eas
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
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.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (smb_node_is_dir(node)) {
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego if (op->create_options & FILE_NON_DIRECTORY_FILE) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_FILE_IS_A_DIRECTORY);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego } else {
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego if ((op->create_options & FILE_DIRECTORY_FILE) ||
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego (op->nt_flags & NT_CREATE_FLAG_OPEN_TARGET_DIR)) {
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego smb_node_release(node);
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego smb_node_release(dnode);
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego return (NT_STATUS_NOT_A_DIRECTORY);
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego }
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) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
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) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_OBJECT_NAME_COLLISION);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Windows seems to check read-only access before file
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * sharing check.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego *
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * Check to see if the file is currently readonly (irrespective
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * of whether this open will make it readonly).
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (SMB_PATHFILE_IS_READONLY(sr, node)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Files data only */
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh if (!smb_node_is_dir(node)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (op->desired_access & (FILE_WRITE_DATA |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw FILE_APPEND_DATA)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_ACCESS_DENIED);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as if ((op->create_disposition == FILE_SUPERSEDE) ||
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as (op->create_disposition == FILE_OVERWRITE_IF) ||
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as (op->create_disposition == FILE_OVERWRITE)) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk if (!smb_sattr_check(op->fqi.fq_fattr.sa_dosattr,
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk op->dattr)) {
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_node_release(node);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_node_release(dnode);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_ACCESS_DENIED);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as }
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk if (smb_node_is_dir(node)) {
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk smb_node_release(node);
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk smb_node_release(dnode);
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk return (NT_STATUS_ACCESS_DENIED);
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk /* MS-FSA 2.1.5.1.2 */
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk if (op->create_disposition == FILE_SUPERSEDE)
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk op->desired_access |= DELETE;
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk if ((op->create_disposition == FILE_OVERWRITE_IF) ||
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk (op->create_disposition == FILE_OVERWRITE))
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk op->desired_access |= FILE_WRITE_DATA;
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw status = smb_fsop_access(sr, sr->user_cr, node,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->desired_access);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (status != NT_STATUS_SUCCESS) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /* SMB1 specific? NT_STATUS_PRIVILEGE_NOT_HELD */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (status == NT_STATUS_PRIVILEGE_NOT_HELD) {
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (status);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_ACCESS_DENIED);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk if (max_requested) {
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk smb_fsop_eaccess(sr, sr->user_cr, node, &max_allowed);
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk op->desired_access |= max_allowed;
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
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 */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if ((op->desired_access & FILE_DATA_ALL) != 0) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross op->desired_access |= (READ_CONTROL |
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross FILE_READ_ATTRIBUTES);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk /*
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 */
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk smb_node_inc_opening_count(node);
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk smb_open_oplock_break(sr, node);
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk smb_node_wrlock(node);
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk /*
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk * Check for sharing violations
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk */
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk status = smb_fsop_shrlock(sr->user_cr, node, uniq_fid,
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk op->desired_access, op->share_access);
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk if (status == NT_STATUS_SHARING_VIOLATION) {
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk smb_node_unlock(node);
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk smb_node_dec_opening_count(node);
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk smb_node_release(node);
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk smb_node_release(dnode);
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk return (status);
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk }
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk /*
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk * Go ahead with modifications as necessary.
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (op->create_disposition) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case FILE_SUPERSEDE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case FILE_OVERWRITE_IF:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case FILE_OVERWRITE:
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego op->dattr |= FILE_ATTRIBUTE_ARCHIVE;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh /* Don't apply readonly bit until smb_ofile_close */
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego if (op->dattr & FILE_ATTRIBUTE_READONLY) {
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego op->created_readonly = B_TRUE;
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego op->dattr &= ~FILE_ATTRIBUTE_READONLY;
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego }
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
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
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh bzero(&new_attr, sizeof (new_attr));
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh new_attr.sa_dosattr = op->dattr;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross new_attr.sa_vattr.va_size = 0;
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 if (rc != 0) {
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_node_unlock(node);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh smb_node_dec_opening_count(node);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_node_release(node);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_node_release(dnode);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (smb_errno2status(rc));
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh }
2c1b14e51525da2c09064641416fc4aed457c72fjose borrego
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * If file is being replaced, remove existing streams
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States if (SMB_IS_STREAM(node) == 0) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = smb_fsop_remove_streams(sr,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross sr->user_cr, node);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (status != 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);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh smb_node_dec_opening_count(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);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (status);
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States }
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->action_taken = SMB_OACT_TRUNCATED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw default:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * FILE_OPEN or FILE_OPEN_IF.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Ignore any user-specified alloc_size for
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * existing files, to avoid truncation in
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * smb_set_open_attributes
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross op->dsize = 0L;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->action_taken = SMB_OACT_OPENED;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* Last component was not found. */
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States dnode = op->fqi.fq_dnode;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
7b59d02d2a384be9a08087b14defadd214b3c1ddjb if (is_dir == 0)
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States is_stream = smb_is_stream_name(pn->pn_path);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((op->create_disposition == FILE_OPEN) ||
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (op->create_disposition == FILE_OVERWRITE)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
7b59d02d2a384be9a08087b14defadd214b3c1ddjb return (NT_STATUS_OBJECT_NAME_NOT_FOUND);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (pn->pn_fname && smb_is_invalid_filename(pn->pn_fname)) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_release(dnode);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego return (NT_STATUS_OBJECT_NAME_INVALID);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego }
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * lock the parent dir node in case another create
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * request to the same parent directory comes in.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_wrlock(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh /* Don't apply readonly bit until smb_ofile_close */
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh if (op->dattr & FILE_ATTRIBUTE_READONLY) {
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh op->dattr &= ~FILE_ATTRIBUTE_READONLY;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh op->created_readonly = B_TRUE;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh bzero(&new_attr, sizeof (new_attr));
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if ((op->crtime.tv_sec != 0) &&
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego (op->crtime.tv_sec != UINT_MAX)) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego new_attr.sa_mask |= SMB_AT_CRTIME;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego new_attr.sa_crtime = op->crtime;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (is_dir == 0) {
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh op->dattr |= FILE_ATTRIBUTE_ARCHIVE;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh new_attr.sa_dosattr = op->dattr;
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;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh new_attr.sa_mask |=
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh SMB_AT_DOSATTR | SMB_AT_TYPE | SMB_AT_MODE;
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * We set alloc_size = op->dsize later,
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * after we have an ofile. See:
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * smb_set_open_attributes
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smb_fsop_create(sr, sr->user_cr, dnode,
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh op->fqi.fq_last_comp, &new_attr, &op->fqi.fq_fnode);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != 0) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_unlock(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (smb_errno2status(rc));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States node = op->fqi.fq_fnode;
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh smb_node_inc_opening_count(node);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_wrlock(node);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb status = smb_fsop_shrlock(sr->user_cr, node, uniq_fid,
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego op->desired_access, op->share_access);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as if (status == NT_STATUS_SHARING_VIOLATION) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_unlock(node);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh smb_node_dec_opening_count(node);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_delete_new_object(sr);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_node_release(node);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_unlock(dnode);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_node_release(dnode);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as return (status);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
3db3f65c6274eb042354801a308c8e9bc4994553amw op->dattr |= FILE_ATTRIBUTE_DIRECTORY;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh new_attr.sa_dosattr = op->dattr;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw new_attr.sa_vattr.va_type = VDIR;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw new_attr.sa_vattr.va_mode = 0777;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh new_attr.sa_mask |=
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh SMB_AT_DOSATTR | SMB_AT_TYPE | SMB_AT_MODE;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smb_fsop_mkdir(sr, sr->user_cr, dnode,
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh op->fqi.fq_last_comp, &new_attr, &op->fqi.fq_fnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != 0) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_unlock(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross return (smb_errno2status(rc));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States node = op->fqi.fq_fnode;
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh smb_node_inc_opening_count(node);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_wrlock(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States created = B_TRUE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw op->action_taken = SMB_OACT_CREATED;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk if (max_requested) {
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk smb_fsop_eaccess(sr, sr->user_cr, node, &max_allowed);
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk op->desired_access |= max_allowed;
fb699f1e35c673b043b5de07040056cd5cb0b50eAlek Pinchuk }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
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.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross op->desired_access |= (READ_CONTROL |
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES);
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego }
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh status = NT_STATUS_SUCCESS;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross of = smb_ofile_open(sr, node, op, SMB_FTYPE_DISK, uniq_fid,
3b13a1ef7511135ec0c75b5f94de8075454efd79Thomas Keiser &err);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (of == NULL) {
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh status = err.status;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh }
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross /*
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.
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross */
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross if (status == NT_STATUS_SUCCESS &&
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross !smb_tree_is_connected(sr->tid_tree)) {
68b2bbf26c7040fea4281dcb58b81e7627e46f34Gordon Ross status = NT_STATUS_INVALID_PARAMETER;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh }
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh /*
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.
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh */
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh if (status == NT_STATUS_SUCCESS) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if ((rc = smb_set_open_attributes(sr, of)) != 0) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross status = smb_errno2status(rc);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh }
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh }
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh if (status == NT_STATUS_SUCCESS) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross /*
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.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross op->fqi.fq_fattr.sa_mask = SMB_AT_ALL;
8622ec4569457733001d4982ef7f5b44427069beGordon Ross rc = smb_node_getattr(sr, node, zone_kcred(), of,
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross &op->fqi.fq_fattr);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (rc != 0) {
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh status = NT_STATUS_INTERNAL_ERROR;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh /*
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 */
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh if (status != NT_STATUS_SUCCESS) {
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh if (of == NULL) {
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh } else {
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_ofile_close(of, 0);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_ofile_release(of);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh }
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);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh smb_node_dec_opening_count(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);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh return (status);
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States }
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States
8c10a8659ac31335ed870a1711c0182623f72fd6as /*
8c10a8659ac31335ed870a1711c0182623f72fd6as * Propagate the write-through mode from the open params
8c10a8659ac31335ed870a1711c0182623f72fd6as * to the node: see the notes in the function header.
8c10a8659ac31335ed870a1711c0182623f72fd6as */
8c10a8659ac31335ed870a1711c0182623f72fd6as if (sr->sr_cfg->skc_sync_enable ||
8c10a8659ac31335ed870a1711c0182623f72fd6as (op->create_options & FILE_WRITE_THROUGH))
8c10a8659ac31335ed870a1711c0182623f72fd6as node->flags |= NODE_FLAGS_WRITE_THROUGH;
8c10a8659ac31335ed870a1711c0182623f72fd6as
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh /*
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * Set up the fileid and dosattr in open_param for response
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh */
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States op->fileid = op->fqi.fq_fattr.sa_vattr.va_nodeid;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh op->dattr = op->fqi.fq_fattr.sa_dosattr;
8c10a8659ac31335ed870a1711c0182623f72fd6as
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
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (smb_node_is_file(node)) {
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh smb_oplock_acquire(sr, node, of);
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 */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego op->op_oplock_level = SMB_OPLOCK_NONE;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego op->dsize = 0;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego }
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh smb_node_dec_opening_count(node);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh smb_node_unlock(node);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh if (created)
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh smb_node_unlock(dnode);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_release(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NT_STATUS_SUCCESS);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh/*
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * smb_open_oplock_break
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh *
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 * Otherwise:
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 mcintosh */
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintoshstatic void
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintoshsmb_open_oplock_break(smb_request_t *sr, smb_node_t *node)
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh{
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh smb_arg_open_t *op = &sr->sr_open;
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh uint32_t flags = 0;
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh if (!smb_node_share_check(node))
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh flags |= SMB_OPLOCK_BREAK_BATCH;
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh if (smb_open_overwrite(op)) {
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh flags |= SMB_OPLOCK_BREAK_TO_NONE;
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh (void) smb_oplock_break(sr, node, flags);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh } else if (!smb_open_attr_only(op)) {
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh flags |= SMB_OPLOCK_BREAK_TO_LEVEL_II;
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh (void) smb_oplock_break(sr, node, flags);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh }
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh}
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh/*
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * smb_open_attr_only
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh *
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 */
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintoshstatic boolean_t
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintoshsmb_open_attr_only(smb_arg_open_t *op)
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh{
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 return (B_TRUE);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh }
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh return (B_FALSE);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh}
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintoshstatic boolean_t
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintoshsmb_open_overwrite(smb_arg_open_t *op)
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh{
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh if ((op->create_disposition == FILE_SUPERSEDE) ||
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh (op->create_disposition == FILE_OVERWRITE_IF) ||
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh (op->create_disposition == FILE_OVERWRITE)) {
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh return (B_TRUE);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh }
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh return (B_FALSE);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh}
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh/*
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * smb_set_open_attributes
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh *
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.
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh *
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.
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh *
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Both are stored "pending" rather than in the file system.
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh *
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * Returns: errno
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh */
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintoshstatic int
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Rosssmb_set_open_attributes(smb_request_t *sr, smb_ofile_t *of)
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh{
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross smb_attr_t attr;
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright smb_arg_open_t *op = &sr->sr_open;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_node_t *node = of->f_node;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross int rc = 0;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh bzero(&attr, sizeof (smb_attr_t));
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (op->created_readonly) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr.sa_dosattr = op->dattr | FILE_ATTRIBUTE_READONLY;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr.sa_mask |= SMB_AT_DOSATTR;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross }
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross if (op->dsize != 0) {
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross attr.sa_allocsz = op->dsize;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross attr.sa_mask |= SMB_AT_ALLOCSZ;
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross }
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh if ((op->mtime.tv_sec != 0) && (op->mtime.tv_sec != UINT_MAX)) {
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh attr.sa_vattr.va_mtime = op->mtime;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr.sa_mask |= SMB_AT_MTIME;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh }
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross /*
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 *
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 */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (op->action_taken == SMB_OACT_TRUNCATED)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross of->f_written = B_TRUE;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (attr.sa_mask != 0)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross rc = smb_node_setattr(sr, node, of->f_cr, of, &attr);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh return (rc);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh}
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
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.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United Statesstatic void
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United Statessmb_delete_new_object(smb_request_t *sr)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright smb_arg_open_t *op = &sr->sr_open;
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);
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States}