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 2019 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 * | 77 * | T1 78 * | 79 * v 80 * +-------------------------+ 81 * | SMB_OFILE_STATE_CLOSING | 82 * +-------------------------+ 83 * | 84 * | T2 85 * | 86 * v 87 * +-------------------------+ T3 88 * | SMB_OFILE_STATE_CLOSED |----------> Deletion/Free 89 * +-------------------------+ 90 * 91 * SMB_OFILE_STATE_OPEN 92 * 93 * While in this state: 94 * - The ofile is queued in the list of ofiles of its tree. 95 * - References will be given out if the ofile is looked up. 96 * 97 * SMB_OFILE_STATE_CLOSING 98 * 99 * While in this state: 100 * - The ofile is queued in the list of ofiles of its tree. 101 * - References will not be given out if the ofile is looked up. 102 * - The file is closed and the locks held are being released. 103 * - The resources associated with the ofile remain. 104 * 105 * SMB_OFILE_STATE_CLOSED 106 * 107 * While in this state: 108 * - The ofile is queued in the list of ofiles of its tree. 109 * - References will not be given out if the ofile is looked up. 110 * - The resources associated with the ofile remain. 111 * 112 * Transition T0 113 * 114 * This transition occurs in smb_ofile_open(). A new ofile is created and 115 * added to the list of ofiles of a tree. 116 * 117 * Transition T1 118 * 119 * This transition occurs in smb_ofile_close(). 120 * 121 * Transition T2 122 * 123 * This transition occurs in smb_ofile_release(). The resources associated 124 * with the ofile are freed as well as the ofile structure. For the 125 * transition to occur, the ofile must be in the SMB_OFILE_STATE_CLOSED 126 * state and the reference count be zero. 127 * 128 * Comments 129 * -------- 130 * 131 * The state machine of the ofile structures is controlled by 3 elements: 132 * - The list of ofiles of the tree it belongs to. 133 * - The mutex embedded in the structure itself. 134 * - The reference count. 135 * 136 * There's a mutex embedded in the ofile structure used to protect its fields 137 * and there's a lock embedded in the list of ofiles of a tree. To 138 * increment or to decrement the reference count the mutex must be entered. 139 * To insert the ofile into the list of ofiles of the tree and to remove 140 * the ofile from it, the lock must be entered in RW_WRITER mode. 141 * 142 * Rules of access to a ofile structure: 143 * 144 * 1) In order to avoid deadlocks, when both (mutex and lock of the ofile 145 * list) have to be entered, the lock must be entered first. 146 * 147 * 2) All actions applied to an ofile require a reference count. 148 * 149 * 3) There are 2 ways of getting a reference count. One is when the ofile 150 * is opened. The other one when the ofile is looked up. This translates 151 * into 2 functions: smb_ofile_open() and smb_ofile_lookup_by_fid(). 152 * 153 * It should be noted that the reference count of an ofile registers the 154 * number of references to the ofile in other structures (such as an smb 155 * request). The reference count is not incremented in these 2 instances: 156 * 157 * 1) The ofile is open. An ofile is anchored by its state. If there's 158 * no activity involving an ofile currently open, the reference count 159 * of that ofile is zero. 160 * 161 * 2) The ofile is queued in the list of ofiles of its tree. The fact of 162 * being queued in that list is NOT registered by incrementing the 163 * reference count. 164 */ 165 #include <smbsrv/smb_kproto.h> 166 #include <smbsrv/smb_fsops.h> 167 168 static boolean_t smb_ofile_is_open_locked(smb_ofile_t *); 169 static smb_ofile_t *smb_ofile_close_and_next(smb_ofile_t *); 170 static int smb_ofile_netinfo_encode(smb_ofile_t *, uint8_t *, size_t, 171 uint32_t *); 172 static int smb_ofile_netinfo_init(smb_ofile_t *, smb_netfileinfo_t *); 173 static void smb_ofile_netinfo_fini(smb_netfileinfo_t *); 174 175 /* 176 * smb_ofile_open 177 */ 178 smb_ofile_t * 179 smb_ofile_open( 180 smb_request_t *sr, 181 smb_node_t *node, 182 struct open_param *op, 183 uint16_t ftype, 184 uint32_t uniqid, 185 smb_error_t *err) 186 { 187 smb_tree_t *tree = sr->tid_tree; 188 smb_ofile_t *of; 189 uint16_t fid; 190 smb_attr_t attr; 191 int rc; 192 193 if (smb_idpool_alloc(&tree->t_fid_pool, &fid)) { 194 err->status = NT_STATUS_TOO_MANY_OPENED_FILES; 195 err->errcls = ERRDOS; 196 err->errcode = ERROR_TOO_MANY_OPEN_FILES; 197 return (NULL); 198 } 199 200 of = kmem_cache_alloc(smb_cache_ofile, KM_SLEEP); 201 bzero(of, sizeof (smb_ofile_t)); 202 of->f_magic = SMB_OFILE_MAGIC; 203 204 mutex_init(&of->f_mutex, NULL, MUTEX_DEFAULT, NULL); 205 list_create(&of->f_notify.nc_waiters, sizeof (smb_request_t), 206 offsetof(smb_request_t, sr_waiters)); 207 208 of->f_state = SMB_OFILE_STATE_OPEN; 209 of->f_refcnt = 1; 210 of->f_fid = fid; 211 of->f_uniqid = uniqid; 212 of->f_opened_by_pid = sr->smb_pid; 213 of->f_granted_access = op->desired_access; 214 of->f_share_access = op->share_access; 215 of->f_create_options = op->create_options; 216 of->f_cr = (op->create_options & FILE_OPEN_FOR_BACKUP_INTENT) ? 217 smb_user_getprivcred(sr->uid_user) : sr->uid_user->u_cred; 218 crhold(of->f_cr); 219 of->f_ftype = ftype; 220 of->f_server = tree->t_server; 221 of->f_session = tree->t_session; 222 223 /* 224 * grab a ref for of->f_user 225 * released in smb_ofile_delete() 226 */ 227 smb_user_hold_internal(sr->uid_user); 228 of->f_user = sr->uid_user; 229 of->f_tree = tree; 230 of->f_node = node; 231 232 if (ftype == SMB_FTYPE_MESG_PIPE) { 233 /* See smb_opipe_open. */ 234 of->f_pipe = op->pipe; 235 smb_server_inc_pipes(of->f_server); 236 } else { 237 ASSERT(ftype == SMB_FTYPE_DISK); /* Regular file, not a pipe */ 238 ASSERT(node); 239 240 /* 241 * Note that the common open path often adds bits like 242 * READ_CONTROL, so the logic "is this open exec-only" 243 * needs to look at only the FILE_DATA_ALL bits. 244 */ 245 if ((of->f_granted_access & FILE_DATA_ALL) == FILE_EXECUTE) 246 of->f_flags |= SMB_OFLAGS_EXECONLY; 247 248 /* 249 * This is an "internal" getattr because we need the 250 * UID and DOS attributes. Don't want to fail here 251 * due to permissions, so use kcred. 252 */ 253 bzero(&attr, sizeof (smb_attr_t)); 254 attr.sa_mask = SMB_AT_UID | SMB_AT_DOSATTR; 255 rc = smb_node_getattr(NULL, node, zone_kcred(), NULL, &attr); 256 if (rc != 0) { 257 err->status = NT_STATUS_INTERNAL_ERROR; 258 err->errcls = ERRDOS; 259 err->errcode = ERROR_INTERNAL_ERROR; 260 goto errout; 261 } 262 if (crgetuid(of->f_cr) == attr.sa_vattr.va_uid) { 263 /* 264 * Add this bit for the file's owner even if it's not 265 * specified in the request (Windows behavior). 266 */ 267 of->f_granted_access |= FILE_READ_ATTRIBUTES; 268 } 269 270 if (smb_node_is_file(node)) { 271 of->f_mode = 272 smb_fsop_amask_to_omode(of->f_granted_access); 273 if (smb_fsop_open(node, of->f_mode, of->f_cr) != 0) { 274 err->status = NT_STATUS_ACCESS_DENIED; 275 err->errcls = ERRDOS; 276 err->errcode = ERROR_ACCESS_DENIED; 277 goto errout; 278 } 279 } 280 281 if (tree->t_flags & SMB_TREE_READONLY) 282 of->f_flags |= SMB_OFLAGS_READONLY; 283 284 /* 285 * Note that if we created_readonly, that 286 * will _not_ yet show in attr.sa_dosattr 287 * so creating a readonly file gives the 288 * caller a writable handle as it should. 289 */ 290 if (attr.sa_dosattr & FILE_ATTRIBUTE_READONLY) 291 of->f_flags |= SMB_OFLAGS_READONLY; 292 293 smb_node_inc_open_ofiles(node); 294 smb_node_add_ofile(node, of); 295 smb_node_ref(node); 296 smb_server_inc_files(of->f_server); 297 } 298 smb_llist_enter(&tree->t_ofile_list, RW_WRITER); 299 smb_llist_insert_tail(&tree->t_ofile_list, of); 300 smb_llist_exit(&tree->t_ofile_list); 301 atomic_inc_32(&tree->t_open_files); 302 atomic_inc_32(&of->f_session->s_file_cnt); 303 return (of); 304 305 errout: 306 smb_user_release(of->f_user); 307 crfree(of->f_cr); 308 309 list_destroy(&of->f_notify.nc_waiters); 310 mutex_destroy(&of->f_mutex); 311 312 of->f_magic = 0; 313 kmem_cache_free(smb_cache_ofile, of); 314 315 smb_idpool_free(&tree->t_fid_pool, fid); 316 317 return (NULL); 318 } 319 320 /* 321 * smb_ofile_close 322 */ 323 void 324 smb_ofile_close(smb_ofile_t *of, int32_t mtime_sec) 325 { 326 smb_attr_t *pa; 327 timestruc_t now; 328 uint32_t flags = 0; 329 330 SMB_OFILE_VALID(of); 331 332 mutex_enter(&of->f_mutex); 333 ASSERT(of->f_refcnt); 334 if (of->f_state != SMB_OFILE_STATE_OPEN) { 335 mutex_exit(&of->f_mutex); 336 return; 337 } 338 of->f_state = SMB_OFILE_STATE_CLOSING; 339 mutex_exit(&of->f_mutex); 340 341 switch (of->f_ftype) { 342 case SMB_FTYPE_BYTE_PIPE: 343 case SMB_FTYPE_MESG_PIPE: 344 smb_opipe_close(of); 345 smb_server_dec_pipes(of->f_server); 346 break; 347 348 case SMB_FTYPE_DISK: 349 case SMB_FTYPE_PRINTER: 350 /* 351 * In here we make changes to of->f_pending_attr 352 * while not holding of->f_mutex. This is OK 353 * because we've changed f_state to CLOSING, 354 * so no more threads will take this path. 355 */ 356 pa = &of->f_pending_attr; 357 if (mtime_sec != 0) { 358 pa->sa_vattr.va_mtime.tv_sec = mtime_sec; 359 pa->sa_mask |= SMB_AT_MTIME; 360 } 361 362 /* 363 * If we have ever modified data via this handle 364 * (write or truncate) and if the mtime was not 365 * set via this handle, update the mtime again 366 * during the close. Windows expects this. 367 * [ MS-FSA 2.1.5.4 "Update Timestamps" ] 368 */ 369 if (of->f_written && 370 (pa->sa_mask & SMB_AT_MTIME) == 0) { 371 pa->sa_mask |= SMB_AT_MTIME; 372 gethrestime(&now); 373 pa->sa_vattr.va_mtime = now; 374 } 375 376 if (of->f_flags & SMB_OFLAGS_SET_DELETE_ON_CLOSE) { 377 if (smb_tree_has_feature(of->f_tree, 378 SMB_TREE_CATIA)) { 379 flags |= SMB_CATIA; 380 } 381 (void) smb_node_set_delete_on_close(of->f_node, 382 of->f_cr, flags); 383 } 384 smb_fsop_unshrlock(of->f_cr, of->f_node, of->f_uniqid); 385 smb_node_destroy_lock_by_ofile(of->f_node, of); 386 387 if (smb_node_is_file(of->f_node)) { 388 (void) smb_fsop_close(of->f_node, of->f_mode, 389 of->f_cr); 390 smb_oplock_release(of->f_node, of); 391 } else { 392 /* 393 * If there was an odir, close it. 394 */ 395 if (of->f_odir != NULL) 396 smb_odir_close(of->f_odir); 397 /* 398 * Cancel any notify change requests that 399 * might be watching this open file (dir), 400 * and unsubscribe it from node events. 401 * 402 * Can't hold f_mutex when calling smb_notify_ofile. 403 * Don't really need it when unsubscribing, but 404 * harmless, and consistent with subscribing. 405 */ 406 if (of->f_notify.nc_subscribed) 407 smb_notify_ofile(of, 408 FILE_ACTION_HANDLE_CLOSED, NULL); 409 mutex_enter(&of->f_mutex); 410 if (of->f_notify.nc_subscribed) { 411 of->f_notify.nc_subscribed = B_FALSE; 412 smb_node_fcn_unsubscribe(of->f_node); 413 of->f_notify.nc_filter = 0; 414 } 415 mutex_exit(&of->f_mutex); 416 } 417 if (smb_node_dec_open_ofiles(of->f_node) == 0) { 418 /* 419 * Last close. The f_pending_attr has 420 * only times (atime,ctime,mtime) so 421 * we can borrow it to commit the 422 * n_pending_dosattr from the node. 423 */ 424 pa->sa_dosattr = 425 of->f_node->n_pending_dosattr; 426 if (pa->sa_dosattr != 0) 427 pa->sa_mask |= SMB_AT_DOSATTR; 428 /* Let's leave this zero when not in use. */ 429 of->f_node->n_allocsz = 0; 430 } 431 if (pa->sa_mask != 0) { 432 /* 433 * Commit any pending attributes from 434 * the ofile we're closing. Note that 435 * we pass NULL as the ofile to setattr 436 * so it will write to the file system 437 * and not keep anything on the ofile. 438 * This clears n_pending_dosattr if 439 * there are no opens, otherwise the 440 * dosattr will be pending again. 441 */ 442 (void) smb_node_setattr(NULL, of->f_node, 443 of->f_cr, NULL, pa); 444 } 445 446 smb_server_dec_files(of->f_server); 447 break; 448 } 449 atomic_dec_32(&of->f_tree->t_open_files); 450 451 mutex_enter(&of->f_mutex); 452 ASSERT(of->f_refcnt); 453 ASSERT(of->f_state == SMB_OFILE_STATE_CLOSING); 454 of->f_state = SMB_OFILE_STATE_CLOSED; 455 mutex_exit(&of->f_mutex); 456 } 457 458 /* 459 * smb_ofile_close_all 460 * 461 * 462 */ 463 void 464 smb_ofile_close_all( 465 smb_tree_t *tree) 466 { 467 smb_ofile_t *of; 468 469 ASSERT(tree); 470 ASSERT(tree->t_magic == SMB_TREE_MAGIC); 471 472 smb_llist_enter(&tree->t_ofile_list, RW_READER); 473 of = smb_llist_head(&tree->t_ofile_list); 474 while (of) { 475 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 476 ASSERT(of->f_tree == tree); 477 of = smb_ofile_close_and_next(of); 478 } 479 smb_llist_exit(&tree->t_ofile_list); 480 } 481 482 /* 483 * smb_ofiles_close_by_pid 484 * 485 * 486 */ 487 void 488 smb_ofile_close_all_by_pid( 489 smb_tree_t *tree, 490 uint16_t pid) 491 { 492 smb_ofile_t *of; 493 494 ASSERT(tree); 495 ASSERT(tree->t_magic == SMB_TREE_MAGIC); 496 497 smb_llist_enter(&tree->t_ofile_list, RW_READER); 498 of = smb_llist_head(&tree->t_ofile_list); 499 while (of) { 500 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 501 ASSERT(of->f_tree == tree); 502 if (of->f_opened_by_pid == pid) { 503 of = smb_ofile_close_and_next(of); 504 } else { 505 of = smb_llist_next(&tree->t_ofile_list, of); 506 } 507 } 508 smb_llist_exit(&tree->t_ofile_list); 509 } 510 511 /* 512 * If the enumeration request is for ofile data, handle it here. 513 * Otherwise, return. 514 * 515 * This function should be called with a hold on the ofile. 516 */ 517 int 518 smb_ofile_enum(smb_ofile_t *of, smb_svcenum_t *svcenum) 519 { 520 uint8_t *pb; 521 uint_t nbytes; 522 int rc; 523 524 ASSERT(of); 525 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 526 ASSERT(of->f_refcnt); 527 528 if (svcenum->se_type != SMB_SVCENUM_TYPE_FILE) 529 return (0); 530 531 if (svcenum->se_nskip > 0) { 532 svcenum->se_nskip--; 533 return (0); 534 } 535 536 if (svcenum->se_nitems >= svcenum->se_nlimit) { 537 svcenum->se_nitems = svcenum->se_nlimit; 538 return (0); 539 } 540 541 pb = &svcenum->se_buf[svcenum->se_bused]; 542 543 rc = smb_ofile_netinfo_encode(of, pb, svcenum->se_bavail, 544 &nbytes); 545 if (rc == 0) { 546 svcenum->se_bavail -= nbytes; 547 svcenum->se_bused += nbytes; 548 svcenum->se_nitems++; 549 } 550 551 return (rc); 552 } 553 554 /* 555 * Take a reference on an open file. 556 */ 557 boolean_t 558 smb_ofile_hold(smb_ofile_t *of) 559 { 560 ASSERT(of); 561 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 562 563 mutex_enter(&of->f_mutex); 564 565 if (of->f_state != SMB_OFILE_STATE_OPEN) { 566 mutex_exit(&of->f_mutex); 567 return (B_FALSE); 568 } 569 of->f_refcnt++; 570 571 mutex_exit(&of->f_mutex); 572 return (B_TRUE); 573 } 574 575 /* 576 * Release a reference on a file. If the reference count falls to 577 * zero and the file has been closed, post the object for deletion. 578 * Object deletion is deferred to avoid modifying a list while an 579 * iteration may be in progress. 580 */ 581 void 582 smb_ofile_release(smb_ofile_t *of) 583 { 584 SMB_OFILE_VALID(of); 585 586 mutex_enter(&of->f_mutex); 587 ASSERT(of->f_refcnt); 588 of->f_refcnt--; 589 switch (of->f_state) { 590 case SMB_OFILE_STATE_OPEN: 591 case SMB_OFILE_STATE_CLOSING: 592 break; 593 594 case SMB_OFILE_STATE_CLOSED: 595 if (of->f_refcnt == 0) 596 smb_tree_post_ofile(of->f_tree, of); 597 break; 598 599 default: 600 ASSERT(0); 601 break; 602 } 603 mutex_exit(&of->f_mutex); 604 } 605 606 /* 607 * smb_ofile_request_complete 608 * 609 * During oplock acquisition, all other oplock requests on the node 610 * are blocked until the acquire request completes and the response 611 * is on the wire. 612 * Call smb_oplock_broadcast to notify the node that the request 613 * has completed. 614 * 615 * THIS MECHANISM RELIES ON THE FACT THAT THE OFILE IS NOT REMOVED 616 * FROM THE SR UNTIL REQUEST COMPLETION (when the sr is destroyed) 617 */ 618 void 619 smb_ofile_request_complete(smb_ofile_t *of) 620 { 621 SMB_OFILE_VALID(of); 622 623 switch (of->f_ftype) { 624 case SMB_FTYPE_DISK: 625 ASSERT(of->f_node); 626 smb_oplock_broadcast(of->f_node); 627 break; 628 case SMB_FTYPE_MESG_PIPE: 629 break; 630 default: 631 break; 632 } 633 } 634 635 /* 636 * smb_ofile_lookup_by_fid 637 * 638 * Find the open file whose fid matches the one specified in the request. 639 * If we can't find the fid or the shares (trees) don't match, we have a 640 * bad fid. 641 */ 642 smb_ofile_t * 643 smb_ofile_lookup_by_fid( 644 smb_request_t *sr, 645 uint16_t fid) 646 { 647 smb_tree_t *tree = sr->tid_tree; 648 smb_llist_t *of_list; 649 smb_ofile_t *of; 650 651 ASSERT(tree->t_magic == SMB_TREE_MAGIC); 652 653 of_list = &tree->t_ofile_list; 654 655 smb_llist_enter(of_list, RW_READER); 656 of = smb_llist_head(of_list); 657 while (of) { 658 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 659 ASSERT(of->f_tree == tree); 660 if (of->f_fid == fid) 661 break; 662 of = smb_llist_next(of_list, of); 663 } 664 if (of == NULL) 665 goto out; 666 667 /* 668 * Only allow use of a given FID with the same UID that 669 * was used to open it. MS-CIFS 3.3.5.14 670 */ 671 if (of->f_user != sr->uid_user) { 672 of = NULL; 673 goto out; 674 } 675 676 mutex_enter(&of->f_mutex); 677 if (of->f_state != SMB_OFILE_STATE_OPEN) { 678 mutex_exit(&of->f_mutex); 679 of = NULL; 680 goto out; 681 } 682 of->f_refcnt++; 683 mutex_exit(&of->f_mutex); 684 685 out: 686 smb_llist_exit(of_list); 687 return (of); 688 } 689 690 /* 691 * smb_ofile_lookup_by_uniqid 692 * 693 * Find the open file whose uniqid matches the one specified in the request. 694 */ 695 smb_ofile_t * 696 smb_ofile_lookup_by_uniqid(smb_tree_t *tree, uint32_t uniqid) 697 { 698 smb_llist_t *of_list; 699 smb_ofile_t *of; 700 701 ASSERT(tree->t_magic == SMB_TREE_MAGIC); 702 703 of_list = &tree->t_ofile_list; 704 smb_llist_enter(of_list, RW_READER); 705 of = smb_llist_head(of_list); 706 707 while (of) { 708 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 709 ASSERT(of->f_tree == tree); 710 711 if (of->f_uniqid == uniqid) { 712 if (smb_ofile_hold(of)) { 713 smb_llist_exit(of_list); 714 return (of); 715 } 716 } 717 718 of = smb_llist_next(of_list, of); 719 } 720 721 smb_llist_exit(of_list); 722 return (NULL); 723 } 724 725 /* 726 * Disallow NetFileClose on certain ofiles to avoid side-effects. 727 * Closing a tree root is not allowed: use NetSessionDel or NetShareDel. 728 * Closing SRVSVC connections is not allowed because this NetFileClose 729 * request may depend on this ofile. 730 */ 731 boolean_t 732 smb_ofile_disallow_fclose(smb_ofile_t *of) 733 { 734 ASSERT(of); 735 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 736 ASSERT(of->f_refcnt); 737 738 switch (of->f_ftype) { 739 case SMB_FTYPE_DISK: 740 ASSERT(of->f_tree); 741 return (of->f_node == of->f_tree->t_snode); 742 743 case SMB_FTYPE_MESG_PIPE: 744 ASSERT(of->f_pipe); 745 if (smb_strcasecmp(of->f_pipe->p_name, "SRVSVC", 0) == 0) 746 return (B_TRUE); 747 break; 748 default: 749 break; 750 } 751 752 return (B_FALSE); 753 } 754 755 /* 756 * smb_ofile_set_flags 757 * 758 * Return value: 759 * 760 * Current flags value 761 * 762 */ 763 void 764 smb_ofile_set_flags( 765 smb_ofile_t *of, 766 uint32_t flags) 767 { 768 ASSERT(of); 769 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 770 ASSERT(of->f_refcnt); 771 772 mutex_enter(&of->f_mutex); 773 of->f_flags |= flags; 774 mutex_exit(&of->f_mutex); 775 } 776 777 /* 778 * smb_ofile_seek 779 * 780 * Return value: 781 * 782 * 0 Success 783 * EINVAL Unknown mode 784 * EOVERFLOW offset too big 785 * 786 */ 787 int 788 smb_ofile_seek( 789 smb_ofile_t *of, 790 ushort_t mode, 791 int32_t off, 792 uint32_t *retoff) 793 { 794 u_offset_t newoff = 0; 795 int rc = 0; 796 smb_attr_t attr; 797 798 ASSERT(of); 799 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 800 ASSERT(of->f_refcnt); 801 802 mutex_enter(&of->f_mutex); 803 switch (mode) { 804 case SMB_SEEK_SET: 805 if (off < 0) 806 newoff = 0; 807 else 808 newoff = (u_offset_t)off; 809 break; 810 811 case SMB_SEEK_CUR: 812 if (off < 0 && (-off) > of->f_seek_pos) 813 newoff = 0; 814 else 815 newoff = of->f_seek_pos + (u_offset_t)off; 816 break; 817 818 case SMB_SEEK_END: 819 bzero(&attr, sizeof (smb_attr_t)); 820 attr.sa_mask |= SMB_AT_SIZE; 821 rc = smb_fsop_getattr(NULL, zone_kcred(), of->f_node, &attr); 822 if (rc != 0) { 823 mutex_exit(&of->f_mutex); 824 return (rc); 825 } 826 if (off < 0 && (-off) > attr.sa_vattr.va_size) 827 newoff = 0; 828 else 829 newoff = attr.sa_vattr.va_size + (u_offset_t)off; 830 break; 831 832 default: 833 mutex_exit(&of->f_mutex); 834 return (EINVAL); 835 } 836 837 /* 838 * See comments at the beginning of smb_seek.c. 839 * If the offset is greater than UINT_MAX, we will return an error. 840 */ 841 842 if (newoff > UINT_MAX) { 843 rc = EOVERFLOW; 844 } else { 845 of->f_seek_pos = newoff; 846 *retoff = (uint32_t)newoff; 847 } 848 mutex_exit(&of->f_mutex); 849 return (rc); 850 } 851 852 /* 853 * smb_ofile_flush 854 * 855 * If writes on this file are not synchronous, flush it using the NFSv3 856 * commit interface. 857 * 858 * XXX - todo: Flush named pipe should drain writes. 859 */ 860 void 861 smb_ofile_flush(struct smb_request *sr, struct smb_ofile *of) 862 { 863 switch (of->f_ftype) { 864 case SMB_FTYPE_DISK: 865 if ((of->f_node->flags & NODE_FLAGS_WRITE_THROUGH) == 0) 866 (void) smb_fsop_commit(sr, of->f_cr, of->f_node); 867 break; 868 default: 869 break; 870 } 871 } 872 873 /* 874 * smb_ofile_is_open 875 */ 876 boolean_t 877 smb_ofile_is_open(smb_ofile_t *of) 878 { 879 boolean_t rc; 880 881 SMB_OFILE_VALID(of); 882 883 mutex_enter(&of->f_mutex); 884 rc = smb_ofile_is_open_locked(of); 885 mutex_exit(&of->f_mutex); 886 return (rc); 887 } 888 889 /* *************************** Static Functions ***************************** */ 890 891 /* 892 * Determine whether or not an ofile is open. 893 * This function must be called with the mutex held. 894 */ 895 static boolean_t 896 smb_ofile_is_open_locked(smb_ofile_t *of) 897 { 898 switch (of->f_state) { 899 case SMB_OFILE_STATE_OPEN: 900 return (B_TRUE); 901 902 case SMB_OFILE_STATE_CLOSING: 903 case SMB_OFILE_STATE_CLOSED: 904 return (B_FALSE); 905 906 default: 907 ASSERT(0); 908 return (B_FALSE); 909 } 910 } 911 912 /* 913 * This function closes the file passed in (if appropriate) and returns the 914 * next open file in the list of open files of the tree of the open file passed 915 * in. It requires that the list of open files of the tree be entered in 916 * RW_READER mode before being called. 917 */ 918 static smb_ofile_t * 919 smb_ofile_close_and_next(smb_ofile_t *of) 920 { 921 smb_ofile_t *next_of; 922 smb_tree_t *tree; 923 924 ASSERT(of); 925 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 926 927 mutex_enter(&of->f_mutex); 928 switch (of->f_state) { 929 case SMB_OFILE_STATE_OPEN: 930 /* The file is still open. */ 931 of->f_refcnt++; 932 ASSERT(of->f_refcnt); 933 tree = of->f_tree; 934 mutex_exit(&of->f_mutex); 935 smb_llist_exit(&of->f_tree->t_ofile_list); 936 smb_ofile_close(of, 0); 937 smb_ofile_release(of); 938 smb_llist_enter(&tree->t_ofile_list, RW_READER); 939 next_of = smb_llist_head(&tree->t_ofile_list); 940 break; 941 case SMB_OFILE_STATE_CLOSING: 942 case SMB_OFILE_STATE_CLOSED: 943 /* 944 * The ofile exists but is closed or 945 * in the process being closed. 946 */ 947 mutex_exit(&of->f_mutex); 948 next_of = smb_llist_next(&of->f_tree->t_ofile_list, of); 949 break; 950 default: 951 ASSERT(0); 952 mutex_exit(&of->f_mutex); 953 next_of = smb_llist_next(&of->f_tree->t_ofile_list, of); 954 break; 955 } 956 return (next_of); 957 } 958 959 /* 960 * Delete an ofile. 961 * 962 * Remove the ofile from the tree list before freeing resources 963 * associated with the ofile. 964 */ 965 void 966 smb_ofile_delete(void *arg) 967 { 968 smb_tree_t *tree; 969 smb_ofile_t *of = (smb_ofile_t *)arg; 970 971 SMB_OFILE_VALID(of); 972 ASSERT(of->f_refcnt == 0); 973 ASSERT(of->f_state == SMB_OFILE_STATE_CLOSED); 974 ASSERT(!SMB_OFILE_OPLOCK_GRANTED(of)); 975 976 tree = of->f_tree; 977 smb_llist_enter(&tree->t_ofile_list, RW_WRITER); 978 smb_llist_remove(&tree->t_ofile_list, of); 979 smb_idpool_free(&tree->t_fid_pool, of->f_fid); 980 atomic_dec_32(&tree->t_session->s_file_cnt); 981 smb_llist_exit(&tree->t_ofile_list); 982 983 /* 984 * Remove this ofile from the node's n_ofile_list so it 985 * can't be found by list walkers like notify or oplock. 986 * Keep the node ref. until later in this function so 987 * of->f_node remains valid while we destroy the ofile. 988 */ 989 if (of->f_ftype == SMB_FTYPE_DISK || 990 of->f_ftype == SMB_FTYPE_PRINTER) { 991 ASSERT(of->f_node != NULL); 992 /* 993 * Note smb_ofile_close did smb_node_dec_open_ofiles() 994 */ 995 smb_node_rem_ofile(of->f_node, of); 996 } 997 998 mutex_enter(&of->f_mutex); 999 mutex_exit(&of->f_mutex); 1000 1001 switch (of->f_ftype) { 1002 case SMB_FTYPE_BYTE_PIPE: 1003 case SMB_FTYPE_MESG_PIPE: 1004 smb_opipe_dealloc(of->f_pipe); 1005 of->f_pipe = NULL; 1006 break; 1007 case SMB_FTYPE_DISK: 1008 ASSERT(of->f_notify.nc_subscribed == B_FALSE); 1009 MBC_FLUSH(&of->f_notify.nc_buffer); 1010 if (of->f_odir != NULL) 1011 smb_odir_release(of->f_odir); 1012 /* FALLTHROUGH */ 1013 case SMB_FTYPE_PRINTER: 1014 /* 1015 * Did smb_node_rem_ofile above. 1016 */ 1017 ASSERT(of->f_node != NULL); 1018 smb_node_release(of->f_node); 1019 break; 1020 default: 1021 ASSERT(!"f_ftype"); 1022 break; 1023 } 1024 1025 of->f_magic = (uint32_t)~SMB_OFILE_MAGIC; 1026 list_destroy(&of->f_notify.nc_waiters); 1027 mutex_destroy(&of->f_mutex); 1028 smb_user_release(of->f_user); 1029 crfree(of->f_cr); 1030 kmem_cache_free(smb_cache_ofile, of); 1031 } 1032 1033 /* 1034 * smb_ofile_access 1035 * 1036 * This function will check to see if the access requested is granted. 1037 * Returns NT status codes. 1038 */ 1039 uint32_t 1040 smb_ofile_access(smb_ofile_t *of, cred_t *cr, uint32_t access) 1041 { 1042 1043 if ((of == NULL) || (cr == zone_kcred())) 1044 return (NT_STATUS_SUCCESS); 1045 1046 /* 1047 * If the request is for something 1048 * I don't grant it is an error 1049 */ 1050 if (~(of->f_granted_access) & access) { 1051 if (!(of->f_granted_access & ACCESS_SYSTEM_SECURITY) && 1052 (access & ACCESS_SYSTEM_SECURITY)) { 1053 return (NT_STATUS_PRIVILEGE_NOT_HELD); 1054 } 1055 return (NT_STATUS_ACCESS_DENIED); 1056 } 1057 1058 return (NT_STATUS_SUCCESS); 1059 } 1060 1061 /* 1062 * smb_ofile_share_check 1063 * 1064 * Check if ofile was opened with share access NONE (0). 1065 * Returns: B_TRUE - share access non-zero 1066 * B_FALSE - share access NONE 1067 */ 1068 boolean_t 1069 smb_ofile_share_check(smb_ofile_t *of) 1070 { 1071 return (!SMB_DENY_ALL(of->f_share_access)); 1072 } 1073 1074 /* 1075 * check file sharing rules for current open request 1076 * against existing open instances of the same file 1077 * 1078 * Returns NT_STATUS_SHARING_VIOLATION if there is any 1079 * sharing conflict, otherwise returns NT_STATUS_SUCCESS. 1080 */ 1081 uint32_t 1082 smb_ofile_open_check(smb_ofile_t *of, uint32_t desired_access, 1083 uint32_t share_access) 1084 { 1085 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 1086 1087 mutex_enter(&of->f_mutex); 1088 1089 if (of->f_state != SMB_OFILE_STATE_OPEN) { 1090 mutex_exit(&of->f_mutex); 1091 return (NT_STATUS_INVALID_HANDLE); 1092 } 1093 1094 /* if it's just meta data */ 1095 if ((of->f_granted_access & FILE_DATA_ALL) == 0) { 1096 mutex_exit(&of->f_mutex); 1097 return (NT_STATUS_SUCCESS); 1098 } 1099 1100 /* 1101 * Check requested share access against the 1102 * open granted (desired) access 1103 */ 1104 if (SMB_DENY_DELETE(share_access) && (of->f_granted_access & DELETE)) { 1105 mutex_exit(&of->f_mutex); 1106 return (NT_STATUS_SHARING_VIOLATION); 1107 } 1108 1109 if (SMB_DENY_READ(share_access) && 1110 (of->f_granted_access & (FILE_READ_DATA | FILE_EXECUTE))) { 1111 mutex_exit(&of->f_mutex); 1112 return (NT_STATUS_SHARING_VIOLATION); 1113 } 1114 1115 if (SMB_DENY_WRITE(share_access) && 1116 (of->f_granted_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) { 1117 mutex_exit(&of->f_mutex); 1118 return (NT_STATUS_SHARING_VIOLATION); 1119 } 1120 1121 /* check requested desired access against the open share access */ 1122 if (SMB_DENY_DELETE(of->f_share_access) && (desired_access & DELETE)) { 1123 mutex_exit(&of->f_mutex); 1124 return (NT_STATUS_SHARING_VIOLATION); 1125 } 1126 1127 if (SMB_DENY_READ(of->f_share_access) && 1128 (desired_access & (FILE_READ_DATA | FILE_EXECUTE))) { 1129 mutex_exit(&of->f_mutex); 1130 return (NT_STATUS_SHARING_VIOLATION); 1131 } 1132 1133 if (SMB_DENY_WRITE(of->f_share_access) && 1134 (desired_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) { 1135 mutex_exit(&of->f_mutex); 1136 return (NT_STATUS_SHARING_VIOLATION); 1137 } 1138 1139 mutex_exit(&of->f_mutex); 1140 return (NT_STATUS_SUCCESS); 1141 } 1142 1143 /* 1144 * smb_ofile_rename_check 1145 * 1146 * This does the work described in MS-FSA 2.1.5.1.2.2 (Algorithm 1147 * to Check Sharing Access to an Existing Stream or Directory), 1148 * where the "open in-progress" has DesiredAccess = DELETE and 1149 * SharingMode = SHARE_READ | SHARE_WRITE | SHARE_DELETE. 1150 */ 1151 1152 uint32_t 1153 smb_ofile_rename_check(smb_ofile_t *of) 1154 { 1155 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 1156 1157 mutex_enter(&of->f_mutex); 1158 1159 if (of->f_state != SMB_OFILE_STATE_OPEN) { 1160 mutex_exit(&of->f_mutex); 1161 return (NT_STATUS_INVALID_HANDLE); 1162 } 1163 1164 if ((of->f_granted_access & FILE_DATA_ALL) == 0) { 1165 mutex_exit(&of->f_mutex); 1166 return (NT_STATUS_SUCCESS); 1167 } 1168 1169 if ((of->f_share_access & FILE_SHARE_DELETE) == 0) { 1170 mutex_exit(&of->f_mutex); 1171 return (NT_STATUS_SHARING_VIOLATION); 1172 } 1173 1174 mutex_exit(&of->f_mutex); 1175 return (NT_STATUS_SUCCESS); 1176 } 1177 1178 /* 1179 * smb_ofile_delete_check 1180 * 1181 * An open file can be deleted only if opened for 1182 * accessing meta data. Share modes aren't important 1183 * in this case. 1184 * 1185 * NOTE: there is another mechanism for deleting an 1186 * open file that NT clients usually use. 1187 * That's setting "Delete on close" flag for an open 1188 * file. In this way the file will be deleted after 1189 * last close. This flag can be set by SmbTrans2SetFileInfo 1190 * with FILE_DISPOSITION_INFO information level. 1191 * For setting this flag, the file should be opened by 1192 * DELETE access in the FID that is passed in the Trans2 1193 * request. 1194 */ 1195 1196 uint32_t 1197 smb_ofile_delete_check(smb_ofile_t *of) 1198 { 1199 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 1200 1201 mutex_enter(&of->f_mutex); 1202 1203 if (of->f_state != SMB_OFILE_STATE_OPEN) { 1204 mutex_exit(&of->f_mutex); 1205 return (NT_STATUS_INVALID_HANDLE); 1206 } 1207 1208 if (of->f_granted_access & 1209 (FILE_READ_DATA | FILE_WRITE_DATA | 1210 FILE_APPEND_DATA | FILE_EXECUTE | DELETE)) { 1211 mutex_exit(&of->f_mutex); 1212 return (NT_STATUS_SHARING_VIOLATION); 1213 } 1214 1215 mutex_exit(&of->f_mutex); 1216 return (NT_STATUS_SUCCESS); 1217 } 1218 1219 cred_t * 1220 smb_ofile_getcred(smb_ofile_t *of) 1221 { 1222 return (of->f_cr); 1223 } 1224 1225 /* 1226 * smb_ofile_set_delete_on_close 1227 * 1228 * Set the DeleteOnClose flag on the smb file. When the file is closed, 1229 * the flag will be transferred to the smb node, which will commit the 1230 * delete operation and inhibit subsequent open requests. 1231 * 1232 * When DeleteOnClose is set on an smb_node, the common open code will 1233 * reject subsequent open requests for the file. Observation of Windows 1234 * 2000 indicates that subsequent opens should be allowed (assuming 1235 * there would be no sharing violation) until the file is closed using 1236 * the fid on which the DeleteOnClose was requested. 1237 */ 1238 void 1239 smb_ofile_set_delete_on_close(smb_ofile_t *of) 1240 { 1241 mutex_enter(&of->f_mutex); 1242 of->f_flags |= SMB_OFLAGS_SET_DELETE_ON_CLOSE; 1243 mutex_exit(&of->f_mutex); 1244 } 1245 1246 /* 1247 * Encode open file information into a buffer; needed in user space to 1248 * support RPC requests. 1249 */ 1250 static int 1251 smb_ofile_netinfo_encode(smb_ofile_t *of, uint8_t *buf, size_t buflen, 1252 uint32_t *nbytes) 1253 { 1254 smb_netfileinfo_t fi; 1255 int rc; 1256 1257 rc = smb_ofile_netinfo_init(of, &fi); 1258 if (rc == 0) { 1259 rc = smb_netfileinfo_encode(&fi, buf, buflen, nbytes); 1260 smb_ofile_netinfo_fini(&fi); 1261 } 1262 1263 return (rc); 1264 } 1265 1266 static int 1267 smb_ofile_netinfo_init(smb_ofile_t *of, smb_netfileinfo_t *fi) 1268 { 1269 smb_user_t *user; 1270 smb_tree_t *tree; 1271 smb_node_t *node; 1272 char *path; 1273 char *buf; 1274 int rc; 1275 1276 ASSERT(of); 1277 user = of->f_user; 1278 tree = of->f_tree; 1279 ASSERT(user); 1280 ASSERT(tree); 1281 1282 buf = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 1283 1284 switch (of->f_ftype) { 1285 case SMB_FTYPE_DISK: 1286 node = of->f_node; 1287 ASSERT(node); 1288 1289 fi->fi_permissions = of->f_granted_access; 1290 fi->fi_numlocks = smb_lock_get_lock_count(node, of); 1291 1292 path = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 1293 1294 if (node != tree->t_snode) { 1295 rc = smb_node_getshrpath(node, tree, path, MAXPATHLEN); 1296 if (rc != 0) 1297 (void) strlcpy(path, node->od_name, MAXPATHLEN); 1298 } 1299 1300 (void) snprintf(buf, MAXPATHLEN, "%s:%s", tree->t_sharename, 1301 path); 1302 kmem_free(path, MAXPATHLEN); 1303 break; 1304 1305 case SMB_FTYPE_MESG_PIPE: 1306 ASSERT(of->f_pipe); 1307 1308 fi->fi_permissions = FILE_READ_DATA | FILE_WRITE_DATA | 1309 FILE_EXECUTE; 1310 fi->fi_numlocks = 0; 1311 (void) snprintf(buf, MAXPATHLEN, "\\PIPE\\%s", 1312 of->f_pipe->p_name); 1313 break; 1314 1315 default: 1316 kmem_free(buf, MAXPATHLEN); 1317 return (-1); 1318 } 1319 1320 fi->fi_fid = of->f_fid; 1321 fi->fi_uniqid = of->f_uniqid; 1322 fi->fi_pathlen = strlen(buf) + 1; 1323 fi->fi_path = smb_mem_strdup(buf); 1324 kmem_free(buf, MAXPATHLEN); 1325 1326 fi->fi_namelen = user->u_domain_len + user->u_name_len + 2; 1327 fi->fi_username = kmem_alloc(fi->fi_namelen, KM_SLEEP); 1328 (void) snprintf(fi->fi_username, fi->fi_namelen, "%s\\%s", 1329 user->u_domain, user->u_name); 1330 return (0); 1331 } 1332 1333 static void 1334 smb_ofile_netinfo_fini(smb_netfileinfo_t *fi) 1335 { 1336 if (fi == NULL) 1337 return; 1338 1339 if (fi->fi_path) 1340 smb_mem_free(fi->fi_path); 1341 if (fi->fi_username) 1342 kmem_free(fi->fi_username, fi->fi_namelen); 1343 1344 bzero(fi, sizeof (smb_netfileinfo_t)); 1345 } 1346 1347 /* 1348 * A query of user and group quotas may span multiple requests. 1349 * f_quota_resume is used to determine where the query should 1350 * be resumed, in a subsequent request. f_quota_resume contains 1351 * the SID of the last quota entry returned to the client. 1352 */ 1353 void 1354 smb_ofile_set_quota_resume(smb_ofile_t *ofile, char *resume) 1355 { 1356 ASSERT(ofile); 1357 mutex_enter(&ofile->f_mutex); 1358 if (resume == NULL) 1359 bzero(ofile->f_quota_resume, SMB_SID_STRSZ); 1360 else 1361 (void) strlcpy(ofile->f_quota_resume, resume, SMB_SID_STRSZ); 1362 mutex_exit(&ofile->f_mutex); 1363 } 1364 1365 void 1366 smb_ofile_get_quota_resume(smb_ofile_t *ofile, char *buf, int bufsize) 1367 { 1368 ASSERT(ofile); 1369 mutex_enter(&ofile->f_mutex); 1370 (void) strlcpy(buf, ofile->f_quota_resume, bufsize); 1371 mutex_exit(&ofile->f_mutex); 1372 } 1373