1da6c28aaSamw /* 2da6c28aaSamw * CDDL HEADER START 3da6c28aaSamw * 4da6c28aaSamw * The contents of this file are subject to the terms of the 5da6c28aaSamw * Common Development and Distribution License (the "License"). 6da6c28aaSamw * You may not use this file except in compliance with the License. 7da6c28aaSamw * 8da6c28aaSamw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9da6c28aaSamw * or http://www.opensolaris.org/os/licensing. 10da6c28aaSamw * See the License for the specific language governing permissions 11da6c28aaSamw * and limitations under the License. 12da6c28aaSamw * 13da6c28aaSamw * When distributing Covered Code, include this CDDL HEADER in each 14da6c28aaSamw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15da6c28aaSamw * If applicable, add the following below this CDDL HEADER, with the 16da6c28aaSamw * fields enclosed by brackets "[]" replaced with your own identifying 17da6c28aaSamw * information: Portions Copyright [yyyy] [name of copyright owner] 18da6c28aaSamw * 19da6c28aaSamw * CDDL HEADER END 20da6c28aaSamw */ 21148c5f43SAlan Wright 22da6c28aaSamw /* 23148c5f43SAlan Wright * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 24fb699f1eSAlek Pinchuk * Copyright 2014 Nexenta Systems, Inc. All rights reserved. 25da6c28aaSamw */ 26da6c28aaSamw 27da6c28aaSamw /* 28da6c28aaSamw * This module provides the common open functionality to the various 29da6c28aaSamw * open and create SMB interface functions. 30da6c28aaSamw */ 31da6c28aaSamw 32bbf6f00cSJordan Brown #include <sys/types.h> 33bbf6f00cSJordan Brown #include <sys/cmn_err.h> 34da6c28aaSamw #include <sys/fcntl.h> 35dc20a302Sas200622 #include <sys/nbmlock.h> 36bbf6f00cSJordan Brown #include <smbsrv/string.h> 37bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h> 38bbf6f00cSJordan Brown #include <smbsrv/smb_fsops.h> 39bbf6f00cSJordan Brown #include <smbsrv/smbinfo.h> 40da6c28aaSamw 41*68b2bbf2SGordon Ross static volatile uint32_t smb_fids = 0; 42b819cea2SGordon Ross #define SMB_UNIQ_FID() atomic_inc_32_nv(&smb_fids) 437b59d02dSjb150015 447b59d02dSjb150015 static uint32_t smb_open_subr(smb_request_t *); 45faa1795aSjb150015 extern uint32_t smb_is_executable(char *); 468b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States static void smb_delete_new_object(smb_request_t *); 475fd03bc0SGordon Ross static int smb_set_open_attributes(smb_request_t *, smb_ofile_t *); 48cb174861Sjoyce mcintosh static void smb_open_oplock_break(smb_request_t *, smb_node_t *); 49cb174861Sjoyce mcintosh static boolean_t smb_open_attr_only(smb_arg_open_t *); 50cb174861Sjoyce mcintosh static boolean_t smb_open_overwrite(smb_arg_open_t *); 51da6c28aaSamw 52da6c28aaSamw /* 53da6c28aaSamw * smb_access_generic_to_file 54da6c28aaSamw * 55da6c28aaSamw * Search MSDN for IoCreateFile to see following mapping. 56da6c28aaSamw * 57da6c28aaSamw * GENERIC_READ STANDARD_RIGHTS_READ, FILE_READ_DATA, 58da6c28aaSamw * FILE_READ_ATTRIBUTES and FILE_READ_EA 59da6c28aaSamw * 60da6c28aaSamw * GENERIC_WRITE STANDARD_RIGHTS_WRITE, FILE_WRITE_DATA, 61da6c28aaSamw * FILE_WRITE_ATTRIBUTES, FILE_WRITE_EA, and FILE_APPEND_DATA 62da6c28aaSamw * 63da6c28aaSamw * GENERIC_EXECUTE STANDARD_RIGHTS_EXECUTE, SYNCHRONIZE, and FILE_EXECUTE. 64193e3365SGordon Ross * 65193e3365SGordon Ross * Careful, we have to emulate some Windows behavior here. 66193e3365SGordon Ross * When requested access == zero, you get READ_CONTROL. 67193e3365SGordon Ross * MacOS 10.7 depends on this. 68da6c28aaSamw */ 69da6c28aaSamw uint32_t 70da6c28aaSamw smb_access_generic_to_file(uint32_t desired_access) 71da6c28aaSamw { 72193e3365SGordon Ross uint32_t access = READ_CONTROL; 73da6c28aaSamw 74da6c28aaSamw if (desired_access & GENERIC_ALL) 75da6c28aaSamw return (FILE_ALL_ACCESS & ~SYNCHRONIZE); 76da6c28aaSamw 77da6c28aaSamw if (desired_access & GENERIC_EXECUTE) { 78da6c28aaSamw desired_access &= ~GENERIC_EXECUTE; 79da6c28aaSamw access |= (STANDARD_RIGHTS_EXECUTE | 80da6c28aaSamw SYNCHRONIZE | FILE_EXECUTE); 81da6c28aaSamw } 82da6c28aaSamw 83da6c28aaSamw if (desired_access & GENERIC_WRITE) { 84da6c28aaSamw desired_access &= ~GENERIC_WRITE; 85da6c28aaSamw access |= (FILE_GENERIC_WRITE & ~SYNCHRONIZE); 86da6c28aaSamw } 87da6c28aaSamw 88da6c28aaSamw if (desired_access & GENERIC_READ) { 89da6c28aaSamw desired_access &= ~GENERIC_READ; 90da6c28aaSamw access |= FILE_GENERIC_READ; 91da6c28aaSamw } 92da6c28aaSamw 93da6c28aaSamw return (access | desired_access); 94da6c28aaSamw } 95da6c28aaSamw 96da6c28aaSamw /* 97da6c28aaSamw * smb_omode_to_amask 98da6c28aaSamw * 99da6c28aaSamw * This function converts open modes used by Open and Open AndX 100da6c28aaSamw * commands to desired access bits used by NT Create AndX command. 101da6c28aaSamw */ 102da6c28aaSamw uint32_t 103da6c28aaSamw smb_omode_to_amask(uint32_t desired_access) 104da6c28aaSamw { 105da6c28aaSamw switch (desired_access & SMB_DA_ACCESS_MASK) { 106da6c28aaSamw case SMB_DA_ACCESS_READ: 107da6c28aaSamw return (FILE_GENERIC_READ); 108da6c28aaSamw 109da6c28aaSamw case SMB_DA_ACCESS_WRITE: 110da6c28aaSamw return (FILE_GENERIC_WRITE); 111da6c28aaSamw 112da6c28aaSamw case SMB_DA_ACCESS_READ_WRITE: 113da6c28aaSamw return (FILE_GENERIC_READ | FILE_GENERIC_WRITE); 114da6c28aaSamw 115da6c28aaSamw case SMB_DA_ACCESS_EXECUTE: 116da6c28aaSamw return (FILE_GENERIC_EXECUTE); 117da6c28aaSamw 1182c2961f8Sjose borrego default: 1192c2961f8Sjose borrego return (FILE_GENERIC_ALL); 1202c2961f8Sjose borrego } 121da6c28aaSamw } 122da6c28aaSamw 123da6c28aaSamw /* 124da6c28aaSamw * smb_denymode_to_sharemode 125da6c28aaSamw * 126da6c28aaSamw * This function converts deny modes used by Open and Open AndX 127da6c28aaSamw * commands to share access bits used by NT Create AndX command. 128da6c28aaSamw */ 129da6c28aaSamw uint32_t 130da6c28aaSamw smb_denymode_to_sharemode(uint32_t desired_access, char *fname) 131da6c28aaSamw { 132da6c28aaSamw switch (desired_access & SMB_DA_SHARE_MASK) { 133da6c28aaSamw case SMB_DA_SHARE_COMPATIBILITY: 134da6c28aaSamw if (smb_is_executable(fname)) 135da6c28aaSamw return (FILE_SHARE_READ | FILE_SHARE_WRITE); 136c8ec8eeaSjose borrego 137c8ec8eeaSjose borrego return (FILE_SHARE_ALL); 138da6c28aaSamw 139da6c28aaSamw case SMB_DA_SHARE_EXCLUSIVE: 140da6c28aaSamw return (FILE_SHARE_NONE); 141da6c28aaSamw 142da6c28aaSamw case SMB_DA_SHARE_DENY_WRITE: 143da6c28aaSamw return (FILE_SHARE_READ); 144da6c28aaSamw 145da6c28aaSamw case SMB_DA_SHARE_DENY_READ: 146da6c28aaSamw return (FILE_SHARE_WRITE); 147da6c28aaSamw 148da6c28aaSamw case SMB_DA_SHARE_DENY_NONE: 1492c2961f8Sjose borrego default: 150da6c28aaSamw return (FILE_SHARE_READ | FILE_SHARE_WRITE); 151da6c28aaSamw } 152da6c28aaSamw } 153da6c28aaSamw 154da6c28aaSamw /* 155da6c28aaSamw * smb_ofun_to_crdisposition 156da6c28aaSamw * 157da6c28aaSamw * This function converts open function values used by Open and Open AndX 158da6c28aaSamw * commands to create disposition values used by NT Create AndX command. 159da6c28aaSamw */ 160da6c28aaSamw uint32_t 161da6c28aaSamw smb_ofun_to_crdisposition(uint16_t ofun) 162da6c28aaSamw { 163da6c28aaSamw static int ofun_cr_map[3][2] = 164da6c28aaSamw { 165da6c28aaSamw { -1, FILE_CREATE }, 166da6c28aaSamw { FILE_OPEN, FILE_OPEN_IF }, 167da6c28aaSamw { FILE_OVERWRITE, FILE_OVERWRITE_IF } 168da6c28aaSamw }; 169da6c28aaSamw 170da6c28aaSamw int row = ofun & SMB_OFUN_OPEN_MASK; 171da6c28aaSamw int col = (ofun & SMB_OFUN_CREATE_MASK) >> 4; 172da6c28aaSamw 173da6c28aaSamw if (row == 3) 1742c2961f8Sjose borrego return (FILE_MAXIMUM_DISPOSITION + 1); 175da6c28aaSamw 176da6c28aaSamw return (ofun_cr_map[row][col]); 177da6c28aaSamw } 178da6c28aaSamw 179da6c28aaSamw /* 1807b59d02dSjb150015 * Retry opens to avoid spurious sharing violations, due to timing 1817b59d02dSjb150015 * issues between closes and opens. The client that already has the 1827b59d02dSjb150015 * file open may be in the process of closing it. 1837b59d02dSjb150015 */ 1847b59d02dSjb150015 uint32_t 1857b59d02dSjb150015 smb_common_open(smb_request_t *sr) 1867b59d02dSjb150015 { 187148c5f43SAlan Wright smb_arg_open_t *parg; 1887b59d02dSjb150015 uint32_t status = NT_STATUS_SUCCESS; 1897b59d02dSjb150015 int count; 1907b59d02dSjb150015 191bbf6f00cSJordan Brown parg = kmem_alloc(sizeof (*parg), KM_SLEEP); 192bbf6f00cSJordan Brown bcopy(&sr->arg.open, parg, sizeof (*parg)); 193bbf6f00cSJordan Brown 1947b59d02dSjb150015 for (count = 0; count <= 4; count++) { 195bbf6f00cSJordan Brown if (count != 0) 1967b59d02dSjb150015 delay(MSEC_TO_TICK(400)); 1977b59d02dSjb150015 198faa1795aSjb150015 status = smb_open_subr(sr); 199faa1795aSjb150015 if (status != NT_STATUS_SHARING_VIOLATION) 2007b59d02dSjb150015 break; 201bbf6f00cSJordan Brown 202bbf6f00cSJordan Brown bcopy(parg, &sr->arg.open, sizeof (*parg)); 2037b59d02dSjb150015 } 2047b59d02dSjb150015 205faa1795aSjb150015 if (status == NT_STATUS_SHARING_VIOLATION) { 2067b59d02dSjb150015 smbsr_error(sr, NT_STATUS_SHARING_VIOLATION, 2077b59d02dSjb150015 ERRDOS, ERROR_SHARING_VIOLATION); 2087b59d02dSjb150015 } 2097b59d02dSjb150015 2102c2961f8Sjose borrego if (status == NT_STATUS_NO_SUCH_FILE) { 2112c2961f8Sjose borrego smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND, 2122c2961f8Sjose borrego ERRDOS, ERROR_FILE_NOT_FOUND); 2132c2961f8Sjose borrego } 2142c2961f8Sjose borrego 215bbf6f00cSJordan Brown kmem_free(parg, sizeof (*parg)); 2167b59d02dSjb150015 return (status); 2177b59d02dSjb150015 } 2187b59d02dSjb150015 2197b59d02dSjb150015 /* 220da6c28aaSamw * smb_open_subr 221da6c28aaSamw * 222da6c28aaSamw * Notes on write-through behaviour. It looks like pre-LM0.12 versions 223da6c28aaSamw * of the protocol specify the write-through mode when a file is opened, 224da6c28aaSamw * (SmbOpen, SmbOpenAndX) so the write calls (SmbWrite, SmbWriteAndClose, 225da6c28aaSamw * SmbWriteAndUnlock) don't need to contain a write-through flag. 226da6c28aaSamw * 227da6c28aaSamw * With LM0.12, the open calls (SmbCreateAndX, SmbNtTransactCreate) 228da6c28aaSamw * don't indicate which write-through mode to use. Instead the write 229da6c28aaSamw * calls (SmbWriteAndX, SmbWriteRaw) specify the mode on a per call 230da6c28aaSamw * basis. 231da6c28aaSamw * 232da6c28aaSamw * We don't care which open call was used to get us here, we just need 233da6c28aaSamw * to ensure that the write-through mode flag is copied from the open 234da6c28aaSamw * parameters to the node. We test the omode write-through flag in all 235da6c28aaSamw * write functions. 236da6c28aaSamw * 237da6c28aaSamw * This function will return NT status codes but it also raises errors, 238da6c28aaSamw * in which case it won't return to the caller. Be careful how you 239da6c28aaSamw * handle things in here. 2408c10a865Sas200622 * 2418c10a865Sas200622 * The following rules apply when processing a file open request: 2428c10a865Sas200622 * 243cb174861Sjoyce mcintosh * - Oplocks must be broken prior to share checking as the break may 244cb174861Sjoyce mcintosh * cause other clients to close the file, which would affect sharing 245cb174861Sjoyce mcintosh * checks. 2468c10a865Sas200622 * 2478c10a865Sas200622 * - Share checks must take place prior to access checks for correct 2488c10a865Sas200622 * Windows semantics and to prevent unnecessary NFS delegation recalls. 2498c10a865Sas200622 * 2508c10a865Sas200622 * - Oplocks must be acquired after open to ensure the correct 2518c10a865Sas200622 * synchronization with NFS delegation and FEM installation. 252c8ec8eeaSjose borrego * 253c8ec8eeaSjose borrego * DOS readonly bit rules 254c8ec8eeaSjose borrego * 255c8ec8eeaSjose borrego * 1. The creator of a readonly file can write to/modify the size of the file 256c8ec8eeaSjose borrego * using the original create fid, even though the file will appear as readonly 257c8ec8eeaSjose borrego * to all other fids and via a CIFS getattr call. 258037cac00Sjoyce mcintosh * The readonly bit therefore cannot be set in the filesystem until the file 259037cac00Sjoyce mcintosh * is closed (smb_ofile_close). It is accounted for via ofile and node flags. 260c8ec8eeaSjose borrego * 261c8ec8eeaSjose borrego * 2. A setinfo operation (using either an open fid or a path) to set/unset 262c8ec8eeaSjose borrego * readonly will be successful regardless of whether a creator of a readonly 263c8ec8eeaSjose borrego * file has an open fid (and has the special privilege mentioned in #1, 264c8ec8eeaSjose borrego * above). I.e., the creator of a readonly fid holding that fid will no longer 265c8ec8eeaSjose borrego * have a special privilege. 266c8ec8eeaSjose borrego * 267c8ec8eeaSjose borrego * 3. The DOS readonly bit affects only data and some metadata. 268c8ec8eeaSjose borrego * The following metadata can be changed regardless of the readonly bit: 269c8ec8eeaSjose borrego * - security descriptors 270c8ec8eeaSjose borrego * - DOS attributes 271c8ec8eeaSjose borrego * - timestamps 272c8ec8eeaSjose borrego * 273c8ec8eeaSjose borrego * In the current implementation, the file size cannot be changed (except for 274c8ec8eeaSjose borrego * the exceptions in #1 and #2, above). 2752c1b14e5Sjose borrego * 2762c1b14e5Sjose borrego * 2772c1b14e5Sjose borrego * DOS attribute rules 2782c1b14e5Sjose borrego * 2792c1b14e5Sjose borrego * These rules are specific to creating / opening files and directories. 2802c1b14e5Sjose borrego * How the attribute value (specifically ZERO or FILE_ATTRIBUTE_NORMAL) 2812c1b14e5Sjose borrego * should be interpreted may differ in other requests. 2822c1b14e5Sjose borrego * 2832c1b14e5Sjose borrego * - An attribute value equal to ZERO or FILE_ATTRIBUTE_NORMAL means that the 2842c1b14e5Sjose borrego * file's attributes should be cleared. 2852c1b14e5Sjose borrego * - If FILE_ATTRIBUTE_NORMAL is specified with any other attributes, 2862c1b14e5Sjose borrego * FILE_ATTRIBUTE_NORMAL is ignored. 2872c1b14e5Sjose borrego * 2882c1b14e5Sjose borrego * 1. Creating a new file 2892c1b14e5Sjose borrego * - The request attributes + FILE_ATTRIBUTE_ARCHIVE are applied to the file. 2902c1b14e5Sjose borrego * 2912c1b14e5Sjose borrego * 2. Creating a new directory 2922c1b14e5Sjose borrego * - The request attributes + FILE_ATTRIBUTE_DIRECTORY are applied to the file. 2932c1b14e5Sjose borrego * - FILE_ATTRIBUTE_ARCHIVE does not get set. 2942c1b14e5Sjose borrego * 2952c1b14e5Sjose borrego * 3. Overwriting an existing file 2962c1b14e5Sjose borrego * - the request attributes are used as search attributes. If the existing 2972c1b14e5Sjose borrego * file does not meet the search criteria access is denied. 2982c1b14e5Sjose borrego * - otherwise, applies attributes + FILE_ATTRIBUTE_ARCHIVE. 2992c1b14e5Sjose borrego * 3002c1b14e5Sjose borrego * 4. Opening an existing file or directory 3012c1b14e5Sjose borrego * The request attributes are ignored. 302da6c28aaSamw */ 3037b59d02dSjb150015 static uint32_t 3047b59d02dSjb150015 smb_open_subr(smb_request_t *sr) 305da6c28aaSamw { 306eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States boolean_t created = B_FALSE; 307eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States boolean_t last_comp_found = B_FALSE; 3082c2961f8Sjose borrego smb_node_t *node = NULL; 3092c2961f8Sjose borrego smb_node_t *dnode = NULL; 310eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States smb_node_t *cur_node = NULL; 311148c5f43SAlan Wright smb_arg_open_t *op = &sr->sr_open; 312da6c28aaSamw int rc; 3132c2961f8Sjose borrego smb_ofile_t *of; 314da6c28aaSamw smb_attr_t new_attr; 315da6c28aaSamw int max_requested = 0; 316da6c28aaSamw uint32_t max_allowed; 317da6c28aaSamw uint32_t status = NT_STATUS_SUCCESS; 318da6c28aaSamw int is_dir; 319da6c28aaSamw smb_error_t err; 3202c2961f8Sjose borrego boolean_t is_stream = B_FALSE; 321da6c28aaSamw int lookup_flags = SMB_FOLLOW_LINKS; 322dc20a302Sas200622 uint32_t uniq_fid; 323eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_t *pn = &op->fqi.fq_path; 324cb174861Sjoyce mcintosh smb_server_t *sv = sr->sr_server; 325da6c28aaSamw 326da6c28aaSamw is_dir = (op->create_options & FILE_DIRECTORY_FILE) ? 1 : 0; 327da6c28aaSamw 328da6c28aaSamw /* 329037cac00Sjoyce mcintosh * If the object being created or opened is a directory 330037cac00Sjoyce mcintosh * the Disposition parameter must be one of FILE_CREATE, 331037cac00Sjoyce mcintosh * FILE_OPEN, or FILE_OPEN_IF 332da6c28aaSamw */ 333037cac00Sjoyce mcintosh if (is_dir) { 334da6c28aaSamw if ((op->create_disposition != FILE_CREATE) && 335da6c28aaSamw (op->create_disposition != FILE_OPEN_IF) && 336da6c28aaSamw (op->create_disposition != FILE_OPEN)) { 337dc20a302Sas200622 smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 338da6c28aaSamw ERRDOS, ERROR_INVALID_ACCESS); 3397b59d02dSjb150015 return (NT_STATUS_INVALID_PARAMETER); 340da6c28aaSamw } 341da6c28aaSamw } 342da6c28aaSamw 343da6c28aaSamw if (op->desired_access & MAXIMUM_ALLOWED) { 344da6c28aaSamw max_requested = 1; 345da6c28aaSamw op->desired_access &= ~MAXIMUM_ALLOWED; 346da6c28aaSamw } 347da6c28aaSamw op->desired_access = smb_access_generic_to_file(op->desired_access); 348da6c28aaSamw 349da6c28aaSamw if (sr->session->s_file_cnt >= SMB_SESSION_OFILE_MAX) { 350da6c28aaSamw ASSERT(sr->uid_user); 351cb174861Sjoyce mcintosh cmn_err(CE_NOTE, "smbsrv[%s\\%s]: TOO_MANY_OPENED_FILES", 352148c5f43SAlan Wright sr->uid_user->u_domain, sr->uid_user->u_name); 353da6c28aaSamw 354dc20a302Sas200622 smbsr_error(sr, NT_STATUS_TOO_MANY_OPENED_FILES, 355da6c28aaSamw ERRDOS, ERROR_TOO_MANY_OPEN_FILES); 3567b59d02dSjb150015 return (NT_STATUS_TOO_MANY_OPENED_FILES); 357da6c28aaSamw } 358da6c28aaSamw 359da6c28aaSamw /* This must be NULL at this point */ 360da6c28aaSamw sr->fid_ofile = NULL; 361da6c28aaSamw 362da6c28aaSamw op->devstate = 0; 363da6c28aaSamw 364da6c28aaSamw switch (sr->tid_tree->t_res_type & STYPE_MASK) { 365da6c28aaSamw case STYPE_DISKTREE: 366f96bd5c8SAlan Wright case STYPE_PRINTQ: 367da6c28aaSamw break; 368da6c28aaSamw 369da6c28aaSamw case STYPE_IPC: 370cb174861Sjoyce mcintosh 371cb174861Sjoyce mcintosh if ((rc = smb_threshold_enter(&sv->sv_opipe_ct)) != 0) { 372cb174861Sjoyce mcintosh status = RPC_NT_SERVER_TOO_BUSY; 373cb174861Sjoyce mcintosh smbsr_error(sr, status, 0, 0); 374cb174861Sjoyce mcintosh return (status); 375cb174861Sjoyce mcintosh } 376cb174861Sjoyce mcintosh 377da6c28aaSamw /* 378da6c28aaSamw * No further processing for IPC, we need to either 379da6c28aaSamw * raise an exception or return success here. 380da6c28aaSamw */ 381*68b2bbf2SGordon Ross uniq_fid = SMB_UNIQ_FID(); 382*68b2bbf2SGordon Ross status = smb_opipe_open(sr, uniq_fid); 383*68b2bbf2SGordon Ross if (status != NT_STATUS_SUCCESS) 3847b59d02dSjb150015 smbsr_error(sr, status, 0, 0); 385cb174861Sjoyce mcintosh 386856399cfSGordon Ross smb_threshold_exit(&sv->sv_opipe_ct); 3877b59d02dSjb150015 return (status); 388da6c28aaSamw 389da6c28aaSamw default: 3907b59d02dSjb150015 smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE, 3917b59d02dSjb150015 ERRDOS, ERROR_BAD_DEV_TYPE); 3927b59d02dSjb150015 return (NT_STATUS_BAD_DEVICE_TYPE); 393da6c28aaSamw } 394da6c28aaSamw 395fe1c642dSBill Krier smb_pathname_init(sr, pn, pn->pn_path); 396fe1c642dSBill Krier if (!smb_pathname_validate(sr, pn)) 397fe1c642dSBill Krier return (sr->smb_error.status); 398fe1c642dSBill Krier 399fe1c642dSBill Krier if (strlen(pn->pn_path) >= MAXPATHLEN) { 400dc20a302Sas200622 smbsr_error(sr, 0, ERRSRV, ERRfilespecs); 4017b59d02dSjb150015 return (NT_STATUS_NAME_TOO_LONG); 402da6c28aaSamw } 403da6c28aaSamw 404fe1c642dSBill Krier if (is_dir) { 405fe1c642dSBill Krier if (!smb_validate_dirname(sr, pn)) 406fe1c642dSBill Krier return (sr->smb_error.status); 407fe1c642dSBill Krier } else { 408fe1c642dSBill Krier if (!smb_validate_object_name(sr, pn)) 409fe1c642dSBill Krier return (sr->smb_error.status); 410da6c28aaSamw } 411da6c28aaSamw 412eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States cur_node = op->fqi.fq_dnode ? 413eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States op->fqi.fq_dnode : sr->tid_tree->t_snode; 414da6c28aaSamw 415eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States /* 416eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States * if no path or filename are specified the stream should be 417eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States * created on cur_node 418eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States */ 419eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States if (!is_dir && !pn->pn_pname && !pn->pn_fname && pn->pn_sname) { 4209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 4219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Can't currently handle a stream on the tree root. 4229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * If a stream is being opened return "not found", otherwise 4239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * return "access denied". 4249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 425eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States if (cur_node == sr->tid_tree->t_snode) { 4269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (op->create_disposition == FILE_OPEN) { 4279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND, 4289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ERRDOS, ERROR_FILE_NOT_FOUND); 4299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (NT_STATUS_OBJECT_NAME_NOT_FOUND); 4309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 431eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, 432eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States ERROR_ACCESS_DENIED); 433eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States return (NT_STATUS_ACCESS_DENIED); 434eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States } 435eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 436eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States (void) snprintf(op->fqi.fq_last_comp, 437eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States sizeof (op->fqi.fq_last_comp), 438eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States "%s%s", cur_node->od_name, pn->pn_sname); 439eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 4401fcced4cSJordan Brown op->fqi.fq_dnode = cur_node->n_dnode; 441eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States smb_node_ref(op->fqi.fq_dnode); 442eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States } else { 443b819cea2SGordon Ross rc = smb_pathname_reduce(sr, sr->user_cr, pn->pn_path, 444eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States sr->tid_tree->t_snode, cur_node, &op->fqi.fq_dnode, 445b819cea2SGordon Ross op->fqi.fq_last_comp); 446b819cea2SGordon Ross if (rc != 0) { 447dc20a302Sas200622 smbsr_errno(sr, rc); 4487b59d02dSjb150015 return (sr->smb_error.status); 449da6c28aaSamw } 450eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States } 451da6c28aaSamw 452da6c28aaSamw /* 453da6c28aaSamw * If the access mask has only DELETE set (ignore 454da6c28aaSamw * FILE_READ_ATTRIBUTES), then assume that this 455da6c28aaSamw * is a request to delete the link (if a link) 456da6c28aaSamw * and do not follow links. Otherwise, follow 457da6c28aaSamw * the link to the target. 458da6c28aaSamw */ 459037cac00Sjoyce mcintosh if ((op->desired_access & ~FILE_READ_ATTRIBUTES) == DELETE) 460da6c28aaSamw lookup_flags &= ~SMB_FOLLOW_LINKS; 461da6c28aaSamw 4628622ec45SGordon Ross rc = smb_fsop_lookup_name(sr, zone_kcred(), lookup_flags, 463eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States sr->tid_tree->t_snode, op->fqi.fq_dnode, op->fqi.fq_last_comp, 464037cac00Sjoyce mcintosh &op->fqi.fq_fnode); 465da6c28aaSamw 466da6c28aaSamw if (rc == 0) { 467eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States last_comp_found = B_TRUE; 4685fd03bc0SGordon Ross /* 4695fd03bc0SGordon Ross * Need the DOS attributes below, where we 4705fd03bc0SGordon Ross * check the search attributes (sattr). 4715fd03bc0SGordon Ross */ 4725fd03bc0SGordon Ross op->fqi.fq_fattr.sa_mask = SMB_AT_DOSATTR; 4738622ec45SGordon Ross rc = smb_node_getattr(sr, op->fqi.fq_fnode, zone_kcred(), 4745fd03bc0SGordon Ross NULL, &op->fqi.fq_fattr); 475037cac00Sjoyce mcintosh if (rc != 0) { 476037cac00Sjoyce mcintosh smb_node_release(op->fqi.fq_fnode); 477037cac00Sjoyce mcintosh smb_node_release(op->fqi.fq_dnode); 478037cac00Sjoyce mcintosh smbsr_error(sr, NT_STATUS_INTERNAL_ERROR, 479037cac00Sjoyce mcintosh ERRDOS, ERROR_INTERNAL_ERROR); 480037cac00Sjoyce mcintosh return (sr->smb_error.status); 481037cac00Sjoyce mcintosh } 482da6c28aaSamw } else if (rc == ENOENT) { 483eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States last_comp_found = B_FALSE; 484eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States op->fqi.fq_fnode = NULL; 485da6c28aaSamw rc = 0; 486da6c28aaSamw } else { 487eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(op->fqi.fq_dnode); 488dc20a302Sas200622 smbsr_errno(sr, rc); 4897b59d02dSjb150015 return (sr->smb_error.status); 490da6c28aaSamw } 491da6c28aaSamw 492037cac00Sjoyce mcintosh 493dc20a302Sas200622 /* 494dc20a302Sas200622 * The uniq_fid is a CIFS-server-wide unique identifier for an ofile 495dc20a302Sas200622 * which is used to uniquely identify open instances for the 496c8ec8eeaSjose borrego * VFS share reservation and POSIX locks. 497dc20a302Sas200622 */ 498dc20a302Sas200622 499dc20a302Sas200622 uniq_fid = SMB_UNIQ_FID(); 500dc20a302Sas200622 501eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States if (last_comp_found) { 5026537f381Sas200622 5039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States node = op->fqi.fq_fnode; 5049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States dnode = op->fqi.fq_dnode; 5056537f381Sas200622 5069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (!smb_node_is_file(node) && !smb_node_is_dir(node) && 5079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States !smb_node_is_symlink(node)) { 5089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(node); 5099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(dnode); 5106537f381Sas200622 smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, 5116537f381Sas200622 ERRnoaccess); 5126537f381Sas200622 return (NT_STATUS_ACCESS_DENIED); 5136537f381Sas200622 } 5146537f381Sas200622 515da6c28aaSamw /* 5162c1b14e5Sjose borrego * Reject this request if either: 5172c1b14e5Sjose borrego * - the target IS a directory and the client requires that 5182c1b14e5Sjose borrego * it must NOT be (required by Lotus Notes) 5192c1b14e5Sjose borrego * - the target is NOT a directory and client requires that 5202c1b14e5Sjose borrego * it MUST be. 521da6c28aaSamw */ 5229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (smb_node_is_dir(node)) { 5232c1b14e5Sjose borrego if (op->create_options & FILE_NON_DIRECTORY_FILE) { 524da6c28aaSamw smb_node_release(node); 525da6c28aaSamw smb_node_release(dnode); 526dc20a302Sas200622 smbsr_error(sr, NT_STATUS_FILE_IS_A_DIRECTORY, 527da6c28aaSamw ERRDOS, ERROR_ACCESS_DENIED); 5287b59d02dSjb150015 return (NT_STATUS_FILE_IS_A_DIRECTORY); 529da6c28aaSamw } 5302c1b14e5Sjose borrego } else { 5312c1b14e5Sjose borrego if ((op->create_options & FILE_DIRECTORY_FILE) || 5322c2961f8Sjose borrego (op->nt_flags & NT_CREATE_FLAG_OPEN_TARGET_DIR)) { 533da6c28aaSamw smb_node_release(node); 534da6c28aaSamw smb_node_release(dnode); 535dc20a302Sas200622 smbsr_error(sr, NT_STATUS_NOT_A_DIRECTORY, 536da6c28aaSamw ERRDOS, ERROR_DIRECTORY); 5377b59d02dSjb150015 return (NT_STATUS_NOT_A_DIRECTORY); 538da6c28aaSamw } 5392c1b14e5Sjose borrego } 540da6c28aaSamw 541da6c28aaSamw /* 542da6c28aaSamw * No more open should be accepted when "Delete on close" 543da6c28aaSamw * flag is set. 544da6c28aaSamw */ 545da6c28aaSamw if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) { 546da6c28aaSamw smb_node_release(node); 547da6c28aaSamw smb_node_release(dnode); 548dc20a302Sas200622 smbsr_error(sr, NT_STATUS_DELETE_PENDING, 549da6c28aaSamw ERRDOS, ERROR_ACCESS_DENIED); 5507b59d02dSjb150015 return (NT_STATUS_DELETE_PENDING); 551da6c28aaSamw } 552da6c28aaSamw 553da6c28aaSamw /* 554da6c28aaSamw * Specified file already exists so the operation should fail. 555da6c28aaSamw */ 556da6c28aaSamw if (op->create_disposition == FILE_CREATE) { 557da6c28aaSamw smb_node_release(node); 558da6c28aaSamw smb_node_release(dnode); 559dc20a302Sas200622 smbsr_error(sr, NT_STATUS_OBJECT_NAME_COLLISION, 560b89a8333Snatalie li - Sun Microsystems - Irvine United States ERRDOS, ERROR_FILE_EXISTS); 5617b59d02dSjb150015 return (NT_STATUS_OBJECT_NAME_COLLISION); 562da6c28aaSamw } 563da6c28aaSamw 564da6c28aaSamw /* 565da6c28aaSamw * Windows seems to check read-only access before file 566da6c28aaSamw * sharing check. 567c8ec8eeaSjose borrego * 568c8ec8eeaSjose borrego * Check to see if the file is currently readonly (irrespective 569c8ec8eeaSjose borrego * of whether this open will make it readonly). 570da6c28aaSamw */ 571c8ec8eeaSjose borrego if (SMB_PATHFILE_IS_READONLY(sr, node)) { 572da6c28aaSamw /* Files data only */ 573037cac00Sjoyce mcintosh if (!smb_node_is_dir(node)) { 574da6c28aaSamw if (op->desired_access & (FILE_WRITE_DATA | 575da6c28aaSamw FILE_APPEND_DATA)) { 576da6c28aaSamw smb_node_release(node); 577da6c28aaSamw smb_node_release(dnode); 578dc20a302Sas200622 smbsr_error(sr, NT_STATUS_ACCESS_DENIED, 579dc20a302Sas200622 ERRDOS, ERRnoaccess); 5807b59d02dSjb150015 return (NT_STATUS_ACCESS_DENIED); 581da6c28aaSamw } 582da6c28aaSamw } 583da6c28aaSamw } 584da6c28aaSamw 585dc20a302Sas200622 if ((op->create_disposition == FILE_SUPERSEDE) || 586dc20a302Sas200622 (op->create_disposition == FILE_OVERWRITE_IF) || 587dc20a302Sas200622 (op->create_disposition == FILE_OVERWRITE)) { 588dc20a302Sas200622 589fb699f1eSAlek Pinchuk if (!smb_sattr_check(op->fqi.fq_fattr.sa_dosattr, 590fb699f1eSAlek Pinchuk op->dattr)) { 591dc20a302Sas200622 smb_node_release(node); 592dc20a302Sas200622 smb_node_release(dnode); 593dc20a302Sas200622 smbsr_error(sr, NT_STATUS_ACCESS_DENIED, 594dc20a302Sas200622 ERRDOS, ERRnoaccess); 5957b59d02dSjb150015 return (NT_STATUS_ACCESS_DENIED); 596dc20a302Sas200622 } 597dc20a302Sas200622 598fb699f1eSAlek Pinchuk if (smb_node_is_dir(node)) { 599da6c28aaSamw smb_node_release(node); 600da6c28aaSamw smb_node_release(dnode); 601fb699f1eSAlek Pinchuk return (NT_STATUS_ACCESS_DENIED); 602da6c28aaSamw } 603fb699f1eSAlek Pinchuk } 604fb699f1eSAlek Pinchuk 605fb699f1eSAlek Pinchuk /* MS-FSA 2.1.5.1.2 */ 606fb699f1eSAlek Pinchuk if (op->create_disposition == FILE_SUPERSEDE) 607fb699f1eSAlek Pinchuk op->desired_access |= DELETE; 608fb699f1eSAlek Pinchuk if ((op->create_disposition == FILE_OVERWRITE_IF) || 609fb699f1eSAlek Pinchuk (op->create_disposition == FILE_OVERWRITE)) 610fb699f1eSAlek Pinchuk op->desired_access |= FILE_WRITE_DATA; 611da6c28aaSamw 612da6c28aaSamw status = smb_fsop_access(sr, sr->user_cr, node, 613da6c28aaSamw op->desired_access); 614da6c28aaSamw if (status != NT_STATUS_SUCCESS) { 615da6c28aaSamw smb_node_release(node); 616da6c28aaSamw smb_node_release(dnode); 617dc20a302Sas200622 618da6c28aaSamw if (status == NT_STATUS_PRIVILEGE_NOT_HELD) { 619dc20a302Sas200622 smbsr_error(sr, status, 620dc20a302Sas200622 ERRDOS, ERROR_PRIVILEGE_NOT_HELD); 6217b59d02dSjb150015 return (status); 622da6c28aaSamw } else { 623dc20a302Sas200622 smbsr_error(sr, NT_STATUS_ACCESS_DENIED, 624dc20a302Sas200622 ERRDOS, ERROR_ACCESS_DENIED); 6257b59d02dSjb150015 return (NT_STATUS_ACCESS_DENIED); 626da6c28aaSamw } 627da6c28aaSamw } 628da6c28aaSamw 629fb699f1eSAlek Pinchuk if (max_requested) { 630fb699f1eSAlek Pinchuk smb_fsop_eaccess(sr, sr->user_cr, node, &max_allowed); 631fb699f1eSAlek Pinchuk op->desired_access |= max_allowed; 632fb699f1eSAlek Pinchuk } 633fb699f1eSAlek Pinchuk 634fb699f1eSAlek Pinchuk /* 635fb699f1eSAlek Pinchuk * Oplock break is done prior to sharing checks as the break 636fb699f1eSAlek Pinchuk * may cause other clients to close the file which would 637fb699f1eSAlek Pinchuk * affect the sharing checks. This may block, so set the 638fb699f1eSAlek Pinchuk * file opening count before oplock stuff. 639fb699f1eSAlek Pinchuk */ 640fb699f1eSAlek Pinchuk smb_node_inc_opening_count(node); 641fb699f1eSAlek Pinchuk smb_open_oplock_break(sr, node); 642fb699f1eSAlek Pinchuk 643fb699f1eSAlek Pinchuk smb_node_wrlock(node); 644fb699f1eSAlek Pinchuk 645fb699f1eSAlek Pinchuk /* 646fb699f1eSAlek Pinchuk * Check for sharing violations 647fb699f1eSAlek Pinchuk */ 648fb699f1eSAlek Pinchuk status = smb_fsop_shrlock(sr->user_cr, node, uniq_fid, 649fb699f1eSAlek Pinchuk op->desired_access, op->share_access); 650fb699f1eSAlek Pinchuk if (status == NT_STATUS_SHARING_VIOLATION) { 6512c2961f8Sjose borrego smb_node_unlock(node); 652cb174861Sjoyce mcintosh smb_node_dec_opening_count(node); 653da6c28aaSamw smb_node_release(node); 654da6c28aaSamw smb_node_release(dnode); 655fb699f1eSAlek Pinchuk return (status); 656da6c28aaSamw } 657da6c28aaSamw 658fb699f1eSAlek Pinchuk /* 659fb699f1eSAlek Pinchuk * Go ahead with modifications as necessary. 660fb699f1eSAlek Pinchuk */ 661fb699f1eSAlek Pinchuk switch (op->create_disposition) { 662fb699f1eSAlek Pinchuk case FILE_SUPERSEDE: 663fb699f1eSAlek Pinchuk case FILE_OVERWRITE_IF: 664fb699f1eSAlek Pinchuk case FILE_OVERWRITE: 665037cac00Sjoyce mcintosh op->dattr |= FILE_ATTRIBUTE_ARCHIVE; 666037cac00Sjoyce mcintosh /* Don't apply readonly bit until smb_ofile_close */ 667037cac00Sjoyce mcintosh if (op->dattr & FILE_ATTRIBUTE_READONLY) { 668037cac00Sjoyce mcintosh op->created_readonly = B_TRUE; 669037cac00Sjoyce mcintosh op->dattr &= ~FILE_ATTRIBUTE_READONLY; 670037cac00Sjoyce mcintosh } 671037cac00Sjoyce mcintosh 672dc20a302Sas200622 bzero(&new_attr, sizeof (new_attr)); 673037cac00Sjoyce mcintosh new_attr.sa_dosattr = op->dattr; 674da6c28aaSamw new_attr.sa_vattr.va_size = op->dsize; 675037cac00Sjoyce mcintosh new_attr.sa_mask = SMB_AT_DOSATTR | SMB_AT_SIZE; 676037cac00Sjoyce mcintosh rc = smb_fsop_setattr(sr, sr->user_cr, node, &new_attr); 677037cac00Sjoyce mcintosh if (rc != 0) { 678037cac00Sjoyce mcintosh smb_fsop_unshrlock(sr->user_cr, node, uniq_fid); 6792c2961f8Sjose borrego smb_node_unlock(node); 680cb174861Sjoyce mcintosh smb_node_dec_opening_count(node); 681da6c28aaSamw smb_node_release(node); 682da6c28aaSamw smb_node_release(dnode); 683dc20a302Sas200622 smbsr_errno(sr, rc); 6847b59d02dSjb150015 return (sr->smb_error.status); 685da6c28aaSamw } 686da6c28aaSamw 687da6c28aaSamw /* 688037cac00Sjoyce mcintosh * If file is being replaced, remove existing streams 689da6c28aaSamw */ 690eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States if (SMB_IS_STREAM(node) == 0) { 691037cac00Sjoyce mcintosh rc = smb_fsop_remove_streams(sr, sr->user_cr, 692037cac00Sjoyce mcintosh node); 693037cac00Sjoyce mcintosh if (rc != 0) { 694eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States smb_fsop_unshrlock(sr->user_cr, node, 695eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States uniq_fid); 696eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States smb_node_unlock(node); 697cb174861Sjoyce mcintosh smb_node_dec_opening_count(node); 698eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(node); 699eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(dnode); 700eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States return (sr->smb_error.status); 701eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States } 702eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States } 703da6c28aaSamw 704da6c28aaSamw op->action_taken = SMB_OACT_TRUNCATED; 705da6c28aaSamw break; 706da6c28aaSamw 707da6c28aaSamw default: 708da6c28aaSamw /* 709da6c28aaSamw * FILE_OPEN or FILE_OPEN_IF. 710da6c28aaSamw */ 711da6c28aaSamw op->action_taken = SMB_OACT_OPENED; 712da6c28aaSamw break; 713da6c28aaSamw } 714da6c28aaSamw } else { 715da6c28aaSamw /* Last component was not found. */ 716eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States dnode = op->fqi.fq_dnode; 717da6c28aaSamw 7187b59d02dSjb150015 if (is_dir == 0) 719eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States is_stream = smb_is_stream_name(pn->pn_path); 7207b59d02dSjb150015 721da6c28aaSamw if ((op->create_disposition == FILE_OPEN) || 722da6c28aaSamw (op->create_disposition == FILE_OVERWRITE)) { 723da6c28aaSamw smb_node_release(dnode); 724dc20a302Sas200622 smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND, 725da6c28aaSamw ERRDOS, ERROR_FILE_NOT_FOUND); 7267b59d02dSjb150015 return (NT_STATUS_OBJECT_NAME_NOT_FOUND); 727da6c28aaSamw } 728da6c28aaSamw 7299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (pn->pn_fname && smb_is_invalid_filename(pn->pn_fname)) { 7302c2961f8Sjose borrego smb_node_release(dnode); 7312c2961f8Sjose borrego smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID, 7322c2961f8Sjose borrego ERRDOS, ERROR_INVALID_NAME); 7332c2961f8Sjose borrego return (NT_STATUS_OBJECT_NAME_INVALID); 7342c2961f8Sjose borrego } 7352c2961f8Sjose borrego 736da6c28aaSamw /* 737da6c28aaSamw * lock the parent dir node in case another create 738da6c28aaSamw * request to the same parent directory comes in. 739da6c28aaSamw */ 7402c2961f8Sjose borrego smb_node_wrlock(dnode); 741da6c28aaSamw 742037cac00Sjoyce mcintosh /* Don't apply readonly bit until smb_ofile_close */ 743037cac00Sjoyce mcintosh if (op->dattr & FILE_ATTRIBUTE_READONLY) { 744037cac00Sjoyce mcintosh op->dattr &= ~FILE_ATTRIBUTE_READONLY; 745037cac00Sjoyce mcintosh op->created_readonly = B_TRUE; 746037cac00Sjoyce mcintosh } 747037cac00Sjoyce mcintosh 748da6c28aaSamw bzero(&new_attr, sizeof (new_attr)); 749c8ec8eeaSjose borrego if ((op->crtime.tv_sec != 0) && 750c8ec8eeaSjose borrego (op->crtime.tv_sec != UINT_MAX)) { 751c8ec8eeaSjose borrego 752c8ec8eeaSjose borrego new_attr.sa_mask |= SMB_AT_CRTIME; 753c8ec8eeaSjose borrego new_attr.sa_crtime = op->crtime; 754c8ec8eeaSjose borrego } 755c8ec8eeaSjose borrego 756da6c28aaSamw if (is_dir == 0) { 757037cac00Sjoyce mcintosh op->dattr |= FILE_ATTRIBUTE_ARCHIVE; 758037cac00Sjoyce mcintosh new_attr.sa_dosattr = op->dattr; 759da6c28aaSamw new_attr.sa_vattr.va_type = VREG; 7607b59d02dSjb150015 new_attr.sa_vattr.va_mode = is_stream ? S_IRUSR : 7617b59d02dSjb150015 S_IRUSR | S_IRGRP | S_IROTH | 7627b59d02dSjb150015 S_IWUSR | S_IWGRP | S_IWOTH; 763037cac00Sjoyce mcintosh new_attr.sa_mask |= 764037cac00Sjoyce mcintosh SMB_AT_DOSATTR | SMB_AT_TYPE | SMB_AT_MODE; 765dc20a302Sas200622 7666537f381Sas200622 if (op->dsize) { 7676537f381Sas200622 new_attr.sa_vattr.va_size = op->dsize; 7686537f381Sas200622 new_attr.sa_mask |= SMB_AT_SIZE; 769dc20a302Sas200622 } 770dc20a302Sas200622 771da6c28aaSamw rc = smb_fsop_create(sr, sr->user_cr, dnode, 772037cac00Sjoyce mcintosh op->fqi.fq_last_comp, &new_attr, &op->fqi.fq_fnode); 773dc20a302Sas200622 774da6c28aaSamw if (rc != 0) { 7752c2961f8Sjose borrego smb_node_unlock(dnode); 776da6c28aaSamw smb_node_release(dnode); 777dc20a302Sas200622 smbsr_errno(sr, rc); 7787b59d02dSjb150015 return (sr->smb_error.status); 779da6c28aaSamw } 780da6c28aaSamw 781eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States node = op->fqi.fq_fnode; 782cb174861Sjoyce mcintosh smb_node_inc_opening_count(node); 7832c2961f8Sjose borrego smb_node_wrlock(node); 784dc20a302Sas200622 785faa1795aSjb150015 status = smb_fsop_shrlock(sr->user_cr, node, uniq_fid, 786c8ec8eeaSjose borrego op->desired_access, op->share_access); 787dc20a302Sas200622 788dc20a302Sas200622 if (status == NT_STATUS_SHARING_VIOLATION) { 7892c2961f8Sjose borrego smb_node_unlock(node); 790cb174861Sjoyce mcintosh smb_node_dec_opening_count(node); 7918b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_delete_new_object(sr); 792dc20a302Sas200622 smb_node_release(node); 7932c2961f8Sjose borrego smb_node_unlock(dnode); 794dc20a302Sas200622 smb_node_release(dnode); 795dc20a302Sas200622 return (status); 796dc20a302Sas200622 } 797da6c28aaSamw } else { 7983db3f65cSamw op->dattr |= FILE_ATTRIBUTE_DIRECTORY; 799037cac00Sjoyce mcintosh new_attr.sa_dosattr = op->dattr; 800da6c28aaSamw new_attr.sa_vattr.va_type = VDIR; 801da6c28aaSamw new_attr.sa_vattr.va_mode = 0777; 802037cac00Sjoyce mcintosh new_attr.sa_mask |= 803037cac00Sjoyce mcintosh SMB_AT_DOSATTR | SMB_AT_TYPE | SMB_AT_MODE; 804c8ec8eeaSjose borrego 805da6c28aaSamw rc = smb_fsop_mkdir(sr, sr->user_cr, dnode, 806037cac00Sjoyce mcintosh op->fqi.fq_last_comp, &new_attr, &op->fqi.fq_fnode); 807da6c28aaSamw if (rc != 0) { 8082c2961f8Sjose borrego smb_node_unlock(dnode); 809da6c28aaSamw smb_node_release(dnode); 810dc20a302Sas200622 smbsr_errno(sr, rc); 8117b59d02dSjb150015 return (sr->smb_error.status); 812da6c28aaSamw } 813dc20a302Sas200622 814eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States node = op->fqi.fq_fnode; 815cb174861Sjoyce mcintosh smb_node_inc_opening_count(node); 8162c2961f8Sjose borrego smb_node_wrlock(node); 817da6c28aaSamw } 818da6c28aaSamw 819eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States created = B_TRUE; 820da6c28aaSamw op->action_taken = SMB_OACT_CREATED; 821c8ec8eeaSjose borrego 8222c1b14e5Sjose borrego if (max_requested) { 8232c1b14e5Sjose borrego smb_fsop_eaccess(sr, sr->user_cr, node, &max_allowed); 8242c1b14e5Sjose borrego op->desired_access |= max_allowed; 8252c1b14e5Sjose borrego } 826fb699f1eSAlek Pinchuk } 8272c1b14e5Sjose borrego 828037cac00Sjoyce mcintosh status = NT_STATUS_SUCCESS; 8292c1b14e5Sjose borrego 830*68b2bbf2SGordon Ross of = smb_ofile_open(sr, node, op, SMB_FTYPE_DISK, uniq_fid, 8313b13a1efSThomas Keiser &err); 832da6c28aaSamw if (of == NULL) { 833dc20a302Sas200622 smbsr_error(sr, err.status, err.errcls, err.errcode); 834037cac00Sjoyce mcintosh status = err.status; 835da6c28aaSamw } 836da6c28aaSamw 837*68b2bbf2SGordon Ross /* 838*68b2bbf2SGordon Ross * We might have blocked in smb_ofile_open long enough so a 839*68b2bbf2SGordon Ross * tree disconnect might have happened. In that case, we've 840*68b2bbf2SGordon Ross * just added an ofile to a tree that's disconnecting, and 841*68b2bbf2SGordon Ross * need to undo that to avoid interfering with tear-down of 842*68b2bbf2SGordon Ross * the tree connection. 843*68b2bbf2SGordon Ross */ 844*68b2bbf2SGordon Ross if (status == NT_STATUS_SUCCESS && 845*68b2bbf2SGordon Ross !smb_tree_is_connected(sr->tid_tree)) { 846037cac00Sjoyce mcintosh smbsr_error(sr, 0, ERRSRV, ERRinvnid); 847*68b2bbf2SGordon Ross status = NT_STATUS_INVALID_PARAMETER; 848037cac00Sjoyce mcintosh } 849037cac00Sjoyce mcintosh 850037cac00Sjoyce mcintosh /* 851037cac00Sjoyce mcintosh * This MUST be done after ofile creation, so that explicitly 8525fd03bc0SGordon Ross * set timestamps can be remembered on the ofile, and the 8535fd03bc0SGordon Ross * readonly flag will be stored "pending" on the node. 854037cac00Sjoyce mcintosh */ 855037cac00Sjoyce mcintosh if (status == NT_STATUS_SUCCESS) { 8565fd03bc0SGordon Ross if ((rc = smb_set_open_attributes(sr, of)) != 0) { 857037cac00Sjoyce mcintosh smbsr_errno(sr, rc); 858037cac00Sjoyce mcintosh status = sr->smb_error.status; 859037cac00Sjoyce mcintosh } 860037cac00Sjoyce mcintosh } 861037cac00Sjoyce mcintosh 862037cac00Sjoyce mcintosh if (status == NT_STATUS_SUCCESS) { 8635fd03bc0SGordon Ross /* 8645fd03bc0SGordon Ross * We've already done access checks above, 8655fd03bc0SGordon Ross * and want this call to succeed even when 8665fd03bc0SGordon Ross * !(desired_access & FILE_READ_ATTRIBUTES), 8675fd03bc0SGordon Ross * so pass kcred here. 8685fd03bc0SGordon Ross */ 8695fd03bc0SGordon Ross op->fqi.fq_fattr.sa_mask = SMB_AT_ALL; 8708622ec45SGordon Ross rc = smb_node_getattr(sr, node, zone_kcred(), of, 8715fd03bc0SGordon Ross &op->fqi.fq_fattr); 8725fd03bc0SGordon Ross if (rc != 0) { 873037cac00Sjoyce mcintosh smbsr_error(sr, NT_STATUS_INTERNAL_ERROR, 874037cac00Sjoyce mcintosh ERRDOS, ERROR_INTERNAL_ERROR); 875037cac00Sjoyce mcintosh status = NT_STATUS_INTERNAL_ERROR; 876037cac00Sjoyce mcintosh } 877037cac00Sjoyce mcintosh } 878037cac00Sjoyce mcintosh 879037cac00Sjoyce mcintosh /* 880037cac00Sjoyce mcintosh * smb_fsop_unshrlock is a no-op if node is a directory 881037cac00Sjoyce mcintosh * smb_fsop_unshrlock is done in smb_ofile_close 882037cac00Sjoyce mcintosh */ 883037cac00Sjoyce mcintosh if (status != NT_STATUS_SUCCESS) { 884037cac00Sjoyce mcintosh if (of == NULL) { 885037cac00Sjoyce mcintosh smb_fsop_unshrlock(sr->user_cr, node, uniq_fid); 886037cac00Sjoyce mcintosh } else { 8878b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_ofile_close(of, 0); 8888b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_ofile_release(of); 889037cac00Sjoyce mcintosh } 8908b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States if (created) 8918b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_delete_new_object(sr); 8928b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_node_unlock(node); 893cb174861Sjoyce mcintosh smb_node_dec_opening_count(node); 8948b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(node); 8958b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States if (created) 8968b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_node_unlock(dnode); 8978b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(dnode); 898037cac00Sjoyce mcintosh return (status); 8998b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States } 9008b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 9018c10a865Sas200622 /* 9028c10a865Sas200622 * Propagate the write-through mode from the open params 9038c10a865Sas200622 * to the node: see the notes in the function header. 9048c10a865Sas200622 */ 9058c10a865Sas200622 if (sr->sr_cfg->skc_sync_enable || 9068c10a865Sas200622 (op->create_options & FILE_WRITE_THROUGH)) 9078c10a865Sas200622 node->flags |= NODE_FLAGS_WRITE_THROUGH; 9088c10a865Sas200622 909037cac00Sjoyce mcintosh /* 910037cac00Sjoyce mcintosh * Set up the fileid and dosattr in open_param for response 911037cac00Sjoyce mcintosh */ 912eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States op->fileid = op->fqi.fq_fattr.sa_vattr.va_nodeid; 913037cac00Sjoyce mcintosh op->dattr = op->fqi.fq_fattr.sa_dosattr; 9148c10a865Sas200622 915da6c28aaSamw /* 916da6c28aaSamw * Set up the file type in open_param for the response 917da6c28aaSamw */ 918da6c28aaSamw op->ftype = SMB_FTYPE_DISK; 919da6c28aaSamw sr->smb_fid = of->f_fid; 920da6c28aaSamw sr->fid_ofile = of; 921da6c28aaSamw 9229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (smb_node_is_file(node)) { 923cb174861Sjoyce mcintosh smb_oplock_acquire(sr, node, of); 924eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States op->dsize = op->fqi.fq_fattr.sa_vattr.va_size; 9259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } else { 9269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* directory or symlink */ 9272c2961f8Sjose borrego op->op_oplock_level = SMB_OPLOCK_NONE; 9282c2961f8Sjose borrego op->dsize = 0; 9292c2961f8Sjose borrego } 930dc20a302Sas200622 931cb174861Sjoyce mcintosh smb_node_dec_opening_count(node); 932cb174861Sjoyce mcintosh 933cb174861Sjoyce mcintosh smb_node_unlock(node); 934cb174861Sjoyce mcintosh if (created) 935cb174861Sjoyce mcintosh smb_node_unlock(dnode); 936cb174861Sjoyce mcintosh 9378b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_node_release(node); 938da6c28aaSamw smb_node_release(dnode); 939da6c28aaSamw 940da6c28aaSamw return (NT_STATUS_SUCCESS); 941da6c28aaSamw } 942da6c28aaSamw 943da6c28aaSamw /* 944cb174861Sjoyce mcintosh * smb_open_oplock_break 945cb174861Sjoyce mcintosh * 946cb174861Sjoyce mcintosh * If the node has an ofile opened with share access none, 947cb174861Sjoyce mcintosh * (smb_node_share_check = FALSE) only break BATCH oplock. 948cb174861Sjoyce mcintosh * Otherwise: 949cb174861Sjoyce mcintosh * If overwriting, break to SMB_OPLOCK_NONE, else 950cb174861Sjoyce mcintosh * If opening for anything other than attribute access, 951cb174861Sjoyce mcintosh * break oplock to LEVEL_II. 952cb174861Sjoyce mcintosh */ 953cb174861Sjoyce mcintosh static void 954cb174861Sjoyce mcintosh smb_open_oplock_break(smb_request_t *sr, smb_node_t *node) 955cb174861Sjoyce mcintosh { 956cb174861Sjoyce mcintosh smb_arg_open_t *op = &sr->sr_open; 957cb174861Sjoyce mcintosh uint32_t flags = 0; 958cb174861Sjoyce mcintosh 959cb174861Sjoyce mcintosh if (!smb_node_share_check(node)) 960cb174861Sjoyce mcintosh flags |= SMB_OPLOCK_BREAK_BATCH; 961cb174861Sjoyce mcintosh 962cb174861Sjoyce mcintosh if (smb_open_overwrite(op)) { 963cb174861Sjoyce mcintosh flags |= SMB_OPLOCK_BREAK_TO_NONE; 964cb174861Sjoyce mcintosh (void) smb_oplock_break(sr, node, flags); 965cb174861Sjoyce mcintosh } else if (!smb_open_attr_only(op)) { 966cb174861Sjoyce mcintosh flags |= SMB_OPLOCK_BREAK_TO_LEVEL_II; 967cb174861Sjoyce mcintosh (void) smb_oplock_break(sr, node, flags); 968cb174861Sjoyce mcintosh } 969cb174861Sjoyce mcintosh } 970cb174861Sjoyce mcintosh 971cb174861Sjoyce mcintosh /* 972cb174861Sjoyce mcintosh * smb_open_attr_only 973cb174861Sjoyce mcintosh * 974cb174861Sjoyce mcintosh * Determine if file is being opened for attribute access only. 975cb174861Sjoyce mcintosh * This is used to determine whether it is necessary to break 976cb174861Sjoyce mcintosh * existing oplocks on the file. 977cb174861Sjoyce mcintosh */ 978cb174861Sjoyce mcintosh static boolean_t 979cb174861Sjoyce mcintosh smb_open_attr_only(smb_arg_open_t *op) 980cb174861Sjoyce mcintosh { 981cb174861Sjoyce mcintosh if (((op->desired_access & ~(FILE_READ_ATTRIBUTES | 982fb699f1eSAlek Pinchuk FILE_WRITE_ATTRIBUTES | SYNCHRONIZE | READ_CONTROL)) == 0) && 983cb174861Sjoyce mcintosh (op->create_disposition != FILE_SUPERSEDE) && 984cb174861Sjoyce mcintosh (op->create_disposition != FILE_OVERWRITE)) { 985cb174861Sjoyce mcintosh return (B_TRUE); 986cb174861Sjoyce mcintosh } 987cb174861Sjoyce mcintosh return (B_FALSE); 988cb174861Sjoyce mcintosh } 989cb174861Sjoyce mcintosh 990cb174861Sjoyce mcintosh static boolean_t 991cb174861Sjoyce mcintosh smb_open_overwrite(smb_arg_open_t *op) 992cb174861Sjoyce mcintosh { 993cb174861Sjoyce mcintosh if ((op->create_disposition == FILE_SUPERSEDE) || 994cb174861Sjoyce mcintosh (op->create_disposition == FILE_OVERWRITE_IF) || 995cb174861Sjoyce mcintosh (op->create_disposition == FILE_OVERWRITE)) { 996cb174861Sjoyce mcintosh return (B_TRUE); 997cb174861Sjoyce mcintosh } 998cb174861Sjoyce mcintosh return (B_FALSE); 999cb174861Sjoyce mcintosh } 10005fd03bc0SGordon Ross 1001cb174861Sjoyce mcintosh /* 10025fd03bc0SGordon Ross * smb_set_open_attributes 1003037cac00Sjoyce mcintosh * 1004037cac00Sjoyce mcintosh * Last write time: 1005037cac00Sjoyce mcintosh * - If the last_write time specified in the open params is not 0 or -1, 1006037cac00Sjoyce mcintosh * use it as file's mtime. This will be considered an explicitly set 1007037cac00Sjoyce mcintosh * timestamps, not reset by subsequent writes. 1008037cac00Sjoyce mcintosh * 10095fd03bc0SGordon Ross * DOS attributes 10105fd03bc0SGordon Ross * - If we created_readonly, we now store the real DOS attributes 10115fd03bc0SGordon Ross * (including the readonly bit) so subsequent opens will see it. 1012037cac00Sjoyce mcintosh * 10135fd03bc0SGordon Ross * Both are stored "pending" rather than in the file system. 1014037cac00Sjoyce mcintosh * 1015037cac00Sjoyce mcintosh * Returns: errno 1016037cac00Sjoyce mcintosh */ 1017037cac00Sjoyce mcintosh static int 10185fd03bc0SGordon Ross smb_set_open_attributes(smb_request_t *sr, smb_ofile_t *of) 1019037cac00Sjoyce mcintosh { 10205fd03bc0SGordon Ross smb_attr_t attr; 1021148c5f43SAlan Wright smb_arg_open_t *op = &sr->sr_open; 1022037cac00Sjoyce mcintosh smb_node_t *node = of->f_node; 10235fd03bc0SGordon Ross int rc = 0; 1024037cac00Sjoyce mcintosh 1025037cac00Sjoyce mcintosh bzero(&attr, sizeof (smb_attr_t)); 10265fd03bc0SGordon Ross 10275fd03bc0SGordon Ross if (op->created_readonly) { 10285fd03bc0SGordon Ross attr.sa_dosattr = op->dattr | FILE_ATTRIBUTE_READONLY; 10295fd03bc0SGordon Ross attr.sa_mask |= SMB_AT_DOSATTR; 10305fd03bc0SGordon Ross } 1031037cac00Sjoyce mcintosh 1032037cac00Sjoyce mcintosh if ((op->mtime.tv_sec != 0) && (op->mtime.tv_sec != UINT_MAX)) { 1033037cac00Sjoyce mcintosh attr.sa_vattr.va_mtime = op->mtime; 10345fd03bc0SGordon Ross attr.sa_mask |= SMB_AT_MTIME; 1035037cac00Sjoyce mcintosh } 1036037cac00Sjoyce mcintosh 10375fd03bc0SGordon Ross /* 10385fd03bc0SGordon Ross * Used to have code here to set mtime, ctime, atime 10395fd03bc0SGordon Ross * when the open op->create_disposition is any of: 10405fd03bc0SGordon Ross * FILE_SUPERSEDE, FILE_OVERWRITE_IF, FILE_OVERWRITE. 10415fd03bc0SGordon Ross * We know that in those cases we will have set the 10425fd03bc0SGordon Ross * file size, in which case the file system will 10435fd03bc0SGordon Ross * update those times, so we don't have to. 10445fd03bc0SGordon Ross * 10455fd03bc0SGordon Ross * However, keep track of the fact that we modified 10465fd03bc0SGordon Ross * the file via this handle, so we can do the evil, 10475fd03bc0SGordon Ross * gratuitious mtime update on close that Windows 10485fd03bc0SGordon Ross * clients appear to expect. 10495fd03bc0SGordon Ross */ 10505fd03bc0SGordon Ross if (op->action_taken == SMB_OACT_TRUNCATED) 10515fd03bc0SGordon Ross of->f_written = B_TRUE; 1052037cac00Sjoyce mcintosh 10535fd03bc0SGordon Ross if (attr.sa_mask != 0) 10545fd03bc0SGordon Ross rc = smb_node_setattr(sr, node, of->f_cr, of, &attr); 1055037cac00Sjoyce mcintosh 1056037cac00Sjoyce mcintosh return (rc); 1057037cac00Sjoyce mcintosh } 1058037cac00Sjoyce mcintosh 1059037cac00Sjoyce mcintosh /* 10608b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * This function is used to delete a newly created object (file or 10618b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * directory) if an error occurs after creation of the object. 1062da6c28aaSamw */ 10638b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States static void 10648b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_delete_new_object(smb_request_t *sr) 1065da6c28aaSamw { 1066148c5f43SAlan Wright smb_arg_open_t *op = &sr->sr_open; 10678b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_fqi_t *fqi = &(op->fqi); 10688b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States uint32_t flags = 0; 10698b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 10708b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States if (SMB_TREE_IS_CASEINSENSITIVE(sr)) 10718b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States flags |= SMB_IGNORE_CASE; 10728b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States if (SMB_TREE_SUPPORTS_CATIA(sr)) 10738b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States flags |= SMB_CATIA; 10748b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 10758b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States if (op->create_options & FILE_DIRECTORY_FILE) 1076eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States (void) smb_fsop_rmdir(sr, sr->user_cr, fqi->fq_dnode, 1077eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States fqi->fq_last_comp, flags); 10788b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States else 1079eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States (void) smb_fsop_remove(sr, sr->user_cr, fqi->fq_dnode, 1080eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States fqi->fq_last_comp, flags); 1081eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States } 1082