1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23 * Copyright 2016 Syneto S.R.L. All rights reserved. 24 * Copyright (c) 2016 by Delphix. All rights reserved. 25 * Copyright 2018 Nexenta Systems, Inc. All rights reserved. 26 */ 27 28 /* 29 * General Structures Layout 30 * ------------------------- 31 * 32 * This is a simplified diagram showing the relationship between most of the 33 * main structures. 34 * 35 * +-------------------+ 36 * | SMB_INFO | 37 * +-------------------+ 38 * | 39 * | 40 * v 41 * +-------------------+ +-------------------+ +-------------------+ 42 * | SESSION |<----->| SESSION |......| SESSION | 43 * +-------------------+ +-------------------+ +-------------------+ 44 * | | 45 * | | 46 * | v 47 * | +-------------------+ +-------------------+ +-------------------+ 48 * | | USER |<--->| USER |...| USER | 49 * | +-------------------+ +-------------------+ +-------------------+ 50 * | 51 * | 52 * v 53 * +-------------------+ +-------------------+ +-------------------+ 54 * | TREE |<----->| TREE |......| TREE | 55 * +-------------------+ +-------------------+ +-------------------+ 56 * | | 57 * | | 58 * | v 59 * | +-------+ +-------+ +-------+ 60 * | | OFILE |<----->| OFILE |......| OFILE | 61 * | +-------+ +-------+ +-------+ 62 * | 63 * | 64 * v 65 * +-------+ +------+ +------+ 66 * | ODIR |<----->| ODIR |......| ODIR | 67 * +-------+ +------+ +------+ 68 * 69 * 70 * Ofile State Machine 71 * ------------------ 72 * 73 * +-------------------------+ T0 74 * | SMB_OFILE_STATE_OPEN |<--+-------- Creation/Allocation 75 * +-------------------------+ | 76 * | | | T5 77 * | | +---------------------------+ 78 * | | | SMB_OFILE_STATE_RECONNECT | 79 * | | +---------------------------+ 80 * | | ^ 81 * | v | 82 * | +---------------+ | 83 * | | STATE_SAVE_DH | | 84 * | | STATE_SAVING | | 85 * | +---------------+ | 86 * | | | T4 87 * | T1 | T3 +--------------------------+ 88 * | +------>| SMB_OFILE_STATE_ORPHANED | 89 * v +--------------------------+ 90 * +-------------------------+ | | 91 * | SMB_OFILE_STATE_CLOSING |<--+ T6 | T7 92 * +-------------------------+ | 93 * | ^ v 94 * | T2 | T8 +-------------------------+ 95 * | +-------| SMB_OFILE_STATE_EXPIRED | 96 * v +-------------------------+ 97 * +-------------------------+ 98 * | SMB_OFILE_STATE_CLOSED |----------> Deletion/Free 99 * +-------------------------+ T9 100 * 101 * SMB_OFILE_STATE_OPEN 102 * 103 * While in this state: 104 * - The ofile is queued in the list of ofiles of its tree. 105 * - References will be given out if the ofile is looked up. 106 * 107 * SMB_OFILE_STATE_SAVE_DH 108 * 109 * Similar to state _CLOSING, but instead of deleting the ofile, 110 * it leaves the ofile in state _ORPHANED (for later reclaim). 111 * Will move to _SAVING after last ref, then _ORPHANED. 112 * 113 * While in this state: 114 * - The ofile has been marked for preservation during a 115 * walk of the tree ofile list to close multiple files. 116 * - References will not be given out if the ofile is looked up, 117 * except for oplock break processing. 118 * - Still affects Sharing Violation rules 119 * 120 * SMB_OFILE_STATE_SAVING 121 * 122 * Transient state used to keep oplock break processing out 123 * while the ofile moves to state _ORPHANED. 124 * 125 * While in this state: 126 * - References will not be given out if the ofile is looked up, 127 * except for oplock break processing. 128 * - Still affects Sharing Violation rules 129 * 130 * SMB_OFILE_STATE_CLOSING 131 * 132 * Close has been requested. Stay in this state until the last 133 * ref. is gone, then move to state _CLOSED 134 * 135 * While in this state: 136 * - The ofile is queued in the list of ofiles of its tree. 137 * - References will not be given out if the ofile is looked up. 138 * - The file is closed and the locks held are being released. 139 * - The resources associated with the ofile remain. 140 * 141 * SMB_OFILE_STATE_CLOSED 142 * 143 * While in this state: 144 * - The ofile is queued in the list of ofiles of its tree. 145 * - References will not be given out if the ofile is looked up. 146 * - The resources associated with the ofile remain. 147 * 148 * SMB_OFILE_STATE_ORPHANED 149 * 150 * While in this state: 151 * - The ofile is queued in the list of ofiles of its tree. 152 * - Can be reclaimed by the original owner 153 * - References will not be given out if the ofile is looked up. 154 * - All the tree, user, and session "up" pointers are NULL! 155 * - Will eventually be "expired" if not reclaimed 156 * - Can be closed if its oplock is broken 157 * - Still affects Sharing Violation rules 158 * 159 * SMB_OFILE_STATE_EXPIRED 160 * 161 * While in this state: 162 * - The ofile is queued in the list of ofiles of its tree. 163 * - References will not be given out if the ofile is looked up. 164 * - The ofile has not been reclaimed and will soon be closed, 165 * due to, for example, the durable handle timer expiring, or its 166 * oplock being broken. 167 * - Cannot be reclaimed at this point 168 * 169 * SMB_OFILE_STATE_RECONNECT 170 * 171 * Transient state used to keep oplock break processing out 172 * while the ofile moves from state _ORPHANED to _OPEN. 173 * 174 * While in this state: 175 * - The ofile is being reclaimed; do not touch it. 176 * - References will not be given out if the ofile is looked up. 177 * - Still affects Sharing Violation rules 178 * - see smb2_dh_reconnect() for which members need to be avoided 179 * 180 * Transition T0 181 * 182 * This transition occurs in smb_ofile_open(). A new ofile is created and 183 * added to the list of ofiles of a tree. 184 * 185 * Transition T1 186 * 187 * This transition occurs in smb_ofile_close(). Note that this only happens 188 * when we determine that an ofile should be closed in spite of its durable 189 * handle properties. 190 * 191 * Transition T2 192 * 193 * This transition occurs in smb_ofile_release(). The resources associated 194 * with the ofile are freed as well as the ofile structure. For the 195 * transition to occur, the ofile must be in the SMB_OFILE_STATE_CLOSED 196 * state and the reference count be zero. 197 * 198 * Transition T3 199 * 200 * This transition occurs in smb_ofile_orphan_dh(). It happens during an 201 * smb2 logoff, or during a session disconnect when certain conditions are 202 * met. The ofile and structures above it will be kept around until the ofile 203 * either gets reclaimed, expires after f_timeout_offset nanoseconds, or its 204 * oplock is broken. 205 * 206 * Transition T4 207 * 208 * This transition occurs in smb2_dh_reconnect(). An smb2 create request 209 * with a DURABLE_HANDLE_RECONNECT(_V2) create context has been 210 * recieved from the original owner. If leases are supported or it's 211 * RECONNECT_V2, reconnect is subject to additional conditions. The ofile 212 * will be unwired from the old, disconnected session, tree, and user, 213 * and wired up to its new context. 214 * 215 * Transition T5 216 * 217 * This transition occurs in smb2_dh_reconnect(). The ofile has been 218 * successfully reclaimed. 219 * 220 * Transition T6 221 * 222 * This transition occurs in smb_ofile_close(). The ofile has been orphaned 223 * while some thread was blocked, and that thread closes the ofile. Can only 224 * happen when the ofile is orphaned due to an SMB2 LOGOFF request. 225 * 226 * Transition T7 227 * 228 * This transition occurs in smb_session_durable_timers() and 229 * smb_oplock_send_brk(). The ofile will soon be closed. 230 * In the former case, f_timeout_offset nanoseconds have passed since 231 * the ofile was orphaned. In the latter, an oplock break occured 232 * on the ofile while it was orphaned. 233 * 234 * Transition T8 235 * 236 * This transition occurs in smb_ofile_close(). 237 * 238 * Transition T9 239 * 240 * This transition occurs in smb_ofile_delete(). 241 * 242 * Comments 243 * -------- 244 * 245 * The state machine of the ofile structures is controlled by 3 elements: 246 * - The list of ofiles of the tree it belongs to. 247 * - The mutex embedded in the structure itself. 248 * - The reference count. 249 * 250 * There's a mutex embedded in the ofile structure used to protect its fields 251 * and there's a lock embedded in the list of ofiles of a tree. To 252 * increment or to decrement the reference count the mutex must be entered. 253 * To insert the ofile into the list of ofiles of the tree and to remove 254 * the ofile from it, the lock must be entered in RW_WRITER mode. 255 * 256 * Rules of access to a ofile structure: 257 * 258 * 1) In order to avoid deadlocks, when both (mutex and lock of the ofile 259 * list) have to be entered, the lock must be entered first. Additionally, 260 * f_mutex must not be held when removing the ofile from sv_persistid_ht. 261 * 262 * 2) All actions applied to an ofile require a reference count. 263 * 264 * 3) There are 2 ways of getting a reference count. One is when the ofile 265 * is opened. The other one when the ofile is looked up. This translates 266 * into 2 functions: smb_ofile_open() and smb_ofile_lookup_by_fid(). 267 * 268 * It should be noted that the reference count of an ofile registers the 269 * number of references to the ofile in other structures (such as an smb 270 * request). The reference count is not incremented in these 2 instances: 271 * 272 * 1) The ofile is open. An ofile is anchored by its state. If there's 273 * no activity involving an ofile currently open, the reference count 274 * of that ofile is zero. 275 * 276 * 2) The ofile is queued in the list of ofiles of its tree. The fact of 277 * being queued in that list is NOT registered by incrementing the 278 * reference count. 279 */ 280 #include <smbsrv/smb2_kproto.h> 281 #include <smbsrv/smb_fsops.h> 282 #include <sys/time.h> 283 284 /* XXX: May need to actually assign GUIDs for these. */ 285 /* Don't leak object addresses */ 286 #define SMB_OFILE_PERSISTID(of) \ 287 ((uintptr_t)&smb_cache_ofile ^ (uintptr_t)(of)) 288 289 static boolean_t smb_ofile_is_open_locked(smb_ofile_t *); 290 static void smb_ofile_delete(void *arg); 291 static void smb_ofile_save_dh(void *arg); 292 293 static int smb_ofile_netinfo_encode(smb_ofile_t *, uint8_t *, size_t, 294 uint32_t *); 295 static int smb_ofile_netinfo_init(smb_ofile_t *, smb_netfileinfo_t *); 296 static void smb_ofile_netinfo_fini(smb_netfileinfo_t *); 297 298 /* 299 * smb_ofile_alloc 300 * Allocate an ofile and fill in it's "up" pointers, but 301 * do NOT link it into the tree's list of ofiles or the 302 * node's list of ofiles. An ofile in this state is a 303 * "proposed" open passed to the oplock break code. 304 * 305 * If we don't get as far as smb_ofile_open with this OF, 306 * call smb_ofile_free() to free this object. 307 */ 308 smb_ofile_t * 309 smb_ofile_alloc( 310 smb_request_t *sr, 311 smb_arg_open_t *op, 312 smb_node_t *node, /* optional (may be NULL) */ 313 uint16_t ftype, 314 uint16_t tree_fid, 315 uint32_t uniqid) 316 { 317 smb_tree_t *tree = sr->tid_tree; 318 smb_ofile_t *of; 319 320 of = kmem_cache_alloc(smb_cache_ofile, KM_SLEEP); 321 bzero(of, sizeof (smb_ofile_t)); 322 of->f_magic = SMB_OFILE_MAGIC; 323 324 mutex_init(&of->f_mutex, NULL, MUTEX_DEFAULT, NULL); 325 list_create(&of->f_notify.nc_waiters, sizeof (smb_request_t), 326 offsetof(smb_request_t, sr_waiters)); 327 328 of->f_state = SMB_OFILE_STATE_ALLOC; 329 of->f_refcnt = 1; 330 of->f_ftype = ftype; 331 of->f_fid = tree_fid; 332 /* of->f_persistid see smb2_create */ 333 of->f_uniqid = uniqid; 334 of->f_opened_by_pid = sr->smb_pid; 335 of->f_granted_access = op->desired_access; 336 of->f_share_access = op->share_access; 337 of->f_create_options = op->create_options; 338 of->f_cr = (op->create_options & FILE_OPEN_FOR_BACKUP_INTENT) ? 339 smb_user_getprivcred(sr->uid_user) : sr->uid_user->u_cred; 340 crhold(of->f_cr); 341 of->f_server = tree->t_server; 342 of->f_session = tree->t_session; 343 (void) memset(of->f_lock_seq, -1, SMB_OFILE_LSEQ_MAX); 344 345 of->f_mode = smb_fsop_amask_to_omode(of->f_granted_access); 346 if ((of->f_granted_access & FILE_DATA_ALL) == FILE_EXECUTE) 347 of->f_flags |= SMB_OFLAGS_EXECONLY; 348 349 /* 350 * In case a lease is requested, copy the lease keys now so 351 * any oplock breaks during open don't break those on our 352 * other handles that might have the same lease. 353 */ 354 bcopy(op->lease_key, of->TargetOplockKey, SMB_LEASE_KEY_SZ); 355 bcopy(op->parent_lease_key, of->ParentOplockKey, SMB_LEASE_KEY_SZ); 356 357 /* 358 * grab a ref for of->f_user and of->f_tree 359 * We know the user and tree must be "live" because 360 * this SR holds references to them. The node ref. is 361 * held by our caller, until smb_ofile_open puts this 362 * ofile on the node ofile list with smb_node_add_ofile. 363 */ 364 smb_user_hold_internal(sr->uid_user); 365 smb_tree_hold_internal(tree); 366 of->f_user = sr->uid_user; 367 of->f_tree = tree; 368 of->f_node = node; 369 370 return (of); 371 } 372 373 /* 374 * smb_ofile_open 375 * 376 * Complete an open on an ofile that was previously allocated by 377 * smb_ofile_alloc, by putting it on the tree ofile list and 378 * (if it's a file) the node ofile list. 379 */ 380 void 381 smb_ofile_open( 382 smb_request_t *sr, 383 smb_arg_open_t *op, 384 smb_ofile_t *of) 385 { 386 smb_tree_t *tree = sr->tid_tree; 387 smb_node_t *node = of->f_node; 388 389 ASSERT(of->f_state == SMB_OFILE_STATE_ALLOC); 390 of->f_state = SMB_OFILE_STATE_OPEN; 391 392 switch (of->f_ftype) { 393 case SMB_FTYPE_BYTE_PIPE: 394 case SMB_FTYPE_MESG_PIPE: 395 /* See smb_opipe_open. */ 396 of->f_pipe = op->pipe; 397 smb_server_inc_pipes(of->f_server); 398 break; 399 case SMB_FTYPE_DISK: 400 case SMB_FTYPE_PRINTER: 401 /* Regular file, not a pipe */ 402 ASSERT(node != NULL); 403 404 smb_node_inc_open_ofiles(node); 405 smb_node_add_ofile(node, of); 406 smb_node_ref(node); 407 smb_server_inc_files(of->f_server); 408 break; 409 default: 410 ASSERT(0); 411 } 412 smb_llist_enter(&tree->t_ofile_list, RW_WRITER); 413 smb_llist_insert_tail(&tree->t_ofile_list, of); 414 smb_llist_exit(&tree->t_ofile_list); 415 atomic_inc_32(&tree->t_open_files); 416 atomic_inc_32(&of->f_session->s_file_cnt); 417 418 } 419 420 /* 421 * smb_ofile_close 422 * 423 * Incoming states: (where from) 424 * SMB_OFILE_STATE_OPEN protocol close, smb_ofile_drop 425 * SMB_OFILE_STATE_EXPIRED called via smb2_dh_expire 426 * SMB_OFILE_STATE_ORPHANED smb2_dh_shutdown 427 */ 428 void 429 smb_ofile_close(smb_ofile_t *of, int32_t mtime_sec) 430 { 431 smb_attr_t *pa; 432 timestruc_t now; 433 434 SMB_OFILE_VALID(of); 435 436 mutex_enter(&of->f_mutex); 437 ASSERT(of->f_refcnt); 438 439 switch (of->f_state) { 440 case SMB_OFILE_STATE_OPEN: 441 case SMB_OFILE_STATE_ORPHANED: 442 case SMB_OFILE_STATE_EXPIRED: 443 of->f_state = SMB_OFILE_STATE_CLOSING; 444 mutex_exit(&of->f_mutex); 445 break; 446 default: 447 mutex_exit(&of->f_mutex); 448 return; 449 } 450 451 switch (of->f_ftype) { 452 case SMB_FTYPE_BYTE_PIPE: 453 case SMB_FTYPE_MESG_PIPE: 454 smb_opipe_close(of); 455 smb_server_dec_pipes(of->f_server); 456 break; 457 458 case SMB_FTYPE_DISK: 459 if (of->f_persistid != 0) 460 smb_ofile_del_persistid(of); 461 if (of->f_lease != NULL) 462 smb2_lease_ofile_close(of); 463 smb_oplock_break_CLOSE(of->f_node, of); 464 /* FALLTHROUGH */ 465 466 case SMB_FTYPE_PRINTER: /* or FTYPE_DISK */ 467 /* 468 * In here we make changes to of->f_pending_attr 469 * while not holding of->f_mutex. This is OK 470 * because we've changed f_state to CLOSING, 471 * so no more threads will take this path. 472 */ 473 pa = &of->f_pending_attr; 474 if (mtime_sec != 0) { 475 pa->sa_vattr.va_mtime.tv_sec = mtime_sec; 476 pa->sa_mask |= SMB_AT_MTIME; 477 } 478 479 /* 480 * If we have ever modified data via this handle 481 * (write or truncate) and if the mtime was not 482 * set via this handle, update the mtime again 483 * during the close. Windows expects this. 484 * [ MS-FSA 2.1.5.4 "Update Timestamps" ] 485 */ 486 if (of->f_written && 487 (pa->sa_mask & SMB_AT_MTIME) == 0) { 488 pa->sa_mask |= SMB_AT_MTIME; 489 gethrestime(&now); 490 pa->sa_vattr.va_mtime = now; 491 } 492 493 if (of->f_flags & SMB_OFLAGS_SET_DELETE_ON_CLOSE) { 494 /* We delete using the on-disk name. */ 495 uint32_t flags = SMB_CASE_SENSITIVE; 496 (void) smb_node_set_delete_on_close(of->f_node, 497 of->f_cr, flags); 498 } 499 smb_fsop_unshrlock(of->f_cr, of->f_node, of->f_uniqid); 500 smb_node_destroy_lock_by_ofile(of->f_node, of); 501 502 if (smb_node_is_file(of->f_node)) { 503 (void) smb_fsop_close(of->f_node, of->f_mode, 504 of->f_cr); 505 } else { 506 /* 507 * If there was an odir, close it. 508 */ 509 if (of->f_odir != NULL) 510 smb_odir_close(of->f_odir); 511 /* 512 * Cancel any notify change requests that 513 * might be watching this open file (dir), 514 * and unsubscribe it from node events. 515 * 516 * Can't hold f_mutex when calling smb_notify_ofile. 517 * Don't really need it when unsubscribing, but 518 * harmless, and consistent with subscribing. 519 */ 520 if (of->f_notify.nc_subscribed) 521 smb_notify_ofile(of, 522 FILE_ACTION_HANDLE_CLOSED, NULL); 523 mutex_enter(&of->f_mutex); 524 if (of->f_notify.nc_subscribed) { 525 of->f_notify.nc_subscribed = B_FALSE; 526 smb_node_fcn_unsubscribe(of->f_node); 527 of->f_notify.nc_filter = 0; 528 } 529 mutex_exit(&of->f_mutex); 530 } 531 if (smb_node_dec_open_ofiles(of->f_node) == 0) { 532 /* 533 * Last close. If we're not deleting 534 * the file, apply any pending attrs. 535 * Leave allocsz zero when no open files, 536 * just to avoid confusion, because it's 537 * only updated when there are opens. 538 * XXX: Just do this on _every_ close. 539 */ 540 mutex_enter(&of->f_node->n_mutex); 541 if (of->f_node->flags & NODE_FLAGS_DELETE_ON_CLOSE) { 542 smb_node_delete_on_close(of->f_node); 543 pa->sa_mask = 0; 544 } 545 of->f_node->n_allocsz = 0; 546 mutex_exit(&of->f_node->n_mutex); 547 } 548 if (pa->sa_mask != 0) { 549 /* 550 * Commit any pending attributes from 551 * the ofile we're closing. Note that 552 * we pass NULL as the ofile to setattr 553 * so it will write to the file system 554 * and not keep anything on the ofile. 555 */ 556 (void) smb_node_setattr(NULL, of->f_node, 557 of->f_cr, NULL, pa); 558 } 559 560 smb_server_dec_files(of->f_server); 561 break; 562 } 563 564 /* 565 * Keep f_state == SMB_OFILE_STATE_CLOSING 566 * until the last ref. is dropped, in 567 * smb_ofile_release() 568 */ 569 } 570 571 /* 572 * "Destructor" function for smb_ofile_close_all, and 573 * smb_ofile_close_all_by_pid, called after the llist lock 574 * for tree list has been exited. Our job is to either 575 * close this ofile, or (if durable) set state _SAVE_DH. 576 * 577 * The next interesting thing happens when the last ref. 578 * on this ofile calls smb_ofile_release(), where we 579 * eihter delete the ofile, or (if durable) leave it 580 * in the persistid hash table for possible reclaim. 581 * 582 * This is run via smb_llist_post (after smb_llist_exit) 583 * because smb_ofile_close can block, and we'd rather not 584 * block while holding the ofile list as reader. 585 */ 586 static void 587 smb_ofile_drop(void *arg) 588 { 589 smb_ofile_t *of = arg; 590 591 SMB_OFILE_VALID(of); 592 593 mutex_enter(&of->f_mutex); 594 switch (of->f_state) { 595 case SMB_OFILE_STATE_OPEN: 596 /* DH checks under mutex. */ 597 if (of->f_ftype == SMB_FTYPE_DISK && 598 of->dh_vers != SMB2_NOT_DURABLE && 599 smb_dh_should_save(of)) { 600 /* 601 * Tell smb_ofile_release() to 602 * make this an _ORPHANED DH. 603 */ 604 of->f_state = SMB_OFILE_STATE_SAVE_DH; 605 mutex_exit(&of->f_mutex); 606 break; 607 } 608 /* OK close it. */ 609 mutex_exit(&of->f_mutex); 610 smb_ofile_close(of, 0); 611 break; 612 613 default: 614 /* Something else closed it already. */ 615 mutex_exit(&of->f_mutex); 616 break; 617 } 618 619 /* 620 * Release the ref acquired during the traversal loop. 621 * Note that on the last ref, this ofile will be 622 * removed from the tree list etc. 623 * See: smb_llist_post, smb_ofile_delete 624 */ 625 smb_ofile_release(of); 626 } 627 628 /* 629 * smb_ofile_close_all 630 * 631 * 632 */ 633 void 634 smb_ofile_close_all( 635 smb_tree_t *tree, 636 uint32_t pid) 637 { 638 smb_ofile_t *of; 639 smb_llist_t *ll; 640 641 ASSERT(tree); 642 ASSERT(tree->t_magic == SMB_TREE_MAGIC); 643 644 ll = &tree->t_ofile_list; 645 646 smb_llist_enter(ll, RW_READER); 647 for (of = smb_llist_head(ll); 648 of != NULL; 649 of = smb_llist_next(ll, of)) { 650 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 651 ASSERT(of->f_tree == tree); 652 if (pid != 0 && of->f_opened_by_pid != pid) 653 continue; 654 if (smb_ofile_hold(of)) { 655 smb_llist_post(ll, of, smb_ofile_drop); 656 } 657 } 658 659 /* 660 * Drop the lock and process the llist dtor queue. 661 * Calls smb_ofile_drop on ofiles that were open. 662 */ 663 smb_llist_exit(ll); 664 } 665 666 /* 667 * If the enumeration request is for ofile data, handle it here. 668 * Otherwise, return. 669 * 670 * This function should be called with a hold on the ofile. 671 */ 672 int 673 smb_ofile_enum(smb_ofile_t *of, smb_svcenum_t *svcenum) 674 { 675 uint8_t *pb; 676 uint_t nbytes; 677 int rc; 678 679 ASSERT(of); 680 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 681 ASSERT(of->f_refcnt); 682 683 if (svcenum->se_type != SMB_SVCENUM_TYPE_FILE) 684 return (0); 685 686 if (svcenum->se_nskip > 0) { 687 svcenum->se_nskip--; 688 return (0); 689 } 690 691 if (svcenum->se_nitems >= svcenum->se_nlimit) { 692 svcenum->se_nitems = svcenum->se_nlimit; 693 return (0); 694 } 695 696 pb = &svcenum->se_buf[svcenum->se_bused]; 697 698 rc = smb_ofile_netinfo_encode(of, pb, svcenum->se_bavail, 699 &nbytes); 700 if (rc == 0) { 701 svcenum->se_bavail -= nbytes; 702 svcenum->se_bused += nbytes; 703 svcenum->se_nitems++; 704 } 705 706 return (rc); 707 } 708 709 /* 710 * Take a reference on an open file, in any of the states: 711 * RECONNECT, SAVE_DH, OPEN, ORPHANED. 712 * Return TRUE if ref taken. Used for oplock breaks. 713 * 714 * Note: When the oplock break code calls this, it holds the 715 * node ofile list lock and node oplock mutex. When we see 716 * an ofile in states RECONNECT or SAVING, we know the ofile 717 * is gaining or losing it's tree, and that happens quickly, 718 * so we just wait for that work to finish. However, the 719 * waiting for state transitions here means we have to be 720 * careful not to re-enter the node list lock or otherwise 721 * block on things that could cause a deadlock. Waiting 722 * just on of->f_mutex here is OK. 723 */ 724 boolean_t 725 smb_ofile_hold_olbrk(smb_ofile_t *of) 726 { 727 boolean_t ret = B_FALSE; 728 729 ASSERT(of); 730 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 731 732 mutex_enter(&of->f_mutex); 733 734 again: 735 switch (of->f_state) { 736 case SMB_OFILE_STATE_RECONNECT: 737 case SMB_OFILE_STATE_SAVING: 738 cv_wait(&of->f_cv, &of->f_mutex); 739 goto again; 740 741 case SMB_OFILE_STATE_OPEN: 742 case SMB_OFILE_STATE_ORPHANED: 743 case SMB_OFILE_STATE_SAVE_DH: 744 of->f_refcnt++; 745 ret = B_TRUE; 746 break; 747 748 default: 749 break; 750 } 751 mutex_exit(&of->f_mutex); 752 753 return (ret); 754 } 755 756 /* 757 * Take a reference on an open file. 758 */ 759 boolean_t 760 smb_ofile_hold(smb_ofile_t *of) 761 { 762 ASSERT(of); 763 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 764 765 mutex_enter(&of->f_mutex); 766 767 if (of->f_state != SMB_OFILE_STATE_OPEN) { 768 mutex_exit(&of->f_mutex); 769 return (B_FALSE); 770 } 771 of->f_refcnt++; 772 773 mutex_exit(&of->f_mutex); 774 return (B_TRUE); 775 } 776 777 /* 778 * Release a reference on a file. If the reference count falls to 779 * zero and the file has been closed, post the object for deletion. 780 * Object deletion is deferred to avoid modifying a list while an 781 * iteration may be in progress. 782 * 783 * We're careful to avoid dropping f_session etc. until the last 784 * reference goes away. The oplock break code depends on that 785 * not changing while it holds a ref. on an ofile. 786 */ 787 void 788 smb_ofile_release(smb_ofile_t *of) 789 { 790 smb_tree_t *tree = of->f_tree; 791 boolean_t delete = B_FALSE; 792 793 SMB_OFILE_VALID(of); 794 795 mutex_enter(&of->f_mutex); 796 ASSERT(of->f_refcnt > 0); 797 of->f_refcnt--; 798 799 switch (of->f_state) { 800 case SMB_OFILE_STATE_OPEN: 801 case SMB_OFILE_STATE_ORPHANED: 802 case SMB_OFILE_STATE_EXPIRED: 803 break; 804 805 case SMB_OFILE_STATE_SAVE_DH: 806 ASSERT(tree != NULL); 807 if (of->f_refcnt == 0) { 808 of->f_state = SMB_OFILE_STATE_SAVING; 809 smb_llist_post(&tree->t_ofile_list, of, 810 smb_ofile_save_dh); 811 } 812 break; 813 814 case SMB_OFILE_STATE_CLOSING: 815 /* Note, tree == NULL on _ORPHANED */ 816 if (of->f_refcnt == 0) { 817 of->f_state = SMB_OFILE_STATE_CLOSED; 818 if (tree == NULL) { 819 /* Skip smb_llist_post */ 820 delete = B_TRUE; 821 break; 822 } 823 smb_llist_post(&tree->t_ofile_list, of, 824 smb_ofile_delete); 825 } 826 break; 827 828 default: 829 ASSERT(0); 830 break; 831 } 832 mutex_exit(&of->f_mutex); 833 834 /* 835 * When we drop the last ref. on an expired DH, it's no longer 836 * in any tree, so skip the smb_llist_post and just call 837 * smb_ofile_delete directly. 838 */ 839 if (delete) { 840 smb_ofile_delete(of); 841 } 842 } 843 844 /* 845 * smb_ofile_lookup_by_fid 846 * 847 * Find the open file whose fid matches the one specified in the request. 848 * If we can't find the fid or the shares (trees) don't match, we have a 849 * bad fid. 850 */ 851 smb_ofile_t * 852 smb_ofile_lookup_by_fid( 853 smb_request_t *sr, 854 uint16_t fid) 855 { 856 smb_tree_t *tree = sr->tid_tree; 857 smb_llist_t *of_list; 858 smb_ofile_t *of; 859 860 ASSERT(tree->t_magic == SMB_TREE_MAGIC); 861 862 of_list = &tree->t_ofile_list; 863 864 smb_llist_enter(of_list, RW_READER); 865 of = smb_llist_head(of_list); 866 while (of) { 867 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 868 ASSERT(of->f_tree == tree); 869 if (of->f_fid == fid) 870 break; 871 of = smb_llist_next(of_list, of); 872 } 873 if (of == NULL) 874 goto out; 875 876 /* 877 * Only allow use of a given FID with the same UID that 878 * was used to open it. MS-CIFS 3.3.5.14 879 */ 880 if (of->f_user != sr->uid_user) { 881 of = NULL; 882 goto out; 883 } 884 885 /* inline smb_ofile_hold() */ 886 mutex_enter(&of->f_mutex); 887 if (of->f_state != SMB_OFILE_STATE_OPEN) { 888 mutex_exit(&of->f_mutex); 889 of = NULL; 890 goto out; 891 } 892 of->f_refcnt++; 893 mutex_exit(&of->f_mutex); 894 895 out: 896 smb_llist_exit(of_list); 897 return (of); 898 } 899 900 /* 901 * smb_ofile_lookup_by_uniqid 902 * 903 * Find the open file whose uniqid matches the one specified in the request. 904 */ 905 smb_ofile_t * 906 smb_ofile_lookup_by_uniqid(smb_tree_t *tree, uint32_t uniqid) 907 { 908 smb_llist_t *of_list; 909 smb_ofile_t *of; 910 911 ASSERT(tree->t_magic == SMB_TREE_MAGIC); 912 913 of_list = &tree->t_ofile_list; 914 smb_llist_enter(of_list, RW_READER); 915 of = smb_llist_head(of_list); 916 917 while (of) { 918 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 919 ASSERT(of->f_tree == tree); 920 921 if (of->f_uniqid == uniqid) { 922 if (smb_ofile_hold(of)) { 923 smb_llist_exit(of_list); 924 return (of); 925 } 926 } 927 928 of = smb_llist_next(of_list, of); 929 } 930 931 smb_llist_exit(of_list); 932 return (NULL); 933 } 934 935 static smb_ofile_t * 936 smb_ofile_hold_cb(smb_ofile_t *of) 937 { 938 smb_ofile_t *ret = of; 939 940 mutex_enter(&of->f_mutex); 941 if (of->f_state == SMB_OFILE_STATE_ORPHANED) 942 /* inline smb_ofile_hold() */ 943 of->f_refcnt++; 944 else 945 ret = NULL; 946 947 mutex_exit(&of->f_mutex); 948 return (ret); 949 } 950 951 /* 952 * Lookup an ofile by persistent ID, and return ONLY if in state ORPHANED 953 * This is used by SMB2 create "reclaim". 954 */ 955 smb_ofile_t * 956 smb_ofile_lookup_by_persistid(smb_request_t *sr, uint64_t persistid) 957 { 958 smb_hash_t *hash; 959 smb_bucket_t *bucket; 960 smb_llist_t *ll; 961 smb_ofile_t *of; 962 uint_t idx; 963 964 hash = sr->sr_server->sv_persistid_ht; 965 idx = smb_hash_uint64(hash, persistid); 966 bucket = &hash->buckets[idx]; 967 ll = &bucket->b_list; 968 969 smb_llist_enter(ll, RW_READER); 970 of = smb_llist_head(ll); 971 while (of != NULL) { 972 if (of->f_persistid == persistid) 973 break; 974 of = smb_llist_next(ll, of); 975 } 976 if (of != NULL) 977 of = smb_ofile_hold_cb(of); 978 smb_llist_exit(ll); 979 980 return (of); 981 } 982 983 /* 984 * Create a (unique) persistent ID for a new ofile, 985 * and add this ofile to the persistid hash table. 986 */ 987 void 988 smb_ofile_set_persistid(smb_ofile_t *of) 989 { 990 smb_hash_t *hash = of->f_server->sv_persistid_ht; 991 smb_bucket_t *bucket; 992 smb_llist_t *ll; 993 uint_t idx; 994 995 of->f_persistid = SMB_OFILE_PERSISTID(of); 996 997 idx = smb_hash_uint64(hash, of->f_persistid); 998 bucket = &hash->buckets[idx]; 999 ll = &bucket->b_list; 1000 smb_llist_enter(ll, RW_WRITER); 1001 smb_llist_insert_tail(ll, of); 1002 smb_llist_exit(ll); 1003 } 1004 1005 void 1006 smb_ofile_del_persistid(smb_ofile_t *of) 1007 { 1008 smb_hash_t *hash = of->f_server->sv_persistid_ht; 1009 smb_bucket_t *bucket; 1010 smb_llist_t *ll; 1011 uint_t idx; 1012 1013 idx = smb_hash_uint64(hash, of->f_persistid); 1014 bucket = &hash->buckets[idx]; 1015 ll = &bucket->b_list; 1016 smb_llist_enter(ll, RW_WRITER); 1017 smb_llist_remove(ll, of); 1018 smb_llist_exit(ll); 1019 } 1020 1021 /* 1022 * Disallow NetFileClose on certain ofiles to avoid side-effects. 1023 * Closing a tree root is not allowed: use NetSessionDel or NetShareDel. 1024 * Closing SRVSVC connections is not allowed because this NetFileClose 1025 * request may depend on this ofile. 1026 */ 1027 boolean_t 1028 smb_ofile_disallow_fclose(smb_ofile_t *of) 1029 { 1030 ASSERT(of); 1031 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 1032 ASSERT(of->f_refcnt); 1033 1034 switch (of->f_ftype) { 1035 case SMB_FTYPE_DISK: 1036 ASSERT(of->f_tree); 1037 return (of->f_node == of->f_tree->t_snode); 1038 1039 case SMB_FTYPE_MESG_PIPE: 1040 ASSERT(of->f_pipe); 1041 if (smb_strcasecmp(of->f_pipe->p_name, "SRVSVC", 0) == 0) 1042 return (B_TRUE); 1043 break; 1044 default: 1045 break; 1046 } 1047 1048 return (B_FALSE); 1049 } 1050 1051 /* 1052 * smb_ofile_set_flags 1053 * 1054 * Return value: 1055 * 1056 * Current flags value 1057 * 1058 */ 1059 void 1060 smb_ofile_set_flags( 1061 smb_ofile_t *of, 1062 uint32_t flags) 1063 { 1064 ASSERT(of); 1065 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 1066 ASSERT(of->f_refcnt); 1067 1068 mutex_enter(&of->f_mutex); 1069 of->f_flags |= flags; 1070 mutex_exit(&of->f_mutex); 1071 } 1072 1073 /* 1074 * smb_ofile_seek 1075 * 1076 * Return value: 1077 * 1078 * 0 Success 1079 * EINVAL Unknown mode 1080 * EOVERFLOW offset too big 1081 * 1082 */ 1083 int 1084 smb_ofile_seek( 1085 smb_ofile_t *of, 1086 ushort_t mode, 1087 int32_t off, 1088 uint32_t *retoff) 1089 { 1090 u_offset_t newoff = 0; 1091 int rc = 0; 1092 smb_attr_t attr; 1093 1094 ASSERT(of); 1095 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 1096 ASSERT(of->f_refcnt); 1097 1098 mutex_enter(&of->f_mutex); 1099 switch (mode) { 1100 case SMB_SEEK_SET: 1101 if (off < 0) 1102 newoff = 0; 1103 else 1104 newoff = (u_offset_t)off; 1105 break; 1106 1107 case SMB_SEEK_CUR: 1108 if (off < 0 && (-off) > of->f_seek_pos) 1109 newoff = 0; 1110 else 1111 newoff = of->f_seek_pos + (u_offset_t)off; 1112 break; 1113 1114 case SMB_SEEK_END: 1115 bzero(&attr, sizeof (smb_attr_t)); 1116 attr.sa_mask |= SMB_AT_SIZE; 1117 rc = smb_fsop_getattr(NULL, zone_kcred(), of->f_node, &attr); 1118 if (rc != 0) { 1119 mutex_exit(&of->f_mutex); 1120 return (rc); 1121 } 1122 if (off < 0 && (-off) > attr.sa_vattr.va_size) 1123 newoff = 0; 1124 else 1125 newoff = attr.sa_vattr.va_size + (u_offset_t)off; 1126 break; 1127 1128 default: 1129 mutex_exit(&of->f_mutex); 1130 return (EINVAL); 1131 } 1132 1133 /* 1134 * See comments at the beginning of smb_seek.c. 1135 * If the offset is greater than UINT_MAX, we will return an error. 1136 */ 1137 1138 if (newoff > UINT_MAX) { 1139 rc = EOVERFLOW; 1140 } else { 1141 of->f_seek_pos = newoff; 1142 *retoff = (uint32_t)newoff; 1143 } 1144 mutex_exit(&of->f_mutex); 1145 return (rc); 1146 } 1147 1148 /* 1149 * smb_ofile_flush 1150 * 1151 * If writes on this file are not synchronous, flush it using the NFSv3 1152 * commit interface. 1153 * 1154 * XXX - todo: Flush named pipe should drain writes. 1155 */ 1156 void 1157 smb_ofile_flush(struct smb_request *sr, struct smb_ofile *of) 1158 { 1159 switch (of->f_ftype) { 1160 case SMB_FTYPE_DISK: 1161 if ((of->f_node->flags & NODE_FLAGS_WRITE_THROUGH) == 0) 1162 (void) smb_fsop_commit(sr, of->f_cr, of->f_node); 1163 break; 1164 default: 1165 break; 1166 } 1167 } 1168 1169 /* 1170 * smb_ofile_is_open 1171 */ 1172 boolean_t 1173 smb_ofile_is_open(smb_ofile_t *of) 1174 { 1175 boolean_t rc; 1176 1177 SMB_OFILE_VALID(of); 1178 1179 mutex_enter(&of->f_mutex); 1180 rc = smb_ofile_is_open_locked(of); 1181 mutex_exit(&of->f_mutex); 1182 return (rc); 1183 } 1184 1185 /* *************************** Static Functions ***************************** */ 1186 1187 /* 1188 * Determine whether or not an ofile is open. 1189 * This function must be called with the mutex held. 1190 */ 1191 static boolean_t 1192 smb_ofile_is_open_locked(smb_ofile_t *of) 1193 { 1194 ASSERT(MUTEX_HELD(&of->f_mutex)); 1195 1196 switch (of->f_state) { 1197 case SMB_OFILE_STATE_OPEN: 1198 case SMB_OFILE_STATE_SAVE_DH: 1199 case SMB_OFILE_STATE_SAVING: 1200 case SMB_OFILE_STATE_ORPHANED: 1201 case SMB_OFILE_STATE_RECONNECT: 1202 return (B_TRUE); 1203 1204 case SMB_OFILE_STATE_CLOSING: 1205 case SMB_OFILE_STATE_CLOSED: 1206 case SMB_OFILE_STATE_EXPIRED: 1207 return (B_FALSE); 1208 1209 default: 1210 ASSERT(0); 1211 return (B_FALSE); 1212 } 1213 } 1214 1215 /* 1216 * smb_ofile_save_dh 1217 * 1218 * Called via smb_llist_post (after smb_llist_exit) when the last ref. 1219 * on this ofile has gone, and this ofile is a "durable handle" (DH) 1220 * that has state we've decided to save. 1221 * 1222 * This does parts of what smb_ofile_delete would do, including: 1223 * remove the ofile from the tree ofile list and related. 1224 * 1225 * We leave the ofile in state ORPHANED, ready for reconnect 1226 * or expiration via smb2_dh_expire (see smb_ofile_delete). 1227 */ 1228 static void 1229 smb_ofile_save_dh(void *arg) 1230 { 1231 smb_ofile_t *of = (smb_ofile_t *)arg; 1232 smb_tree_t *tree = of->f_tree; 1233 1234 SMB_OFILE_VALID(of); 1235 ASSERT(of->f_refcnt == 0); 1236 ASSERT(of->f_ftype == SMB_FTYPE_DISK); 1237 ASSERT(of->f_state == SMB_OFILE_STATE_SAVING); 1238 1239 atomic_dec_32(&of->f_session->s_file_cnt); 1240 atomic_dec_32(&of->f_tree->t_open_files); 1241 smb_llist_enter(&tree->t_ofile_list, RW_WRITER); 1242 smb_llist_remove(&tree->t_ofile_list, of); 1243 smb_llist_exit(&tree->t_ofile_list); 1244 1245 /* 1246 * This ofile is no longer on t_ofile_list, however... 1247 * 1248 * This is called via smb_llist_post, which means it may run 1249 * BEFORE smb_ofile_release drops f_mutex (if another thread 1250 * flushes the delete queue before we do). Synchronize. 1251 */ 1252 mutex_enter(&of->f_mutex); 1253 DTRACE_PROBE1(ofile__exit, smb_ofile_t, of); 1254 mutex_exit(&of->f_mutex); 1255 1256 /* 1257 * Keep f_notify state, lease, and 1258 * keep on node ofile list. 1259 * Keep of->f_cr until reclaim. 1260 */ 1261 1262 ASSERT(of->f_fid != 0); 1263 smb_idpool_free(&tree->t_fid_pool, of->f_fid); 1264 of->f_fid = 0; 1265 smb_tree_release(of->f_tree); 1266 of->f_tree = NULL; 1267 smb_user_release(of->f_user); 1268 of->f_user = NULL; 1269 of->f_session = NULL; 1270 1271 /* 1272 * Make it "orphaned" so it can now be reclaimed. 1273 * Note that smb_ofile_hold_olbrk() may have blocked 1274 * for state SMB_OFILE_STATE_SAVING, so wake it. 1275 */ 1276 mutex_enter(&of->f_mutex); 1277 of->dh_expire_time = gethrtime() + of->dh_timeout_offset; 1278 of->f_state = SMB_OFILE_STATE_ORPHANED; 1279 cv_broadcast(&of->f_cv); 1280 mutex_exit(&of->f_mutex); 1281 } 1282 1283 /* 1284 * Delete an ofile. 1285 * 1286 * Approximately the inverse of smb_ofile_alloc() 1287 * Called via smb_llist_post (after smb_llist_exit) 1288 * when the last ref. on this ofile has gone. 1289 * 1290 * Normally,this removes the ofile from the tree list and 1291 * then frees resources held on the ofile. However, when 1292 * we're expiring an orphaned durable handle, the linkage 1293 * into the tree lists etc. have already been destroyed. 1294 * This case is distinguished by of->f_tree == NULL. 1295 */ 1296 static void 1297 smb_ofile_delete(void *arg) 1298 { 1299 smb_ofile_t *of = (smb_ofile_t *)arg; 1300 smb_tree_t *tree = of->f_tree; 1301 1302 SMB_OFILE_VALID(of); 1303 ASSERT(of->f_refcnt == 0); 1304 ASSERT(of->f_state == SMB_OFILE_STATE_CLOSED); 1305 1306 if (tree != NULL) { 1307 ASSERT(of->f_user != NULL); 1308 ASSERT(of->f_session != NULL); 1309 atomic_dec_32(&of->f_session->s_file_cnt); 1310 atomic_dec_32(&of->f_tree->t_open_files); 1311 smb_llist_enter(&tree->t_ofile_list, RW_WRITER); 1312 smb_llist_remove(&tree->t_ofile_list, of); 1313 smb_llist_exit(&tree->t_ofile_list); 1314 } 1315 1316 /* 1317 * Remove this ofile from the node's n_ofile_list so it 1318 * can't be found by list walkers like notify or oplock. 1319 * Keep the node ref. until later in this function so 1320 * of->f_node remains valid while we destroy the ofile. 1321 */ 1322 if (of->f_ftype == SMB_FTYPE_DISK || 1323 of->f_ftype == SMB_FTYPE_PRINTER) { 1324 ASSERT(of->f_node != NULL); 1325 /* 1326 * Note smb_ofile_close did smb_node_dec_open_ofiles() 1327 */ 1328 smb_node_rem_ofile(of->f_node, of); 1329 } 1330 1331 /* 1332 * This ofile is no longer on any lists, however... 1333 * 1334 * This is called via smb_llist_post, which means it may run 1335 * BEFORE smb_ofile_release drops f_mutex (if another thread 1336 * flushes the delete queue before we do). Synchronize. 1337 */ 1338 mutex_enter(&of->f_mutex); 1339 of->f_state = SMB_OFILE_STATE_ALLOC; 1340 DTRACE_PROBE1(ofile__exit, smb_ofile_t, of); 1341 mutex_exit(&of->f_mutex); 1342 1343 switch (of->f_ftype) { 1344 case SMB_FTYPE_BYTE_PIPE: 1345 case SMB_FTYPE_MESG_PIPE: 1346 smb_opipe_dealloc(of->f_pipe); 1347 of->f_pipe = NULL; 1348 break; 1349 case SMB_FTYPE_DISK: 1350 ASSERT(of->f_notify.nc_subscribed == B_FALSE); 1351 MBC_FLUSH(&of->f_notify.nc_buffer); 1352 if (of->f_odir != NULL) 1353 smb_odir_release(of->f_odir); 1354 if (of->f_lease != NULL) { 1355 smb2_lease_rele(of->f_lease); 1356 of->f_lease = NULL; 1357 } 1358 /* FALLTHROUGH */ 1359 case SMB_FTYPE_PRINTER: 1360 /* 1361 * Did smb_node_rem_ofile above. 1362 */ 1363 ASSERT(of->f_node != NULL); 1364 smb_node_release(of->f_node); 1365 break; 1366 default: 1367 ASSERT(!"f_ftype"); 1368 break; 1369 } 1370 1371 smb_ofile_free(of); 1372 } 1373 1374 void 1375 smb_ofile_free(smb_ofile_t *of) 1376 { 1377 smb_tree_t *tree = of->f_tree; 1378 1379 ASSERT(of->f_state == SMB_OFILE_STATE_ALLOC); 1380 1381 if (tree != NULL) { 1382 if (of->f_fid != 0) 1383 smb_idpool_free(&tree->t_fid_pool, of->f_fid); 1384 smb_tree_release(of->f_tree); 1385 smb_user_release(of->f_user); 1386 } 1387 1388 if (of->f_cr != NULL) 1389 crfree(of->f_cr); 1390 1391 of->f_magic = (uint32_t)~SMB_OFILE_MAGIC; 1392 list_destroy(&of->f_notify.nc_waiters); 1393 mutex_destroy(&of->f_mutex); 1394 kmem_cache_free(smb_cache_ofile, of); 1395 } 1396 1397 /* 1398 * smb_ofile_access 1399 * 1400 * This function will check to see if the access requested is granted. 1401 * Returns NT status codes. 1402 */ 1403 uint32_t 1404 smb_ofile_access(smb_ofile_t *of, cred_t *cr, uint32_t access) 1405 { 1406 1407 if ((of == NULL) || (cr == zone_kcred())) 1408 return (NT_STATUS_SUCCESS); 1409 1410 /* 1411 * If the request is for something 1412 * I don't grant it is an error 1413 */ 1414 if (~(of->f_granted_access) & access) { 1415 if (!(of->f_granted_access & ACCESS_SYSTEM_SECURITY) && 1416 (access & ACCESS_SYSTEM_SECURITY)) { 1417 return (NT_STATUS_PRIVILEGE_NOT_HELD); 1418 } 1419 return (NT_STATUS_ACCESS_DENIED); 1420 } 1421 1422 return (NT_STATUS_SUCCESS); 1423 } 1424 1425 /* 1426 * smb_ofile_share_check 1427 * 1428 * Check if ofile was opened with share access NONE (0). 1429 * Returns: B_TRUE - share access non-zero 1430 * B_FALSE - share access NONE 1431 */ 1432 boolean_t 1433 smb_ofile_share_check(smb_ofile_t *of) 1434 { 1435 return (!SMB_DENY_ALL(of->f_share_access)); 1436 } 1437 1438 /* 1439 * check file sharing rules for current open request 1440 * against existing open instances of the same file 1441 * 1442 * Returns NT_STATUS_SHARING_VIOLATION if there is any 1443 * sharing conflict, otherwise returns NT_STATUS_SUCCESS. 1444 */ 1445 uint32_t 1446 smb_ofile_open_check(smb_ofile_t *of, uint32_t desired_access, 1447 uint32_t share_access) 1448 { 1449 uint32_t ret; 1450 1451 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 1452 1453 mutex_enter(&of->f_mutex); 1454 1455 if (!smb_ofile_is_open_locked(of)) { 1456 ret = NT_STATUS_INVALID_HANDLE; 1457 goto out; 1458 } 1459 1460 /* if it's just meta data */ 1461 if ((of->f_granted_access & FILE_DATA_ALL) == 0) { 1462 ret = NT_STATUS_SUCCESS; 1463 goto out; 1464 } 1465 1466 /* 1467 * Check requested share access against the 1468 * open granted (desired) access 1469 */ 1470 if (SMB_DENY_DELETE(share_access) && (of->f_granted_access & DELETE)) { 1471 ret = NT_STATUS_SHARING_VIOLATION; 1472 goto out; 1473 } 1474 1475 if (SMB_DENY_READ(share_access) && 1476 (of->f_granted_access & (FILE_READ_DATA | FILE_EXECUTE))) { 1477 ret = NT_STATUS_SHARING_VIOLATION; 1478 goto out; 1479 } 1480 1481 if (SMB_DENY_WRITE(share_access) && 1482 (of->f_granted_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) { 1483 ret = NT_STATUS_SHARING_VIOLATION; 1484 goto out; 1485 } 1486 1487 /* check requested desired access against the open share access */ 1488 if (SMB_DENY_DELETE(of->f_share_access) && (desired_access & DELETE)) { 1489 ret = NT_STATUS_SHARING_VIOLATION; 1490 goto out; 1491 } 1492 1493 if (SMB_DENY_READ(of->f_share_access) && 1494 (desired_access & (FILE_READ_DATA | FILE_EXECUTE))) { 1495 ret = NT_STATUS_SHARING_VIOLATION; 1496 goto out; 1497 } 1498 1499 if (SMB_DENY_WRITE(of->f_share_access) && 1500 (desired_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) { 1501 ret = NT_STATUS_SHARING_VIOLATION; 1502 goto out; 1503 } 1504 1505 ret = NT_STATUS_SUCCESS; 1506 out: 1507 mutex_exit(&of->f_mutex); 1508 return (ret); 1509 } 1510 1511 /* 1512 * smb_ofile_rename_check 1513 * 1514 * This does the work described in MS-FSA 2.1.5.1.2.2 (Algorithm 1515 * to Check Sharing Access to an Existing Stream or Directory), 1516 * where the "open in-progress" has DesiredAccess = DELETE and 1517 * SharingMode = SHARE_READ | SHARE_WRITE | SHARE_DELETE. 1518 */ 1519 1520 uint32_t 1521 smb_ofile_rename_check(smb_ofile_t *of) 1522 { 1523 uint32_t ret; 1524 1525 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 1526 1527 mutex_enter(&of->f_mutex); 1528 1529 if (!smb_ofile_is_open_locked(of)) { 1530 ret = NT_STATUS_INVALID_HANDLE; 1531 goto out; 1532 } 1533 1534 if ((of->f_granted_access & FILE_DATA_ALL) == 0) { 1535 ret = NT_STATUS_SUCCESS; 1536 goto out; 1537 } 1538 1539 if ((of->f_share_access & FILE_SHARE_DELETE) == 0) { 1540 ret = NT_STATUS_SHARING_VIOLATION; 1541 goto out; 1542 } 1543 1544 ret = NT_STATUS_SUCCESS; 1545 out: 1546 mutex_exit(&of->f_mutex); 1547 return (ret); 1548 } 1549 1550 /* 1551 * smb_ofile_delete_check 1552 * 1553 * An open file can be deleted only if opened for 1554 * accessing meta data. Share modes aren't important 1555 * in this case. 1556 * 1557 * NOTE: there is another mechanism for deleting an 1558 * open file that NT clients usually use. 1559 * That's setting "Delete on close" flag for an open 1560 * file. In this way the file will be deleted after 1561 * last close. This flag can be set by SmbTrans2SetFileInfo 1562 * with FILE_DISPOSITION_INFO information level. 1563 * For setting this flag, the file should be opened by 1564 * DELETE access in the FID that is passed in the Trans2 1565 * request. 1566 */ 1567 1568 uint32_t 1569 smb_ofile_delete_check(smb_ofile_t *of) 1570 { 1571 uint32_t ret; 1572 1573 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 1574 1575 mutex_enter(&of->f_mutex); 1576 1577 if (!smb_ofile_is_open_locked(of)) { 1578 ret = NT_STATUS_INVALID_HANDLE; 1579 goto out; 1580 } 1581 1582 if (of->f_granted_access & 1583 (FILE_READ_DATA | FILE_WRITE_DATA | 1584 FILE_APPEND_DATA | FILE_EXECUTE | DELETE)) { 1585 ret = NT_STATUS_SHARING_VIOLATION; 1586 goto out; 1587 } 1588 1589 ret = NT_STATUS_SUCCESS; 1590 out: 1591 mutex_exit(&of->f_mutex); 1592 return (ret); 1593 } 1594 1595 cred_t * 1596 smb_ofile_getcred(smb_ofile_t *of) 1597 { 1598 return (of->f_cr); 1599 } 1600 1601 /* 1602 * smb_ofile_set_delete_on_close 1603 * 1604 * Set the DeleteOnClose flag on the smb file. When the file is closed, 1605 * the flag will be transferred to the smb node, which will commit the 1606 * delete operation and inhibit subsequent open requests. 1607 * 1608 * When DeleteOnClose is set on an smb_node, the common open code will 1609 * reject subsequent open requests for the file. Observation of Windows 1610 * 2000 indicates that subsequent opens should be allowed (assuming 1611 * there would be no sharing violation) until the file is closed using 1612 * the fid on which the DeleteOnClose was requested. 1613 */ 1614 void 1615 smb_ofile_set_delete_on_close(smb_request_t *sr, smb_ofile_t *of) 1616 { 1617 uint32_t status; 1618 1619 /* 1620 * Break any oplock handle caching. 1621 */ 1622 status = smb_oplock_break_SETINFO(of->f_node, of, 1623 FileDispositionInformation); 1624 if (status == NT_STATUS_OPLOCK_BREAK_IN_PROGRESS) { 1625 if (sr->session->dialect >= SMB_VERS_2_BASE) 1626 (void) smb2sr_go_async(sr); 1627 (void) smb_oplock_wait_break(of->f_node, 0); 1628 } 1629 1630 mutex_enter(&of->f_mutex); 1631 of->f_flags |= SMB_OFLAGS_SET_DELETE_ON_CLOSE; 1632 mutex_exit(&of->f_mutex); 1633 } 1634 1635 /* 1636 * Encode open file information into a buffer; needed in user space to 1637 * support RPC requests. 1638 */ 1639 static int 1640 smb_ofile_netinfo_encode(smb_ofile_t *of, uint8_t *buf, size_t buflen, 1641 uint32_t *nbytes) 1642 { 1643 smb_netfileinfo_t fi; 1644 int rc; 1645 1646 rc = smb_ofile_netinfo_init(of, &fi); 1647 if (rc == 0) { 1648 rc = smb_netfileinfo_encode(&fi, buf, buflen, nbytes); 1649 smb_ofile_netinfo_fini(&fi); 1650 } 1651 1652 return (rc); 1653 } 1654 1655 static int 1656 smb_ofile_netinfo_init(smb_ofile_t *of, smb_netfileinfo_t *fi) 1657 { 1658 smb_user_t *user; 1659 smb_tree_t *tree; 1660 smb_node_t *node; 1661 char *path; 1662 char *buf; 1663 int rc; 1664 1665 ASSERT(of); 1666 user = of->f_user; 1667 tree = of->f_tree; 1668 ASSERT(user); 1669 ASSERT(tree); 1670 1671 buf = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 1672 1673 switch (of->f_ftype) { 1674 case SMB_FTYPE_DISK: 1675 node = of->f_node; 1676 ASSERT(node); 1677 1678 fi->fi_permissions = of->f_granted_access; 1679 fi->fi_numlocks = smb_lock_get_lock_count(node, of); 1680 1681 path = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 1682 1683 if (node != tree->t_snode) { 1684 rc = smb_node_getshrpath(node, tree, path, MAXPATHLEN); 1685 if (rc != 0) 1686 (void) strlcpy(path, node->od_name, MAXPATHLEN); 1687 } 1688 1689 (void) snprintf(buf, MAXPATHLEN, "%s:%s", tree->t_sharename, 1690 path); 1691 kmem_free(path, MAXPATHLEN); 1692 break; 1693 1694 case SMB_FTYPE_MESG_PIPE: 1695 ASSERT(of->f_pipe); 1696 1697 fi->fi_permissions = FILE_READ_DATA | FILE_WRITE_DATA | 1698 FILE_EXECUTE; 1699 fi->fi_numlocks = 0; 1700 (void) snprintf(buf, MAXPATHLEN, "\\PIPE\\%s", 1701 of->f_pipe->p_name); 1702 break; 1703 1704 default: 1705 kmem_free(buf, MAXPATHLEN); 1706 return (-1); 1707 } 1708 1709 fi->fi_fid = of->f_fid; 1710 fi->fi_uniqid = of->f_uniqid; 1711 fi->fi_pathlen = strlen(buf) + 1; 1712 fi->fi_path = smb_mem_strdup(buf); 1713 kmem_free(buf, MAXPATHLEN); 1714 1715 fi->fi_namelen = user->u_domain_len + user->u_name_len + 2; 1716 fi->fi_username = kmem_alloc(fi->fi_namelen, KM_SLEEP); 1717 (void) snprintf(fi->fi_username, fi->fi_namelen, "%s\\%s", 1718 user->u_domain, user->u_name); 1719 return (0); 1720 } 1721 1722 static void 1723 smb_ofile_netinfo_fini(smb_netfileinfo_t *fi) 1724 { 1725 if (fi == NULL) 1726 return; 1727 1728 if (fi->fi_path) 1729 smb_mem_free(fi->fi_path); 1730 if (fi->fi_username) 1731 kmem_free(fi->fi_username, fi->fi_namelen); 1732 1733 bzero(fi, sizeof (smb_netfileinfo_t)); 1734 } 1735 1736 /* 1737 * A query of user and group quotas may span multiple requests. 1738 * f_quota_resume is used to determine where the query should 1739 * be resumed, in a subsequent request. f_quota_resume contains 1740 * the SID of the last quota entry returned to the client. 1741 */ 1742 void 1743 smb_ofile_set_quota_resume(smb_ofile_t *ofile, char *resume) 1744 { 1745 ASSERT(ofile); 1746 mutex_enter(&ofile->f_mutex); 1747 if (resume == NULL) 1748 bzero(ofile->f_quota_resume, SMB_SID_STRSZ); 1749 else 1750 (void) strlcpy(ofile->f_quota_resume, resume, SMB_SID_STRSZ); 1751 mutex_exit(&ofile->f_mutex); 1752 } 1753 1754 void 1755 smb_ofile_get_quota_resume(smb_ofile_t *ofile, char *buf, int bufsize) 1756 { 1757 ASSERT(ofile); 1758 mutex_enter(&ofile->f_mutex); 1759 (void) strlcpy(buf, ofile->f_quota_resume, bufsize); 1760 mutex_exit(&ofile->f_mutex); 1761 } 1762