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 */ 21da6c28aaSamw /* 22f96bd5c8SAlan Wright * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 23da6c28aaSamw * Use is subject to license terms. 24da6c28aaSamw */ 25da6c28aaSamw 26da6c28aaSamw /* 27da6c28aaSamw * General Structures Layout 28da6c28aaSamw * ------------------------- 29da6c28aaSamw * 30da6c28aaSamw * This is a simplified diagram showing the relationship between most of the 31da6c28aaSamw * main structures. 32da6c28aaSamw * 33da6c28aaSamw * +-------------------+ 34da6c28aaSamw * | SMB_INFO | 35da6c28aaSamw * +-------------------+ 36da6c28aaSamw * | 37da6c28aaSamw * | 38da6c28aaSamw * v 39da6c28aaSamw * +-------------------+ +-------------------+ +-------------------+ 40da6c28aaSamw * | SESSION |<----->| SESSION |......| SESSION | 41da6c28aaSamw * +-------------------+ +-------------------+ +-------------------+ 42da6c28aaSamw * | 43da6c28aaSamw * | 44da6c28aaSamw * v 45da6c28aaSamw * +-------------------+ +-------------------+ +-------------------+ 46da6c28aaSamw * | USER |<----->| USER |......| USER | 47da6c28aaSamw * +-------------------+ +-------------------+ +-------------------+ 48da6c28aaSamw * | 49da6c28aaSamw * | 50da6c28aaSamw * v 51da6c28aaSamw * +-------------------+ +-------------------+ +-------------------+ 52da6c28aaSamw * | TREE |<----->| TREE |......| TREE | 53da6c28aaSamw * +-------------------+ +-------------------+ +-------------------+ 54da6c28aaSamw * | | 55da6c28aaSamw * | | 56da6c28aaSamw * | v 57da6c28aaSamw * | +-------+ +-------+ +-------+ 58da6c28aaSamw * | | OFILE |<----->| OFILE |......| OFILE | 59da6c28aaSamw * | +-------+ +-------+ +-------+ 60da6c28aaSamw * | 61da6c28aaSamw * | 62da6c28aaSamw * v 63da6c28aaSamw * +-------+ +------+ +------+ 64da6c28aaSamw * | ODIR |<----->| ODIR |......| ODIR | 65da6c28aaSamw * +-------+ +------+ +------+ 66da6c28aaSamw * 67da6c28aaSamw * 68da6c28aaSamw * Ofile State Machine 69da6c28aaSamw * ------------------ 70da6c28aaSamw * 71da6c28aaSamw * +-------------------------+ T0 72da6c28aaSamw * | SMB_OFILE_STATE_OPEN |<----------- Creation/Allocation 73da6c28aaSamw * +-------------------------+ 74da6c28aaSamw * | 75da6c28aaSamw * | T1 76da6c28aaSamw * | 77da6c28aaSamw * v 78da6c28aaSamw * +-------------------------+ 79da6c28aaSamw * | SMB_OFILE_STATE_CLOSING | 80da6c28aaSamw * +-------------------------+ 81da6c28aaSamw * | 82da6c28aaSamw * | T2 83da6c28aaSamw * | 84da6c28aaSamw * v 85da6c28aaSamw * +-------------------------+ T3 86da6c28aaSamw * | SMB_OFILE_STATE_CLOSED |----------> Deletion/Free 87da6c28aaSamw * +-------------------------+ 88da6c28aaSamw * 89da6c28aaSamw * SMB_OFILE_STATE_OPEN 90da6c28aaSamw * 91da6c28aaSamw * While in this state: 92da6c28aaSamw * - The ofile is queued in the list of ofiles of its tree. 93da6c28aaSamw * - References will be given out if the ofile is looked up. 94da6c28aaSamw * 95da6c28aaSamw * SMB_OFILE_STATE_CLOSING 96da6c28aaSamw * 97da6c28aaSamw * While in this state: 98da6c28aaSamw * - The ofile is queued in the list of ofiles of its tree. 99da6c28aaSamw * - References will not be given out if the ofile is looked up. 100da6c28aaSamw * - The file is closed and the locks held are being released. 101da6c28aaSamw * - The resources associated with the ofile remain. 102da6c28aaSamw * 103da6c28aaSamw * SMB_OFILE_STATE_CLOSED 104da6c28aaSamw * 105da6c28aaSamw * While in this state: 106da6c28aaSamw * - The ofile is queued in the list of ofiles of its tree. 107da6c28aaSamw * - References will not be given out if the ofile is looked up. 108da6c28aaSamw * - The resources associated with the ofile remain. 109da6c28aaSamw * 110da6c28aaSamw * Transition T0 111da6c28aaSamw * 112da6c28aaSamw * This transition occurs in smb_ofile_open(). A new ofile is created and 113da6c28aaSamw * added to the list of ofiles of a tree. 114da6c28aaSamw * 115da6c28aaSamw * Transition T1 116da6c28aaSamw * 117da6c28aaSamw * This transition occurs in smb_ofile_close(). 118da6c28aaSamw * 119da6c28aaSamw * Transition T2 120da6c28aaSamw * 121da6c28aaSamw * This transition occurs in smb_ofile_release(). The resources associated 122da6c28aaSamw * with the ofile are freed as well as the ofile structure. For the 123da6c28aaSamw * transition to occur, the ofile must be in the SMB_OFILE_STATE_CLOSED 124da6c28aaSamw * state and the reference count be zero. 125da6c28aaSamw * 126da6c28aaSamw * Comments 127da6c28aaSamw * -------- 128da6c28aaSamw * 129da6c28aaSamw * The state machine of the ofile structures is controlled by 3 elements: 130da6c28aaSamw * - The list of ofiles of the tree it belongs to. 131da6c28aaSamw * - The mutex embedded in the structure itself. 132da6c28aaSamw * - The reference count. 133da6c28aaSamw * 134da6c28aaSamw * There's a mutex embedded in the ofile structure used to protect its fields 135da6c28aaSamw * and there's a lock embedded in the list of ofiles of a tree. To 136da6c28aaSamw * increment or to decrement the reference count the mutex must be entered. 137da6c28aaSamw * To insert the ofile into the list of ofiles of the tree and to remove 138da6c28aaSamw * the ofile from it, the lock must be entered in RW_WRITER mode. 139da6c28aaSamw * 140da6c28aaSamw * Rules of access to a ofile structure: 141da6c28aaSamw * 142da6c28aaSamw * 1) In order to avoid deadlocks, when both (mutex and lock of the ofile 143da6c28aaSamw * list) have to be entered, the lock must be entered first. 144da6c28aaSamw * 145da6c28aaSamw * 2) All actions applied to an ofile require a reference count. 146da6c28aaSamw * 147da6c28aaSamw * 3) There are 2 ways of getting a reference count. One is when the ofile 148da6c28aaSamw * is opened. The other one when the ofile is looked up. This translates 149da6c28aaSamw * into 2 functions: smb_ofile_open() and smb_ofile_lookup_by_fid(). 150da6c28aaSamw * 151da6c28aaSamw * It should be noted that the reference count of an ofile registers the 152da6c28aaSamw * number of references to the ofile in other structures (such as an smb 153da6c28aaSamw * request). The reference count is not incremented in these 2 instances: 154da6c28aaSamw * 155da6c28aaSamw * 1) The ofile is open. An ofile is anchored by his state. If there's 156da6c28aaSamw * no activity involving an ofile currently open, the reference count 157da6c28aaSamw * of that ofile is zero. 158da6c28aaSamw * 159da6c28aaSamw * 2) The ofile is queued in the list of ofiles of its tree. The fact of 160da6c28aaSamw * being queued in that list is NOT registered by incrementing the 161da6c28aaSamw * reference count. 162da6c28aaSamw */ 163da6c28aaSamw #include <smbsrv/smb_kproto.h> 164da6c28aaSamw #include <smbsrv/smb_fsops.h> 165da6c28aaSamw 1661fcced4cSJordan Brown static boolean_t smb_ofile_is_open_locked(smb_ofile_t *); 1671fcced4cSJordan Brown static smb_ofile_t *smb_ofile_close_and_next(smb_ofile_t *); 168037cac00Sjoyce mcintosh static void smb_ofile_set_close_attrs(smb_ofile_t *, uint32_t); 1691fcced4cSJordan Brown static int smb_ofile_netinfo_encode(smb_ofile_t *, uint8_t *, size_t, 1701fcced4cSJordan Brown uint32_t *); 1711fcced4cSJordan Brown static int smb_ofile_netinfo_init(smb_ofile_t *, smb_netfileinfo_t *); 1721fcced4cSJordan Brown static void smb_ofile_netinfo_fini(smb_netfileinfo_t *); 173da6c28aaSamw 174da6c28aaSamw /* 175da6c28aaSamw * smb_ofile_open 176da6c28aaSamw */ 177da6c28aaSamw smb_ofile_t * 178da6c28aaSamw smb_ofile_open( 179da6c28aaSamw smb_tree_t *tree, 180da6c28aaSamw smb_node_t *node, 181da6c28aaSamw uint16_t pid, 182c8ec8eeaSjose borrego struct open_param *op, 183da6c28aaSamw uint16_t ftype, 184dc20a302Sas200622 uint32_t uniqid, 185da6c28aaSamw smb_error_t *err) 186da6c28aaSamw { 187da6c28aaSamw smb_ofile_t *of; 188da6c28aaSamw uint16_t fid; 189037cac00Sjoyce mcintosh smb_attr_t attr; 190da6c28aaSamw 191da6c28aaSamw if (smb_idpool_alloc(&tree->t_fid_pool, &fid)) { 192da6c28aaSamw err->status = NT_STATUS_TOO_MANY_OPENED_FILES; 193da6c28aaSamw err->errcls = ERRDOS; 194da6c28aaSamw err->errcode = ERROR_TOO_MANY_OPEN_FILES; 195da6c28aaSamw return (NULL); 196da6c28aaSamw } 197da6c28aaSamw 198faa1795aSjb150015 of = kmem_cache_alloc(tree->t_server->si_cache_ofile, KM_SLEEP); 199da6c28aaSamw bzero(of, sizeof (smb_ofile_t)); 200da6c28aaSamw of->f_magic = SMB_OFILE_MAGIC; 201da6c28aaSamw of->f_refcnt = 1; 202da6c28aaSamw of->f_fid = fid; 203dc20a302Sas200622 of->f_uniqid = uniqid; 204da6c28aaSamw of->f_opened_by_pid = pid; 205c8ec8eeaSjose borrego of->f_granted_access = op->desired_access; 206c8ec8eeaSjose borrego of->f_share_access = op->share_access; 207c8ec8eeaSjose borrego of->f_create_options = op->create_options; 208b89a8333Snatalie li - Sun Microsystems - Irvine United States of->f_cr = (op->create_options & FILE_OPEN_FOR_BACKUP_INTENT) ? 209b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_user_getprivcred(tree->t_user) : tree->t_user->u_cred; 210da6c28aaSamw crhold(of->f_cr); 211da6c28aaSamw of->f_ftype = ftype; 212faa1795aSjb150015 of->f_server = tree->t_server; 213da6c28aaSamw of->f_session = tree->t_user->u_session; 214da6c28aaSamw of->f_user = tree->t_user; 215da6c28aaSamw of->f_tree = tree; 216da6c28aaSamw of->f_node = node; 217037cac00Sjoyce mcintosh of->f_explicit_times = 0; 218da6c28aaSamw mutex_init(&of->f_mutex, NULL, MUTEX_DEFAULT, NULL); 219da6c28aaSamw of->f_state = SMB_OFILE_STATE_OPEN; 220da6c28aaSamw 221037cac00Sjoyce mcintosh 222da6c28aaSamw if (ftype == SMB_FTYPE_MESG_PIPE) { 223*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States of->f_pipe = smb_opipe_alloc(tree->t_server); 224da6c28aaSamw } else { 225da6c28aaSamw ASSERT(ftype == SMB_FTYPE_DISK); /* Regular file, not a pipe */ 226da6c28aaSamw ASSERT(node); 2272c2961f8Sjose borrego 2282c2961f8Sjose borrego if (of->f_granted_access == FILE_EXECUTE) 2292c2961f8Sjose borrego of->f_flags |= SMB_OFLAGS_EXECONLY; 2302c2961f8Sjose borrego 231037cac00Sjoyce mcintosh bzero(&attr, sizeof (smb_attr_t)); 232037cac00Sjoyce mcintosh attr.sa_mask |= SMB_AT_UID; 233037cac00Sjoyce mcintosh if (smb_fsop_getattr(NULL, kcred, node, &attr) != 0) { 234037cac00Sjoyce mcintosh of->f_magic = 0; 235037cac00Sjoyce mcintosh mutex_destroy(&of->f_mutex); 236037cac00Sjoyce mcintosh crfree(of->f_cr); 237037cac00Sjoyce mcintosh smb_idpool_free(&tree->t_fid_pool, of->f_fid); 238037cac00Sjoyce mcintosh kmem_cache_free(tree->t_server->si_cache_ofile, of); 239037cac00Sjoyce mcintosh err->status = NT_STATUS_INTERNAL_ERROR; 240037cac00Sjoyce mcintosh err->errcls = ERRDOS; 241037cac00Sjoyce mcintosh err->errcode = ERROR_INTERNAL_ERROR; 242037cac00Sjoyce mcintosh return (NULL); 243037cac00Sjoyce mcintosh } 244037cac00Sjoyce mcintosh if (crgetuid(of->f_cr) == attr.sa_vattr.va_uid) { 245da6c28aaSamw /* 246da6c28aaSamw * Add this bit for the file's owner even if it's not 247da6c28aaSamw * specified in the request (Windows behavior). 248da6c28aaSamw */ 249da6c28aaSamw of->f_granted_access |= FILE_READ_ATTRIBUTES; 250da6c28aaSamw } 251da6c28aaSamw 252*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (smb_node_is_file(node)) { 2538c10a865Sas200622 of->f_mode = 2548c10a865Sas200622 smb_fsop_amask_to_omode(of->f_granted_access); 255c8ec8eeaSjose borrego if (smb_fsop_open(node, of->f_mode, of->f_cr) != 0) { 256da6c28aaSamw of->f_magic = 0; 257da6c28aaSamw mutex_destroy(&of->f_mutex); 258da6c28aaSamw crfree(of->f_cr); 259c8ec8eeaSjose borrego smb_idpool_free(&tree->t_fid_pool, of->f_fid); 2608c10a865Sas200622 kmem_cache_free(tree->t_server->si_cache_ofile, 2618c10a865Sas200622 of); 262da6c28aaSamw err->status = NT_STATUS_ACCESS_DENIED; 263da6c28aaSamw err->errcls = ERRDOS; 264da6c28aaSamw err->errcode = ERROR_ACCESS_DENIED; 265da6c28aaSamw return (NULL); 266da6c28aaSamw } 2678c10a865Sas200622 } 2688c10a865Sas200622 269c8ec8eeaSjose borrego if (tree->t_flags & SMB_TREE_READONLY) 270c8ec8eeaSjose borrego of->f_flags |= SMB_OFLAGS_READONLY; 271c8ec8eeaSjose borrego 272c8ec8eeaSjose borrego if (op->created_readonly) 273c8ec8eeaSjose borrego node->readonly_creator = of; 274c8ec8eeaSjose borrego 2752c2961f8Sjose borrego smb_node_inc_open_ofiles(node); 276fc724630SAlan Wright smb_node_add_ofile(node, of); 2778b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_node_ref(node); 278da6c28aaSamw } 279da6c28aaSamw smb_llist_enter(&tree->t_ofile_list, RW_WRITER); 280da6c28aaSamw smb_llist_insert_tail(&tree->t_ofile_list, of); 281da6c28aaSamw smb_llist_exit(&tree->t_ofile_list); 2821fcced4cSJordan Brown atomic_inc_32(&tree->t_open_files); 283faa1795aSjb150015 atomic_inc_32(&tree->t_server->sv_open_files); 284da6c28aaSamw atomic_inc_32(&of->f_session->s_file_cnt); 285da6c28aaSamw 286da6c28aaSamw return (of); 287da6c28aaSamw } 288da6c28aaSamw 289da6c28aaSamw /* 290da6c28aaSamw * smb_ofile_close 291da6c28aaSamw */ 292c8ec8eeaSjose borrego void 293037cac00Sjoyce mcintosh smb_ofile_close(smb_ofile_t *of, uint32_t last_wtime) 294da6c28aaSamw { 295da6c28aaSamw ASSERT(of); 296da6c28aaSamw ASSERT(of->f_magic == SMB_OFILE_MAGIC); 2978b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States uint32_t flags = 0; 298da6c28aaSamw 299da6c28aaSamw mutex_enter(&of->f_mutex); 300da6c28aaSamw ASSERT(of->f_refcnt); 301da6c28aaSamw switch (of->f_state) { 302da6c28aaSamw case SMB_OFILE_STATE_OPEN: { 303da6c28aaSamw 304da6c28aaSamw of->f_state = SMB_OFILE_STATE_CLOSING; 305da6c28aaSamw mutex_exit(&of->f_mutex); 306da6c28aaSamw 307da6c28aaSamw if (of->f_ftype == SMB_FTYPE_MESG_PIPE) { 3083db3f65cSamw smb_opipe_close(of); 309da6c28aaSamw } else { 310037cac00Sjoyce mcintosh smb_ofile_set_close_attrs(of, last_wtime); 311da6c28aaSamw 3128b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States if (of->f_flags & SMB_OFLAGS_SET_DELETE_ON_CLOSE) { 3138b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States if (smb_tree_has_feature(of->f_tree, 3148b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States SMB_TREE_CATIA)) { 3158b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States flags |= SMB_CATIA; 3168b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States } 3178b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States (void) smb_node_set_delete_on_close(of->f_node, 3188b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States of->f_cr, flags); 3198b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States } 320dc20a302Sas200622 smb_fsop_unshrlock(of->f_cr, of->f_node, of->f_uniqid); 3216537f381Sas200622 smb_node_destroy_lock_by_ofile(of->f_node, of); 322dc20a302Sas200622 323*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (smb_node_is_file(of->f_node)) 3248c10a865Sas200622 (void) smb_fsop_close(of->f_node, of->f_mode, 3258c10a865Sas200622 of->f_cr); 326dc20a302Sas200622 327dc20a302Sas200622 /* 328dc20a302Sas200622 * Cancel any notify change requests related 329dc20a302Sas200622 * to this open instance. 330da6c28aaSamw */ 331da6c28aaSamw if (of->f_node->flags & NODE_FLAGS_NOTIFY_CHANGE) 332da6c28aaSamw smb_process_file_notify_change_queue(of); 333da6c28aaSamw } 3341fcced4cSJordan Brown atomic_dec_32(&of->f_tree->t_open_files); 335faa1795aSjb150015 atomic_dec_32(&of->f_tree->t_server->sv_open_files); 336da6c28aaSamw 337da6c28aaSamw mutex_enter(&of->f_mutex); 338da6c28aaSamw ASSERT(of->f_refcnt); 339da6c28aaSamw ASSERT(of->f_state == SMB_OFILE_STATE_CLOSING); 340da6c28aaSamw of->f_state = SMB_OFILE_STATE_CLOSED; 34124d2db37Sjose borrego mutex_exit(&of->f_mutex); 342fc724630SAlan Wright if (of->f_node != NULL) { 3432c2961f8Sjose borrego smb_node_dec_open_ofiles(of->f_node); 344fc724630SAlan Wright if (of->f_oplock_granted) { 3452c2961f8Sjose borrego smb_oplock_release(of->f_node, of); 3462c2961f8Sjose borrego of->f_oplock_granted = B_FALSE; 3472c2961f8Sjose borrego } 348fc724630SAlan Wright } 349c8ec8eeaSjose borrego return; 350da6c28aaSamw } 351da6c28aaSamw case SMB_OFILE_STATE_CLOSED: 352da6c28aaSamw case SMB_OFILE_STATE_CLOSING: 353da6c28aaSamw break; 354da6c28aaSamw 355da6c28aaSamw default: 356da6c28aaSamw ASSERT(0); 357da6c28aaSamw break; 358da6c28aaSamw } 359da6c28aaSamw mutex_exit(&of->f_mutex); 360da6c28aaSamw } 361da6c28aaSamw 362da6c28aaSamw /* 363da6c28aaSamw * smb_ofile_close_all 364da6c28aaSamw * 365da6c28aaSamw * 366da6c28aaSamw */ 367da6c28aaSamw void 368da6c28aaSamw smb_ofile_close_all( 369da6c28aaSamw smb_tree_t *tree) 370da6c28aaSamw { 371da6c28aaSamw smb_ofile_t *of; 372da6c28aaSamw 373da6c28aaSamw ASSERT(tree); 374da6c28aaSamw ASSERT(tree->t_magic == SMB_TREE_MAGIC); 375da6c28aaSamw 376da6c28aaSamw smb_llist_enter(&tree->t_ofile_list, RW_READER); 377da6c28aaSamw of = smb_llist_head(&tree->t_ofile_list); 378da6c28aaSamw while (of) { 379da6c28aaSamw ASSERT(of->f_magic == SMB_OFILE_MAGIC); 380da6c28aaSamw ASSERT(of->f_tree == tree); 381da6c28aaSamw of = smb_ofile_close_and_next(of); 382da6c28aaSamw } 383da6c28aaSamw smb_llist_exit(&tree->t_ofile_list); 384da6c28aaSamw } 385da6c28aaSamw 386da6c28aaSamw /* 387da6c28aaSamw * smb_ofiles_close_by_pid 388da6c28aaSamw * 389da6c28aaSamw * 390da6c28aaSamw */ 391da6c28aaSamw void 392da6c28aaSamw smb_ofile_close_all_by_pid( 393da6c28aaSamw smb_tree_t *tree, 394da6c28aaSamw uint16_t pid) 395da6c28aaSamw { 396da6c28aaSamw smb_ofile_t *of; 397da6c28aaSamw 398da6c28aaSamw ASSERT(tree); 399da6c28aaSamw ASSERT(tree->t_magic == SMB_TREE_MAGIC); 400da6c28aaSamw 401da6c28aaSamw smb_llist_enter(&tree->t_ofile_list, RW_READER); 402da6c28aaSamw of = smb_llist_head(&tree->t_ofile_list); 403da6c28aaSamw while (of) { 404da6c28aaSamw ASSERT(of->f_magic == SMB_OFILE_MAGIC); 405da6c28aaSamw ASSERT(of->f_tree == tree); 406da6c28aaSamw if (of->f_opened_by_pid == pid) { 407da6c28aaSamw of = smb_ofile_close_and_next(of); 408da6c28aaSamw } else { 409da6c28aaSamw of = smb_llist_next(&tree->t_ofile_list, of); 410da6c28aaSamw } 411da6c28aaSamw } 412da6c28aaSamw smb_llist_exit(&tree->t_ofile_list); 413da6c28aaSamw } 414da6c28aaSamw 415da6c28aaSamw /* 4161fcced4cSJordan Brown * If the enumeration request is for ofile data, handle it here. 4171fcced4cSJordan Brown * Otherwise, return. 4181fcced4cSJordan Brown * 4191fcced4cSJordan Brown * This function should be called with a hold on the ofile. 4201fcced4cSJordan Brown */ 4211fcced4cSJordan Brown int 4221fcced4cSJordan Brown smb_ofile_enum(smb_ofile_t *of, smb_svcenum_t *svcenum) 4231fcced4cSJordan Brown { 4241fcced4cSJordan Brown uint8_t *pb; 4251fcced4cSJordan Brown uint_t nbytes; 4261fcced4cSJordan Brown int rc; 4271fcced4cSJordan Brown 4281fcced4cSJordan Brown ASSERT(of); 4291fcced4cSJordan Brown ASSERT(of->f_magic == SMB_OFILE_MAGIC); 4301fcced4cSJordan Brown ASSERT(of->f_refcnt); 4311fcced4cSJordan Brown 4321fcced4cSJordan Brown if (svcenum->se_type != SMB_SVCENUM_TYPE_FILE) 4331fcced4cSJordan Brown return (0); 4341fcced4cSJordan Brown 4351fcced4cSJordan Brown if (svcenum->se_nskip > 0) { 4361fcced4cSJordan Brown svcenum->se_nskip--; 4371fcced4cSJordan Brown return (0); 4381fcced4cSJordan Brown } 4391fcced4cSJordan Brown 4401fcced4cSJordan Brown if (svcenum->se_nitems >= svcenum->se_nlimit) { 4411fcced4cSJordan Brown svcenum->se_nitems = svcenum->se_nlimit; 4421fcced4cSJordan Brown return (0); 4431fcced4cSJordan Brown } 4441fcced4cSJordan Brown 4451fcced4cSJordan Brown pb = &svcenum->se_buf[svcenum->se_bused]; 4461fcced4cSJordan Brown 4471fcced4cSJordan Brown rc = smb_ofile_netinfo_encode(of, pb, svcenum->se_bavail, 4481fcced4cSJordan Brown &nbytes); 4491fcced4cSJordan Brown if (rc == 0) { 4501fcced4cSJordan Brown svcenum->se_bavail -= nbytes; 4511fcced4cSJordan Brown svcenum->se_bused += nbytes; 4521fcced4cSJordan Brown svcenum->se_nitems++; 4531fcced4cSJordan Brown } 4541fcced4cSJordan Brown 4551fcced4cSJordan Brown return (rc); 4561fcced4cSJordan Brown } 4571fcced4cSJordan Brown 4581fcced4cSJordan Brown /* 4591fcced4cSJordan Brown * Take a reference on an open file. 4601fcced4cSJordan Brown */ 4611fcced4cSJordan Brown boolean_t 4621fcced4cSJordan Brown smb_ofile_hold(smb_ofile_t *of) 4631fcced4cSJordan Brown { 4641fcced4cSJordan Brown ASSERT(of); 4651fcced4cSJordan Brown ASSERT(of->f_magic == SMB_OFILE_MAGIC); 4661fcced4cSJordan Brown 4671fcced4cSJordan Brown mutex_enter(&of->f_mutex); 4681fcced4cSJordan Brown 4691fcced4cSJordan Brown if (smb_ofile_is_open_locked(of)) { 4701fcced4cSJordan Brown of->f_refcnt++; 4711fcced4cSJordan Brown mutex_exit(&of->f_mutex); 4721fcced4cSJordan Brown return (B_TRUE); 4731fcced4cSJordan Brown } 4741fcced4cSJordan Brown 4751fcced4cSJordan Brown mutex_exit(&of->f_mutex); 4761fcced4cSJordan Brown return (B_FALSE); 4771fcced4cSJordan Brown } 4781fcced4cSJordan Brown 4791fcced4cSJordan Brown /* 480*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Release a reference on a file. If the reference count falls to 481*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * zero and the file has been closed, post the object for deletion. 482*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Object deletion is deferred to avoid modifying a list while an 483*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * iteration may be in progress. 484da6c28aaSamw */ 485da6c28aaSamw void 48624d2db37Sjose borrego smb_ofile_release(smb_ofile_t *of) 487da6c28aaSamw { 48824d2db37Sjose borrego boolean_t rb; 48924d2db37Sjose borrego 490*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_OFILE_VALID(of); 491da6c28aaSamw 492da6c28aaSamw mutex_enter(&of->f_mutex); 49324d2db37Sjose borrego if (of->f_oplock_exit) { 49424d2db37Sjose borrego mutex_exit(&of->f_mutex); 49524d2db37Sjose borrego rb = smb_oplock_broadcast(of->f_node); 49624d2db37Sjose borrego mutex_enter(&of->f_mutex); 49724d2db37Sjose borrego if (rb) 4982c2961f8Sjose borrego of->f_oplock_exit = B_FALSE; 49924d2db37Sjose borrego } 500da6c28aaSamw ASSERT(of->f_refcnt); 501da6c28aaSamw of->f_refcnt--; 502da6c28aaSamw switch (of->f_state) { 503da6c28aaSamw case SMB_OFILE_STATE_OPEN: 504da6c28aaSamw case SMB_OFILE_STATE_CLOSING: 505da6c28aaSamw break; 506da6c28aaSamw 507da6c28aaSamw case SMB_OFILE_STATE_CLOSED: 508*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (of->f_refcnt == 0) 509*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_tree_post_ofile(of->f_tree, of); 510da6c28aaSamw break; 511da6c28aaSamw 512da6c28aaSamw default: 513da6c28aaSamw ASSERT(0); 514da6c28aaSamw break; 515da6c28aaSamw } 516da6c28aaSamw mutex_exit(&of->f_mutex); 517da6c28aaSamw } 518da6c28aaSamw 519da6c28aaSamw /* 520da6c28aaSamw * smb_ofile_lookup_by_fid 521da6c28aaSamw * 522da6c28aaSamw * Find the open file whose fid matches the one specified in the request. 523da6c28aaSamw * If we can't find the fid or the shares (trees) don't match, we have a 524da6c28aaSamw * bad fid. 525da6c28aaSamw */ 526da6c28aaSamw smb_ofile_t * 527da6c28aaSamw smb_ofile_lookup_by_fid( 528da6c28aaSamw smb_tree_t *tree, 529da6c28aaSamw uint16_t fid) 530da6c28aaSamw { 531da6c28aaSamw smb_llist_t *of_list; 532da6c28aaSamw smb_ofile_t *of; 533da6c28aaSamw 534da6c28aaSamw ASSERT(tree->t_magic == SMB_TREE_MAGIC); 535da6c28aaSamw 536da6c28aaSamw of_list = &tree->t_ofile_list; 537da6c28aaSamw 538da6c28aaSamw smb_llist_enter(of_list, RW_READER); 539da6c28aaSamw of = smb_llist_head(of_list); 540da6c28aaSamw while (of) { 541da6c28aaSamw ASSERT(of->f_magic == SMB_OFILE_MAGIC); 542da6c28aaSamw ASSERT(of->f_tree == tree); 543da6c28aaSamw if (of->f_fid == fid) { 544da6c28aaSamw mutex_enter(&of->f_mutex); 545da6c28aaSamw if (of->f_state != SMB_OFILE_STATE_OPEN) { 546da6c28aaSamw mutex_exit(&of->f_mutex); 547da6c28aaSamw smb_llist_exit(of_list); 548da6c28aaSamw return (NULL); 549da6c28aaSamw } 550da6c28aaSamw of->f_refcnt++; 551da6c28aaSamw mutex_exit(&of->f_mutex); 552da6c28aaSamw break; 553da6c28aaSamw } 554da6c28aaSamw of = smb_llist_next(of_list, of); 555da6c28aaSamw } 556da6c28aaSamw smb_llist_exit(of_list); 557da6c28aaSamw return (of); 558da6c28aaSamw } 559da6c28aaSamw 560da6c28aaSamw /* 5611fcced4cSJordan Brown * smb_ofile_lookup_by_uniqid 5621fcced4cSJordan Brown * 5631fcced4cSJordan Brown * Find the open file whose uniqid matches the one specified in the request. 5641fcced4cSJordan Brown */ 5651fcced4cSJordan Brown smb_ofile_t * 5661fcced4cSJordan Brown smb_ofile_lookup_by_uniqid(smb_tree_t *tree, uint32_t uniqid) 5671fcced4cSJordan Brown { 5681fcced4cSJordan Brown smb_llist_t *of_list; 5691fcced4cSJordan Brown smb_ofile_t *of; 5701fcced4cSJordan Brown 5711fcced4cSJordan Brown ASSERT(tree->t_magic == SMB_TREE_MAGIC); 5721fcced4cSJordan Brown 5731fcced4cSJordan Brown of_list = &tree->t_ofile_list; 5741fcced4cSJordan Brown smb_llist_enter(of_list, RW_READER); 5751fcced4cSJordan Brown of = smb_llist_head(of_list); 5761fcced4cSJordan Brown 5771fcced4cSJordan Brown while (of) { 5781fcced4cSJordan Brown ASSERT(of->f_magic == SMB_OFILE_MAGIC); 5791fcced4cSJordan Brown ASSERT(of->f_tree == tree); 5801fcced4cSJordan Brown 5811fcced4cSJordan Brown if (of->f_uniqid == uniqid) { 5821fcced4cSJordan Brown if (smb_ofile_hold(of)) { 5831fcced4cSJordan Brown smb_llist_exit(of_list); 5841fcced4cSJordan Brown return (of); 5851fcced4cSJordan Brown } 5861fcced4cSJordan Brown } 5871fcced4cSJordan Brown 5881fcced4cSJordan Brown of = smb_llist_next(of_list, of); 5891fcced4cSJordan Brown } 5901fcced4cSJordan Brown 5911fcced4cSJordan Brown smb_llist_exit(of_list); 5921fcced4cSJordan Brown return (NULL); 5931fcced4cSJordan Brown } 5941fcced4cSJordan Brown 5951fcced4cSJordan Brown /* 5961fcced4cSJordan Brown * Disallow NetFileClose on certain ofiles to avoid side-effects. 5971fcced4cSJordan Brown * Closing a tree root is not allowed: use NetSessionDel or NetShareDel. 5981fcced4cSJordan Brown * Closing SRVSVC connections is not allowed because this NetFileClose 5991fcced4cSJordan Brown * request may depend on this ofile. 6001fcced4cSJordan Brown */ 6011fcced4cSJordan Brown boolean_t 6021fcced4cSJordan Brown smb_ofile_disallow_fclose(smb_ofile_t *of) 6031fcced4cSJordan Brown { 6041fcced4cSJordan Brown ASSERT(of); 6051fcced4cSJordan Brown ASSERT(of->f_magic == SMB_OFILE_MAGIC); 6061fcced4cSJordan Brown ASSERT(of->f_refcnt); 6071fcced4cSJordan Brown 6081fcced4cSJordan Brown switch (of->f_ftype) { 6091fcced4cSJordan Brown case SMB_FTYPE_DISK: 6101fcced4cSJordan Brown ASSERT(of->f_tree); 6111fcced4cSJordan Brown return (of->f_node == of->f_tree->t_snode); 6121fcced4cSJordan Brown 6131fcced4cSJordan Brown case SMB_FTYPE_MESG_PIPE: 6141fcced4cSJordan Brown ASSERT(of->f_pipe); 615bbf6f00cSJordan Brown if (smb_strcasecmp(of->f_pipe->p_name, "SRVSVC", 0) == 0) 6161fcced4cSJordan Brown return (B_TRUE); 6171fcced4cSJordan Brown break; 6181fcced4cSJordan Brown default: 6191fcced4cSJordan Brown break; 6201fcced4cSJordan Brown } 6211fcced4cSJordan Brown 6221fcced4cSJordan Brown return (B_FALSE); 6231fcced4cSJordan Brown } 6241fcced4cSJordan Brown 6251fcced4cSJordan Brown /* 626da6c28aaSamw * smb_ofile_set_flags 627da6c28aaSamw * 628da6c28aaSamw * Return value: 629da6c28aaSamw * 630da6c28aaSamw * Current flags value 631da6c28aaSamw * 632da6c28aaSamw */ 633da6c28aaSamw void 634da6c28aaSamw smb_ofile_set_flags( 635da6c28aaSamw smb_ofile_t *of, 636da6c28aaSamw uint32_t flags) 637da6c28aaSamw { 638da6c28aaSamw ASSERT(of); 639da6c28aaSamw ASSERT(of->f_magic == SMB_OFILE_MAGIC); 640da6c28aaSamw ASSERT(of->f_refcnt); 641da6c28aaSamw 642da6c28aaSamw mutex_enter(&of->f_mutex); 643da6c28aaSamw of->f_flags |= flags; 644da6c28aaSamw mutex_exit(&of->f_mutex); 645da6c28aaSamw } 646f96bd5c8SAlan Wright 647da6c28aaSamw /* 648da6c28aaSamw * smb_ofile_seek 649da6c28aaSamw * 650da6c28aaSamw * Return value: 651da6c28aaSamw * 652da6c28aaSamw * 0 Success 653da6c28aaSamw * EINVAL Unknown mode 654da6c28aaSamw * EOVERFLOW offset too big 655da6c28aaSamw * 656da6c28aaSamw */ 657da6c28aaSamw int 658da6c28aaSamw smb_ofile_seek( 659da6c28aaSamw smb_ofile_t *of, 660da6c28aaSamw ushort_t mode, 661da6c28aaSamw int32_t off, 662da6c28aaSamw uint32_t *retoff) 663da6c28aaSamw { 66455bf511dSas200622 u_offset_t newoff = 0; 665da6c28aaSamw int rc = 0; 666037cac00Sjoyce mcintosh smb_attr_t attr; 667da6c28aaSamw 668da6c28aaSamw ASSERT(of); 669da6c28aaSamw ASSERT(of->f_magic == SMB_OFILE_MAGIC); 670da6c28aaSamw ASSERT(of->f_refcnt); 671da6c28aaSamw 672da6c28aaSamw mutex_enter(&of->f_mutex); 673da6c28aaSamw switch (mode) { 674da6c28aaSamw case SMB_SEEK_SET: 675da6c28aaSamw if (off < 0) 676da6c28aaSamw newoff = 0; 677da6c28aaSamw else 67855bf511dSas200622 newoff = (u_offset_t)off; 679da6c28aaSamw break; 680da6c28aaSamw 681da6c28aaSamw case SMB_SEEK_CUR: 682da6c28aaSamw if (off < 0 && (-off) > of->f_seek_pos) 683da6c28aaSamw newoff = 0; 684da6c28aaSamw else 68555bf511dSas200622 newoff = of->f_seek_pos + (u_offset_t)off; 686da6c28aaSamw break; 687da6c28aaSamw 688da6c28aaSamw case SMB_SEEK_END: 689037cac00Sjoyce mcintosh bzero(&attr, sizeof (smb_attr_t)); 690037cac00Sjoyce mcintosh attr.sa_mask |= SMB_AT_SIZE; 691037cac00Sjoyce mcintosh rc = smb_fsop_getattr(NULL, kcred, of->f_node, &attr); 692037cac00Sjoyce mcintosh if (rc != 0) { 693037cac00Sjoyce mcintosh mutex_exit(&of->f_mutex); 694037cac00Sjoyce mcintosh return (rc); 695037cac00Sjoyce mcintosh } 696037cac00Sjoyce mcintosh if (off < 0 && (-off) > attr.sa_vattr.va_size) 697da6c28aaSamw newoff = 0; 698da6c28aaSamw else 699037cac00Sjoyce mcintosh newoff = attr.sa_vattr.va_size + (u_offset_t)off; 700da6c28aaSamw break; 701da6c28aaSamw 702da6c28aaSamw default: 703da6c28aaSamw mutex_exit(&of->f_mutex); 704da6c28aaSamw return (EINVAL); 705da6c28aaSamw } 706da6c28aaSamw 70755bf511dSas200622 /* 70855bf511dSas200622 * See comments at the beginning of smb_seek.c. 70955bf511dSas200622 * If the offset is greater than UINT_MAX, we will return an error. 71055bf511dSas200622 */ 71155bf511dSas200622 71255bf511dSas200622 if (newoff > UINT_MAX) { 713da6c28aaSamw rc = EOVERFLOW; 714da6c28aaSamw } else { 715da6c28aaSamw of->f_seek_pos = newoff; 716da6c28aaSamw *retoff = (uint32_t)newoff; 717da6c28aaSamw } 718da6c28aaSamw mutex_exit(&of->f_mutex); 719da6c28aaSamw return (rc); 720da6c28aaSamw } 721da6c28aaSamw 722da6c28aaSamw /* 723da6c28aaSamw * smb_ofile_is_open 724da6c28aaSamw */ 725da6c28aaSamw boolean_t 7262c2961f8Sjose borrego smb_ofile_is_open(smb_ofile_t *of) 727da6c28aaSamw { 7281fcced4cSJordan Brown boolean_t rc; 729da6c28aaSamw 7302c2961f8Sjose borrego SMB_OFILE_VALID(of); 731da6c28aaSamw 732da6c28aaSamw mutex_enter(&of->f_mutex); 7331fcced4cSJordan Brown rc = smb_ofile_is_open_locked(of); 734da6c28aaSamw mutex_exit(&of->f_mutex); 735da6c28aaSamw return (rc); 736da6c28aaSamw } 737da6c28aaSamw 7382c2961f8Sjose borrego void 7392c2961f8Sjose borrego smb_ofile_set_oplock_granted(smb_ofile_t *of) 7402c2961f8Sjose borrego { 7412c2961f8Sjose borrego SMB_OFILE_VALID(of); 7422c2961f8Sjose borrego mutex_enter(&of->f_mutex); 7432c2961f8Sjose borrego ASSERT(!of->f_oplock_granted); 7442c2961f8Sjose borrego of->f_oplock_granted = B_TRUE; 7452c2961f8Sjose borrego of->f_oplock_exit = B_TRUE; 7462c2961f8Sjose borrego mutex_exit(&of->f_mutex); 7472c2961f8Sjose borrego } 7482c2961f8Sjose borrego 749037cac00Sjoyce mcintosh /* 750037cac00Sjoyce mcintosh * smb_ofile_pending_write_time 751037cac00Sjoyce mcintosh * 752037cac00Sjoyce mcintosh * Flag write times as pending - to be set on close, setattr 753037cac00Sjoyce mcintosh * or delayed write timer. 754037cac00Sjoyce mcintosh */ 755037cac00Sjoyce mcintosh void 756037cac00Sjoyce mcintosh smb_ofile_set_write_time_pending(smb_ofile_t *of) 757037cac00Sjoyce mcintosh { 758037cac00Sjoyce mcintosh SMB_OFILE_VALID(of); 759037cac00Sjoyce mcintosh mutex_enter(&of->f_mutex); 760037cac00Sjoyce mcintosh of->f_flags |= SMB_OFLAGS_TIMESTAMPS_PENDING; 761037cac00Sjoyce mcintosh mutex_exit(&of->f_mutex); 762037cac00Sjoyce mcintosh } 763037cac00Sjoyce mcintosh 764e3f2c991SKeyur Desai /* 765e3f2c991SKeyur Desai * smb_ofile_write_time_pending 766e3f2c991SKeyur Desai * 767e3f2c991SKeyur Desai * Get and reset the write times pending flag. 768e3f2c991SKeyur Desai */ 769037cac00Sjoyce mcintosh boolean_t 770037cac00Sjoyce mcintosh smb_ofile_write_time_pending(smb_ofile_t *of) 771037cac00Sjoyce mcintosh { 772037cac00Sjoyce mcintosh boolean_t rc = B_FALSE; 773037cac00Sjoyce mcintosh 774037cac00Sjoyce mcintosh SMB_OFILE_VALID(of); 775037cac00Sjoyce mcintosh mutex_enter(&of->f_mutex); 776e3f2c991SKeyur Desai if (of->f_flags & SMB_OFLAGS_TIMESTAMPS_PENDING) { 777037cac00Sjoyce mcintosh rc = B_TRUE; 778e3f2c991SKeyur Desai of->f_flags &= ~SMB_OFLAGS_TIMESTAMPS_PENDING; 779e3f2c991SKeyur Desai } 780037cac00Sjoyce mcintosh mutex_exit(&of->f_mutex); 781037cac00Sjoyce mcintosh 782037cac00Sjoyce mcintosh return (rc); 783037cac00Sjoyce mcintosh } 784037cac00Sjoyce mcintosh 785037cac00Sjoyce mcintosh /* 786037cac00Sjoyce mcintosh * smb_ofile_set_explicit_time_flag 787037cac00Sjoyce mcintosh * 788037cac00Sjoyce mcintosh * Note the timestamps specified in "what", as having been 789e3f2c991SKeyur Desai * explicity set for the ofile. 790037cac00Sjoyce mcintosh */ 791037cac00Sjoyce mcintosh void 792037cac00Sjoyce mcintosh smb_ofile_set_explicit_times(smb_ofile_t *of, uint32_t what) 793037cac00Sjoyce mcintosh { 794037cac00Sjoyce mcintosh SMB_OFILE_VALID(of); 795037cac00Sjoyce mcintosh mutex_enter(&of->f_mutex); 796037cac00Sjoyce mcintosh of->f_explicit_times |= (what & SMB_AT_TIMES); 797037cac00Sjoyce mcintosh mutex_exit(&of->f_mutex); 798037cac00Sjoyce mcintosh } 799037cac00Sjoyce mcintosh 800037cac00Sjoyce mcintosh uint32_t 801037cac00Sjoyce mcintosh smb_ofile_explicit_times(smb_ofile_t *of) 802037cac00Sjoyce mcintosh { 803037cac00Sjoyce mcintosh uint32_t rc; 804037cac00Sjoyce mcintosh 805037cac00Sjoyce mcintosh SMB_OFILE_VALID(of); 806037cac00Sjoyce mcintosh mutex_enter(&of->f_mutex); 807037cac00Sjoyce mcintosh rc = of->f_explicit_times; 808037cac00Sjoyce mcintosh mutex_exit(&of->f_mutex); 809037cac00Sjoyce mcintosh 810037cac00Sjoyce mcintosh return (rc); 811037cac00Sjoyce mcintosh } 812037cac00Sjoyce mcintosh 813da6c28aaSamw /* *************************** Static Functions ***************************** */ 814da6c28aaSamw 815da6c28aaSamw /* 8161fcced4cSJordan Brown * Determine whether or not an ofile is open. 8171fcced4cSJordan Brown * This function must be called with the mutex held. 8181fcced4cSJordan Brown */ 8191fcced4cSJordan Brown static boolean_t 8201fcced4cSJordan Brown smb_ofile_is_open_locked(smb_ofile_t *of) 8211fcced4cSJordan Brown { 8221fcced4cSJordan Brown switch (of->f_state) { 8231fcced4cSJordan Brown case SMB_OFILE_STATE_OPEN: 8241fcced4cSJordan Brown return (B_TRUE); 8251fcced4cSJordan Brown 8261fcced4cSJordan Brown case SMB_OFILE_STATE_CLOSING: 8271fcced4cSJordan Brown case SMB_OFILE_STATE_CLOSED: 8281fcced4cSJordan Brown return (B_FALSE); 8291fcced4cSJordan Brown 8301fcced4cSJordan Brown default: 8311fcced4cSJordan Brown ASSERT(0); 8321fcced4cSJordan Brown return (B_FALSE); 8331fcced4cSJordan Brown } 8341fcced4cSJordan Brown } 8351fcced4cSJordan Brown 8361fcced4cSJordan Brown /* 837037cac00Sjoyce mcintosh * smb_ofile_set_close_attrs 838037cac00Sjoyce mcintosh * 839037cac00Sjoyce mcintosh * Updates timestamps, size and readonly bit. 840037cac00Sjoyce mcintosh * The last_wtime is specified in the request received 841037cac00Sjoyce mcintosh * from the client. If it is neither 0 nor -1, this time 842037cac00Sjoyce mcintosh * should be used as the file's mtime. It must first be 843037cac00Sjoyce mcintosh * converted from the server's localtime (as received in 844037cac00Sjoyce mcintosh * the client's request) to GMT. 845037cac00Sjoyce mcintosh * 846037cac00Sjoyce mcintosh * Call smb_node_setattr even if no attributes are being 847037cac00Sjoyce mcintosh * explicitly set, to set any pending attributes. 848037cac00Sjoyce mcintosh */ 849037cac00Sjoyce mcintosh static void 850037cac00Sjoyce mcintosh smb_ofile_set_close_attrs(smb_ofile_t *of, uint32_t last_wtime) 851037cac00Sjoyce mcintosh { 852037cac00Sjoyce mcintosh smb_node_t *node = of->f_node; 853037cac00Sjoyce mcintosh smb_attr_t attr; 854037cac00Sjoyce mcintosh 855037cac00Sjoyce mcintosh bzero(&attr, sizeof (smb_attr_t)); 856037cac00Sjoyce mcintosh 857037cac00Sjoyce mcintosh /* For files created readonly, propagate readonly bit */ 858037cac00Sjoyce mcintosh if (node->readonly_creator == of) { 859037cac00Sjoyce mcintosh attr.sa_mask |= SMB_AT_DOSATTR; 860037cac00Sjoyce mcintosh if (smb_fsop_getattr(NULL, kcred, node, &attr) && 861037cac00Sjoyce mcintosh (attr.sa_dosattr & FILE_ATTRIBUTE_READONLY)) { 862037cac00Sjoyce mcintosh attr.sa_mask = 0; 863037cac00Sjoyce mcintosh } else { 864037cac00Sjoyce mcintosh attr.sa_dosattr |= FILE_ATTRIBUTE_READONLY; 865037cac00Sjoyce mcintosh } 866037cac00Sjoyce mcintosh 867037cac00Sjoyce mcintosh node->readonly_creator = NULL; 868037cac00Sjoyce mcintosh } 869037cac00Sjoyce mcintosh 870037cac00Sjoyce mcintosh /* apply last_wtime if specified */ 871037cac00Sjoyce mcintosh if (last_wtime != 0 && last_wtime != 0xFFFFFFFF) { 872037cac00Sjoyce mcintosh attr.sa_vattr.va_mtime.tv_sec = 873037cac00Sjoyce mcintosh last_wtime + of->f_server->si_gmtoff; 874037cac00Sjoyce mcintosh attr.sa_mask |= SMB_AT_MTIME; 875037cac00Sjoyce mcintosh } 876037cac00Sjoyce mcintosh 877037cac00Sjoyce mcintosh (void) smb_node_setattr(NULL, node, of->f_cr, of, &attr); 878037cac00Sjoyce mcintosh } 879037cac00Sjoyce mcintosh 880037cac00Sjoyce mcintosh /* 881da6c28aaSamw * This function closes the file passed in (if appropriate) and returns the 882da6c28aaSamw * next open file in the list of open files of the tree of the open file passed 883da6c28aaSamw * in. It requires that the list of open files of the tree be entered in 884da6c28aaSamw * RW_READER mode before being called. 885da6c28aaSamw */ 886da6c28aaSamw static smb_ofile_t * 887037cac00Sjoyce mcintosh smb_ofile_close_and_next(smb_ofile_t *of) 888da6c28aaSamw { 889da6c28aaSamw smb_ofile_t *next_of; 890da6c28aaSamw smb_tree_t *tree; 891da6c28aaSamw 892da6c28aaSamw ASSERT(of); 893da6c28aaSamw ASSERT(of->f_magic == SMB_OFILE_MAGIC); 894da6c28aaSamw 895da6c28aaSamw mutex_enter(&of->f_mutex); 896da6c28aaSamw switch (of->f_state) { 897da6c28aaSamw case SMB_OFILE_STATE_OPEN: 898da6c28aaSamw /* The file is still open. */ 899da6c28aaSamw of->f_refcnt++; 900da6c28aaSamw ASSERT(of->f_refcnt); 901da6c28aaSamw tree = of->f_tree; 902da6c28aaSamw mutex_exit(&of->f_mutex); 903da6c28aaSamw smb_llist_exit(&of->f_tree->t_ofile_list); 904c8ec8eeaSjose borrego smb_ofile_close(of, 0); 905da6c28aaSamw smb_ofile_release(of); 906da6c28aaSamw smb_llist_enter(&tree->t_ofile_list, RW_READER); 907da6c28aaSamw next_of = smb_llist_head(&tree->t_ofile_list); 908da6c28aaSamw break; 909da6c28aaSamw case SMB_OFILE_STATE_CLOSING: 910da6c28aaSamw case SMB_OFILE_STATE_CLOSED: 911da6c28aaSamw /* 912da6c28aaSamw * The ofile exists but is closed or 913da6c28aaSamw * in the process being closed. 914da6c28aaSamw */ 915da6c28aaSamw mutex_exit(&of->f_mutex); 916da6c28aaSamw next_of = smb_llist_next(&of->f_tree->t_ofile_list, of); 917da6c28aaSamw break; 918da6c28aaSamw default: 919da6c28aaSamw ASSERT(0); 920da6c28aaSamw mutex_exit(&of->f_mutex); 921da6c28aaSamw next_of = smb_llist_next(&of->f_tree->t_ofile_list, of); 922da6c28aaSamw break; 923da6c28aaSamw } 924da6c28aaSamw return (next_of); 925da6c28aaSamw } 926da6c28aaSamw 927da6c28aaSamw /* 928*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Delete an ofile. 929da6c28aaSamw * 930*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Remove the ofile from the tree list before freeing resources 931*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * associated with the odir. 932da6c28aaSamw */ 933*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void 934*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_ofile_delete(void *arg) 935da6c28aaSamw { 936*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_tree_t *tree; 937*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_ofile_t *of = (smb_ofile_t *)arg; 938*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 939*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_OFILE_VALID(of); 940da6c28aaSamw ASSERT(of->f_refcnt == 0); 941da6c28aaSamw ASSERT(of->f_state == SMB_OFILE_STATE_CLOSED); 942da6c28aaSamw 943*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States tree = of->f_tree; 944*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_enter(&tree->t_ofile_list, RW_WRITER); 945*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_remove(&tree->t_ofile_list, of); 946*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idpool_free(&tree->t_fid_pool, of->f_fid); 947*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States atomic_dec_32(&tree->t_session->s_file_cnt); 948*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_exit(&tree->t_ofile_list); 949*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 950*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&of->f_mutex); 951*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&of->f_mutex); 952da6c28aaSamw 953da6c28aaSamw if (of->f_ftype == SMB_FTYPE_MESG_PIPE) { 954*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_opipe_dealloc(of->f_pipe); 9553db3f65cSamw of->f_pipe = NULL; 956da6c28aaSamw } else { 957da6c28aaSamw ASSERT(of->f_ftype == SMB_FTYPE_DISK); 958da6c28aaSamw ASSERT(of->f_node != NULL); 9592c2961f8Sjose borrego smb_node_rem_ofile(of->f_node, of); 960da6c28aaSamw smb_node_release(of->f_node); 961da6c28aaSamw } 962da6c28aaSamw 963da6c28aaSamw of->f_magic = (uint32_t)~SMB_OFILE_MAGIC; 964da6c28aaSamw mutex_destroy(&of->f_mutex); 965da6c28aaSamw crfree(of->f_cr); 966faa1795aSjb150015 kmem_cache_free(of->f_tree->t_server->si_cache_ofile, of); 967da6c28aaSamw } 968da6c28aaSamw 969da6c28aaSamw /* 970da6c28aaSamw * smb_ofile_access 971da6c28aaSamw * 972da6c28aaSamw * This function will check to see if the access requested is granted. 973da6c28aaSamw * Returns NT status codes. 974da6c28aaSamw */ 975da6c28aaSamw uint32_t 976da6c28aaSamw smb_ofile_access(smb_ofile_t *of, cred_t *cr, uint32_t access) 977da6c28aaSamw { 978da6c28aaSamw 979da6c28aaSamw if ((of == NULL) || (cr == kcred)) 980da6c28aaSamw return (NT_STATUS_SUCCESS); 981da6c28aaSamw 982da6c28aaSamw /* 983da6c28aaSamw * If the request is for something 984da6c28aaSamw * I don't grant it is an error 985da6c28aaSamw */ 986da6c28aaSamw if (~(of->f_granted_access) & access) { 987da6c28aaSamw if (!(of->f_granted_access & ACCESS_SYSTEM_SECURITY) && 988da6c28aaSamw (access & ACCESS_SYSTEM_SECURITY)) { 989da6c28aaSamw return (NT_STATUS_PRIVILEGE_NOT_HELD); 990da6c28aaSamw } 991da6c28aaSamw return (NT_STATUS_ACCESS_DENIED); 992da6c28aaSamw } 993da6c28aaSamw 994da6c28aaSamw return (NT_STATUS_SUCCESS); 995da6c28aaSamw } 9963ad684d6Sjb150015 9973ad684d6Sjb150015 9983ad684d6Sjb150015 /* 9993ad684d6Sjb150015 * check file sharing rules for current open request 10003ad684d6Sjb150015 * against existing open instances of the same file 10013ad684d6Sjb150015 * 10023ad684d6Sjb150015 * Returns NT_STATUS_SHARING_VIOLATION if there is any 10033ad684d6Sjb150015 * sharing conflict, otherwise returns NT_STATUS_SUCCESS. 10043ad684d6Sjb150015 */ 10053ad684d6Sjb150015 uint32_t 1006*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_ofile_open_check(smb_ofile_t *of, uint32_t desired_access, 10073ad684d6Sjb150015 uint32_t share_access) 10083ad684d6Sjb150015 { 10093ad684d6Sjb150015 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 10103ad684d6Sjb150015 10113ad684d6Sjb150015 mutex_enter(&of->f_mutex); 10123ad684d6Sjb150015 10133ad684d6Sjb150015 if (of->f_state != SMB_OFILE_STATE_OPEN) { 10143ad684d6Sjb150015 mutex_exit(&of->f_mutex); 10153ad684d6Sjb150015 return (NT_STATUS_INVALID_HANDLE); 10163ad684d6Sjb150015 } 10173ad684d6Sjb150015 10183ad684d6Sjb150015 /* if it's just meta data */ 10193ad684d6Sjb150015 if ((of->f_granted_access & FILE_DATA_ALL) == 0) { 10203ad684d6Sjb150015 mutex_exit(&of->f_mutex); 10213ad684d6Sjb150015 return (NT_STATUS_SUCCESS); 10223ad684d6Sjb150015 } 10233ad684d6Sjb150015 10243ad684d6Sjb150015 /* 10253ad684d6Sjb150015 * Check requested share access against the 10263ad684d6Sjb150015 * open granted (desired) access 10273ad684d6Sjb150015 */ 10283ad684d6Sjb150015 if (SMB_DENY_DELETE(share_access) && (of->f_granted_access & DELETE)) { 10293ad684d6Sjb150015 mutex_exit(&of->f_mutex); 10303ad684d6Sjb150015 return (NT_STATUS_SHARING_VIOLATION); 10313ad684d6Sjb150015 } 10323ad684d6Sjb150015 10333ad684d6Sjb150015 if (SMB_DENY_READ(share_access) && 10343ad684d6Sjb150015 (of->f_granted_access & (FILE_READ_DATA | FILE_EXECUTE))) { 10353ad684d6Sjb150015 mutex_exit(&of->f_mutex); 10363ad684d6Sjb150015 return (NT_STATUS_SHARING_VIOLATION); 10373ad684d6Sjb150015 } 10383ad684d6Sjb150015 10393ad684d6Sjb150015 if (SMB_DENY_WRITE(share_access) && 10403ad684d6Sjb150015 (of->f_granted_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) { 10413ad684d6Sjb150015 mutex_exit(&of->f_mutex); 10423ad684d6Sjb150015 return (NT_STATUS_SHARING_VIOLATION); 10433ad684d6Sjb150015 } 10443ad684d6Sjb150015 10453ad684d6Sjb150015 /* check requested desired access against the open share access */ 10463ad684d6Sjb150015 if (SMB_DENY_DELETE(of->f_share_access) && (desired_access & DELETE)) { 10473ad684d6Sjb150015 mutex_exit(&of->f_mutex); 10483ad684d6Sjb150015 return (NT_STATUS_SHARING_VIOLATION); 10493ad684d6Sjb150015 } 10503ad684d6Sjb150015 10513ad684d6Sjb150015 if (SMB_DENY_READ(of->f_share_access) && 10523ad684d6Sjb150015 (desired_access & (FILE_READ_DATA | FILE_EXECUTE))) { 10533ad684d6Sjb150015 mutex_exit(&of->f_mutex); 10543ad684d6Sjb150015 return (NT_STATUS_SHARING_VIOLATION); 10553ad684d6Sjb150015 } 10563ad684d6Sjb150015 10573ad684d6Sjb150015 if (SMB_DENY_WRITE(of->f_share_access) && 10583ad684d6Sjb150015 (desired_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) { 10593ad684d6Sjb150015 mutex_exit(&of->f_mutex); 10603ad684d6Sjb150015 return (NT_STATUS_SHARING_VIOLATION); 10613ad684d6Sjb150015 } 10623ad684d6Sjb150015 10633ad684d6Sjb150015 mutex_exit(&of->f_mutex); 10643ad684d6Sjb150015 return (NT_STATUS_SUCCESS); 10653ad684d6Sjb150015 } 10663ad684d6Sjb150015 10673ad684d6Sjb150015 /* 10683ad684d6Sjb150015 * smb_ofile_rename_check 10693ad684d6Sjb150015 * 10703ad684d6Sjb150015 * An open file can be renamed if 10713ad684d6Sjb150015 * 10723ad684d6Sjb150015 * 1. isn't opened for data writing or deleting 10733ad684d6Sjb150015 * 10743ad684d6Sjb150015 * 2. Opened with "Deny Delete" share mode 10753ad684d6Sjb150015 * But not opened for data reading or executing 10763ad684d6Sjb150015 * (opened for accessing meta data) 10773ad684d6Sjb150015 */ 10783ad684d6Sjb150015 10793ad684d6Sjb150015 uint32_t 10803ad684d6Sjb150015 smb_ofile_rename_check(smb_ofile_t *of) 10813ad684d6Sjb150015 { 10823ad684d6Sjb150015 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 10833ad684d6Sjb150015 10843ad684d6Sjb150015 mutex_enter(&of->f_mutex); 10853ad684d6Sjb150015 10863ad684d6Sjb150015 if (of->f_state != SMB_OFILE_STATE_OPEN) { 10873ad684d6Sjb150015 mutex_exit(&of->f_mutex); 10883ad684d6Sjb150015 return (NT_STATUS_INVALID_HANDLE); 10893ad684d6Sjb150015 } 10903ad684d6Sjb150015 10913ad684d6Sjb150015 if (of->f_granted_access & 10923ad684d6Sjb150015 (FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE)) { 10933ad684d6Sjb150015 mutex_exit(&of->f_mutex); 10943ad684d6Sjb150015 return (NT_STATUS_SHARING_VIOLATION); 10953ad684d6Sjb150015 } 10963ad684d6Sjb150015 10973ad684d6Sjb150015 if ((of->f_share_access & FILE_SHARE_DELETE) == 0) { 10983ad684d6Sjb150015 if (of->f_granted_access & 10993ad684d6Sjb150015 (FILE_READ_DATA | FILE_EXECUTE)) { 11003ad684d6Sjb150015 mutex_exit(&of->f_mutex); 11013ad684d6Sjb150015 return (NT_STATUS_SHARING_VIOLATION); 11023ad684d6Sjb150015 } 11033ad684d6Sjb150015 } 11043ad684d6Sjb150015 11053ad684d6Sjb150015 mutex_exit(&of->f_mutex); 11063ad684d6Sjb150015 return (NT_STATUS_SUCCESS); 11073ad684d6Sjb150015 } 11083ad684d6Sjb150015 11093ad684d6Sjb150015 /* 11103ad684d6Sjb150015 * smb_ofile_delete_check 11113ad684d6Sjb150015 * 11123ad684d6Sjb150015 * An open file can be deleted only if opened for 11133ad684d6Sjb150015 * accessing meta data. Share modes aren't important 11143ad684d6Sjb150015 * in this case. 11153ad684d6Sjb150015 * 11163ad684d6Sjb150015 * NOTE: there is another mechanism for deleting an 11173ad684d6Sjb150015 * open file that NT clients usually use. 11183ad684d6Sjb150015 * That's setting "Delete on close" flag for an open 11193ad684d6Sjb150015 * file. In this way the file will be deleted after 11203ad684d6Sjb150015 * last close. This flag can be set by SmbTrans2SetFileInfo 11213ad684d6Sjb150015 * with FILE_DISPOSITION_INFO information level. 11223ad684d6Sjb150015 * For setting this flag, the file should be opened by 11233ad684d6Sjb150015 * DELETE access in the FID that is passed in the Trans2 11243ad684d6Sjb150015 * request. 11253ad684d6Sjb150015 */ 11263ad684d6Sjb150015 11273ad684d6Sjb150015 uint32_t 11283ad684d6Sjb150015 smb_ofile_delete_check(smb_ofile_t *of) 11293ad684d6Sjb150015 { 11303ad684d6Sjb150015 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 11313ad684d6Sjb150015 11323ad684d6Sjb150015 mutex_enter(&of->f_mutex); 11333ad684d6Sjb150015 11343ad684d6Sjb150015 if (of->f_state != SMB_OFILE_STATE_OPEN) { 11353ad684d6Sjb150015 mutex_exit(&of->f_mutex); 11363ad684d6Sjb150015 return (NT_STATUS_INVALID_HANDLE); 11373ad684d6Sjb150015 } 11383ad684d6Sjb150015 11393ad684d6Sjb150015 if (of->f_granted_access & 11403ad684d6Sjb150015 (FILE_READ_DATA | FILE_WRITE_DATA | 11413ad684d6Sjb150015 FILE_APPEND_DATA | FILE_EXECUTE | DELETE)) { 11423ad684d6Sjb150015 mutex_exit(&of->f_mutex); 11433ad684d6Sjb150015 return (NT_STATUS_SHARING_VIOLATION); 11443ad684d6Sjb150015 } 11453ad684d6Sjb150015 11463ad684d6Sjb150015 mutex_exit(&of->f_mutex); 11473ad684d6Sjb150015 return (NT_STATUS_SUCCESS); 11483ad684d6Sjb150015 } 1149b89a8333Snatalie li - Sun Microsystems - Irvine United States 1150b89a8333Snatalie li - Sun Microsystems - Irvine United States cred_t * 1151b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_ofile_getcred(smb_ofile_t *of) 1152b89a8333Snatalie li - Sun Microsystems - Irvine United States { 1153b89a8333Snatalie li - Sun Microsystems - Irvine United States return (of->f_cr); 1154b89a8333Snatalie li - Sun Microsystems - Irvine United States } 11558b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 11568b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States /* 11578b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * smb_ofile_set_delete_on_close 11588b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * 11598b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * Set the DeleteOnClose flag on the smb file. When the file is closed, 11608b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * the flag will be transferred to the smb node, which will commit the 11618b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * delete operation and inhibit subsequent open requests. 11628b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * 11638b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * When DeleteOnClose is set on an smb_node, the common open code will 11648b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * reject subsequent open requests for the file. Observation of Windows 11658b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * 2000 indicates that subsequent opens should be allowed (assuming 11668b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * there would be no sharing violation) until the file is closed using 11678b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States * the fid on which the DeleteOnClose was requested. 11688b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States */ 11698b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States void 11708b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States smb_ofile_set_delete_on_close(smb_ofile_t *of) 11718b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States { 11728b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&of->f_mutex); 11738b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States of->f_flags |= SMB_OFLAGS_SET_DELETE_ON_CLOSE; 11748b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&of->f_mutex); 11758b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States } 11761fcced4cSJordan Brown 11771fcced4cSJordan Brown /* 11781fcced4cSJordan Brown * Encode open file information into a buffer; needed in user space to 11791fcced4cSJordan Brown * support RPC requests. 11801fcced4cSJordan Brown */ 11811fcced4cSJordan Brown static int 11821fcced4cSJordan Brown smb_ofile_netinfo_encode(smb_ofile_t *of, uint8_t *buf, size_t buflen, 11831fcced4cSJordan Brown uint32_t *nbytes) 11841fcced4cSJordan Brown { 11851fcced4cSJordan Brown smb_netfileinfo_t fi; 11861fcced4cSJordan Brown int rc; 11871fcced4cSJordan Brown 11881fcced4cSJordan Brown rc = smb_ofile_netinfo_init(of, &fi); 11891fcced4cSJordan Brown if (rc == 0) { 11901fcced4cSJordan Brown rc = smb_netfileinfo_encode(&fi, buf, buflen, nbytes); 11911fcced4cSJordan Brown smb_ofile_netinfo_fini(&fi); 11921fcced4cSJordan Brown } 11931fcced4cSJordan Brown 11941fcced4cSJordan Brown return (rc); 11951fcced4cSJordan Brown } 11961fcced4cSJordan Brown 11971fcced4cSJordan Brown static int 11981fcced4cSJordan Brown smb_ofile_netinfo_init(smb_ofile_t *of, smb_netfileinfo_t *fi) 11991fcced4cSJordan Brown { 12001fcced4cSJordan Brown smb_user_t *user; 12011fcced4cSJordan Brown smb_tree_t *tree; 12021fcced4cSJordan Brown smb_node_t *node; 12031fcced4cSJordan Brown char *path; 12041fcced4cSJordan Brown char *buf; 12051fcced4cSJordan Brown int rc; 12061fcced4cSJordan Brown 12071fcced4cSJordan Brown ASSERT(of); 12081fcced4cSJordan Brown user = of->f_user; 12091fcced4cSJordan Brown tree = of->f_tree; 12101fcced4cSJordan Brown ASSERT(user); 12111fcced4cSJordan Brown ASSERT(tree); 12121fcced4cSJordan Brown 12131fcced4cSJordan Brown buf = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 12141fcced4cSJordan Brown 12151fcced4cSJordan Brown switch (of->f_ftype) { 12161fcced4cSJordan Brown case SMB_FTYPE_DISK: 12171fcced4cSJordan Brown node = of->f_node; 12181fcced4cSJordan Brown ASSERT(node); 12191fcced4cSJordan Brown 12201fcced4cSJordan Brown fi->fi_permissions = of->f_granted_access; 12211fcced4cSJordan Brown fi->fi_numlocks = smb_lock_get_lock_count(node); 12221fcced4cSJordan Brown 12231fcced4cSJordan Brown path = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 12241fcced4cSJordan Brown 12251fcced4cSJordan Brown if (node != tree->t_snode) { 12261fcced4cSJordan Brown rc = vnodetopath(tree->t_snode->vp, node->vp, path, 12271fcced4cSJordan Brown MAXPATHLEN, kcred); 12281fcced4cSJordan Brown if (rc == 0) 12291fcced4cSJordan Brown (void) strsubst(path, '/', '\\'); 12301fcced4cSJordan Brown else 12311fcced4cSJordan Brown (void) strlcpy(path, node->od_name, MAXPATHLEN); 12321fcced4cSJordan Brown } 12331fcced4cSJordan Brown 12341fcced4cSJordan Brown (void) snprintf(buf, MAXPATHLEN, "%s:%s", tree->t_sharename, 12351fcced4cSJordan Brown path); 12361fcced4cSJordan Brown kmem_free(path, MAXPATHLEN); 12371fcced4cSJordan Brown break; 12381fcced4cSJordan Brown 12391fcced4cSJordan Brown case SMB_FTYPE_MESG_PIPE: 12401fcced4cSJordan Brown ASSERT(of->f_pipe); 12411fcced4cSJordan Brown 12421fcced4cSJordan Brown fi->fi_permissions = FILE_READ_DATA | FILE_WRITE_DATA | 12431fcced4cSJordan Brown FILE_EXECUTE; 12441fcced4cSJordan Brown fi->fi_numlocks = 0; 12451fcced4cSJordan Brown (void) snprintf(buf, MAXPATHLEN, "\\PIPE\\%s", 12461fcced4cSJordan Brown of->f_pipe->p_name); 12471fcced4cSJordan Brown break; 12481fcced4cSJordan Brown 12491fcced4cSJordan Brown default: 12501fcced4cSJordan Brown kmem_free(buf, MAXPATHLEN); 12511fcced4cSJordan Brown return (-1); 12521fcced4cSJordan Brown } 12531fcced4cSJordan Brown 12541fcced4cSJordan Brown fi->fi_fid = of->f_fid; 12551fcced4cSJordan Brown fi->fi_uniqid = of->f_uniqid; 12561fcced4cSJordan Brown fi->fi_pathlen = strlen(buf) + 1; 1257*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States fi->fi_path = smb_mem_strdup(buf); 12581fcced4cSJordan Brown kmem_free(buf, MAXPATHLEN); 12591fcced4cSJordan Brown 12601fcced4cSJordan Brown fi->fi_namelen = user->u_domain_len + user->u_name_len + 2; 12611fcced4cSJordan Brown fi->fi_username = kmem_alloc(fi->fi_namelen, KM_SLEEP); 12621fcced4cSJordan Brown (void) snprintf(fi->fi_username, fi->fi_namelen, "%s\\%s", 12631fcced4cSJordan Brown user->u_domain, user->u_name); 12641fcced4cSJordan Brown return (0); 12651fcced4cSJordan Brown } 12661fcced4cSJordan Brown 12671fcced4cSJordan Brown static void 12681fcced4cSJordan Brown smb_ofile_netinfo_fini(smb_netfileinfo_t *fi) 12691fcced4cSJordan Brown { 12701fcced4cSJordan Brown if (fi == NULL) 12711fcced4cSJordan Brown return; 12721fcced4cSJordan Brown 12731fcced4cSJordan Brown if (fi->fi_path) 1274*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_mem_free(fi->fi_path); 12751fcced4cSJordan Brown if (fi->fi_username) 12761fcced4cSJordan Brown kmem_free(fi->fi_username, fi->fi_namelen); 12771fcced4cSJordan Brown 12781fcced4cSJordan Brown bzero(fi, sizeof (smb_netfileinfo_t)); 12791fcced4cSJordan Brown } 1280*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 1281*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 1282*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * A query of user and group quotas may span multiple requests. 1283*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * f_quota_resume is used to determine where the query should 1284*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * be resumed, in a subsequent request. f_quota_resume contains 1285*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * the SID of the last quota entry returned to the client. 1286*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 1287*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void 1288*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_ofile_set_quota_resume(smb_ofile_t *ofile, char *resume) 1289*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 1290*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ASSERT(ofile); 1291*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&ofile->f_mutex); 1292*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (resume == NULL) 1293*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States bzero(ofile->f_quota_resume, SMB_SID_STRSZ); 1294*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States else 1295*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) strlcpy(ofile->f_quota_resume, resume, SMB_SID_STRSZ); 1296*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&ofile->f_mutex); 1297*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 1298*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 1299*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void 1300*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_ofile_get_quota_resume(smb_ofile_t *ofile, char *buf, int bufsize) 1301*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 1302*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ASSERT(ofile); 1303*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&ofile->f_mutex); 1304*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) strlcpy(buf, ofile->f_quota_resume, bufsize); 1305*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&ofile->f_mutex); 1306*9fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 1307