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 mutex_enter(&of->f_node->n_mutex); 431 if (of->f_node->flags & NODE_FLAGS_DELETE_ON_CLOSE) { 432 smb_node_delete_on_close(of->f_node); 433 pa->sa_mask = 0; 434 } 435 mutex_exit(&of->f_node->n_mutex); 436 } 437 if (pa->sa_mask != 0) { 438 /* 439 * Commit any pending attributes from 440 * the ofile we're closing. Note that 441 * we pass NULL as the ofile to setattr 442 * so it will write to the file system 443 * and not keep anything on the ofile. 444 * This clears n_pending_dosattr if 445 * there are no opens, otherwise the 446 * dosattr will be pending again. 447 */ 448 (void) smb_node_setattr(NULL, of->f_node, 449 of->f_cr, NULL, pa); 450 } 451 452 smb_server_dec_files(of->f_server); 453 break; 454 } 455 atomic_dec_32(&of->f_tree->t_open_files); 456 457 mutex_enter(&of->f_mutex); 458 ASSERT(of->f_refcnt); 459 ASSERT(of->f_state == SMB_OFILE_STATE_CLOSING); 460 of->f_state = SMB_OFILE_STATE_CLOSED; 461 mutex_exit(&of->f_mutex); 462 } 463 464 /* 465 * smb_ofile_close_all 466 * 467 * 468 */ 469 void 470 smb_ofile_close_all( 471 smb_tree_t *tree) 472 { 473 smb_ofile_t *of; 474 475 ASSERT(tree); 476 ASSERT(tree->t_magic == SMB_TREE_MAGIC); 477 478 smb_llist_enter(&tree->t_ofile_list, RW_READER); 479 of = smb_llist_head(&tree->t_ofile_list); 480 while (of) { 481 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 482 ASSERT(of->f_tree == tree); 483 of = smb_ofile_close_and_next(of); 484 } 485 smb_llist_exit(&tree->t_ofile_list); 486 } 487 488 /* 489 * smb_ofiles_close_by_pid 490 * 491 * 492 */ 493 void 494 smb_ofile_close_all_by_pid( 495 smb_tree_t *tree, 496 uint16_t pid) 497 { 498 smb_ofile_t *of; 499 500 ASSERT(tree); 501 ASSERT(tree->t_magic == SMB_TREE_MAGIC); 502 503 smb_llist_enter(&tree->t_ofile_list, RW_READER); 504 of = smb_llist_head(&tree->t_ofile_list); 505 while (of) { 506 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 507 ASSERT(of->f_tree == tree); 508 if (of->f_opened_by_pid == pid) { 509 of = smb_ofile_close_and_next(of); 510 } else { 511 of = smb_llist_next(&tree->t_ofile_list, of); 512 } 513 } 514 smb_llist_exit(&tree->t_ofile_list); 515 } 516 517 /* 518 * If the enumeration request is for ofile data, handle it here. 519 * Otherwise, return. 520 * 521 * This function should be called with a hold on the ofile. 522 */ 523 int 524 smb_ofile_enum(smb_ofile_t *of, smb_svcenum_t *svcenum) 525 { 526 uint8_t *pb; 527 uint_t nbytes; 528 int rc; 529 530 ASSERT(of); 531 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 532 ASSERT(of->f_refcnt); 533 534 if (svcenum->se_type != SMB_SVCENUM_TYPE_FILE) 535 return (0); 536 537 if (svcenum->se_nskip > 0) { 538 svcenum->se_nskip--; 539 return (0); 540 } 541 542 if (svcenum->se_nitems >= svcenum->se_nlimit) { 543 svcenum->se_nitems = svcenum->se_nlimit; 544 return (0); 545 } 546 547 pb = &svcenum->se_buf[svcenum->se_bused]; 548 549 rc = smb_ofile_netinfo_encode(of, pb, svcenum->se_bavail, 550 &nbytes); 551 if (rc == 0) { 552 svcenum->se_bavail -= nbytes; 553 svcenum->se_bused += nbytes; 554 svcenum->se_nitems++; 555 } 556 557 return (rc); 558 } 559 560 /* 561 * Take a reference on an open file. 562 */ 563 boolean_t 564 smb_ofile_hold(smb_ofile_t *of) 565 { 566 ASSERT(of); 567 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 568 569 mutex_enter(&of->f_mutex); 570 571 if (of->f_state != SMB_OFILE_STATE_OPEN) { 572 mutex_exit(&of->f_mutex); 573 return (B_FALSE); 574 } 575 of->f_refcnt++; 576 577 mutex_exit(&of->f_mutex); 578 return (B_TRUE); 579 } 580 581 /* 582 * Release a reference on a file. If the reference count falls to 583 * zero and the file has been closed, post the object for deletion. 584 * Object deletion is deferred to avoid modifying a list while an 585 * iteration may be in progress. 586 */ 587 void 588 smb_ofile_release(smb_ofile_t *of) 589 { 590 SMB_OFILE_VALID(of); 591 592 mutex_enter(&of->f_mutex); 593 ASSERT(of->f_refcnt); 594 of->f_refcnt--; 595 switch (of->f_state) { 596 case SMB_OFILE_STATE_OPEN: 597 case SMB_OFILE_STATE_CLOSING: 598 break; 599 600 case SMB_OFILE_STATE_CLOSED: 601 if (of->f_refcnt == 0) 602 smb_tree_post_ofile(of->f_tree, of); 603 break; 604 605 default: 606 ASSERT(0); 607 break; 608 } 609 mutex_exit(&of->f_mutex); 610 } 611 612 /* 613 * smb_ofile_request_complete 614 * 615 * During oplock acquisition, all other oplock requests on the node 616 * are blocked until the acquire request completes and the response 617 * is on the wire. 618 * Call smb_oplock_broadcast to notify the node that the request 619 * has completed. 620 * 621 * THIS MECHANISM RELIES ON THE FACT THAT THE OFILE IS NOT REMOVED 622 * FROM THE SR UNTIL REQUEST COMPLETION (when the sr is destroyed) 623 */ 624 void 625 smb_ofile_request_complete(smb_ofile_t *of) 626 { 627 SMB_OFILE_VALID(of); 628 629 switch (of->f_ftype) { 630 case SMB_FTYPE_DISK: 631 ASSERT(of->f_node); 632 smb_oplock_broadcast(of->f_node); 633 break; 634 case SMB_FTYPE_MESG_PIPE: 635 break; 636 default: 637 break; 638 } 639 } 640 641 /* 642 * smb_ofile_lookup_by_fid 643 * 644 * Find the open file whose fid matches the one specified in the request. 645 * If we can't find the fid or the shares (trees) don't match, we have a 646 * bad fid. 647 */ 648 smb_ofile_t * 649 smb_ofile_lookup_by_fid( 650 smb_request_t *sr, 651 uint16_t fid) 652 { 653 smb_tree_t *tree = sr->tid_tree; 654 smb_llist_t *of_list; 655 smb_ofile_t *of; 656 657 ASSERT(tree->t_magic == SMB_TREE_MAGIC); 658 659 of_list = &tree->t_ofile_list; 660 661 smb_llist_enter(of_list, RW_READER); 662 of = smb_llist_head(of_list); 663 while (of) { 664 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 665 ASSERT(of->f_tree == tree); 666 if (of->f_fid == fid) 667 break; 668 of = smb_llist_next(of_list, of); 669 } 670 if (of == NULL) 671 goto out; 672 673 /* 674 * Only allow use of a given FID with the same UID that 675 * was used to open it. MS-CIFS 3.3.5.14 676 */ 677 if (of->f_user != sr->uid_user) { 678 of = NULL; 679 goto out; 680 } 681 682 mutex_enter(&of->f_mutex); 683 if (of->f_state != SMB_OFILE_STATE_OPEN) { 684 mutex_exit(&of->f_mutex); 685 of = NULL; 686 goto out; 687 } 688 of->f_refcnt++; 689 mutex_exit(&of->f_mutex); 690 691 out: 692 smb_llist_exit(of_list); 693 return (of); 694 } 695 696 /* 697 * smb_ofile_lookup_by_uniqid 698 * 699 * Find the open file whose uniqid matches the one specified in the request. 700 */ 701 smb_ofile_t * 702 smb_ofile_lookup_by_uniqid(smb_tree_t *tree, uint32_t uniqid) 703 { 704 smb_llist_t *of_list; 705 smb_ofile_t *of; 706 707 ASSERT(tree->t_magic == SMB_TREE_MAGIC); 708 709 of_list = &tree->t_ofile_list; 710 smb_llist_enter(of_list, RW_READER); 711 of = smb_llist_head(of_list); 712 713 while (of) { 714 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 715 ASSERT(of->f_tree == tree); 716 717 if (of->f_uniqid == uniqid) { 718 if (smb_ofile_hold(of)) { 719 smb_llist_exit(of_list); 720 return (of); 721 } 722 } 723 724 of = smb_llist_next(of_list, of); 725 } 726 727 smb_llist_exit(of_list); 728 return (NULL); 729 } 730 731 /* 732 * Disallow NetFileClose on certain ofiles to avoid side-effects. 733 * Closing a tree root is not allowed: use NetSessionDel or NetShareDel. 734 * Closing SRVSVC connections is not allowed because this NetFileClose 735 * request may depend on this ofile. 736 */ 737 boolean_t 738 smb_ofile_disallow_fclose(smb_ofile_t *of) 739 { 740 ASSERT(of); 741 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 742 ASSERT(of->f_refcnt); 743 744 switch (of->f_ftype) { 745 case SMB_FTYPE_DISK: 746 ASSERT(of->f_tree); 747 return (of->f_node == of->f_tree->t_snode); 748 749 case SMB_FTYPE_MESG_PIPE: 750 ASSERT(of->f_pipe); 751 if (smb_strcasecmp(of->f_pipe->p_name, "SRVSVC", 0) == 0) 752 return (B_TRUE); 753 break; 754 default: 755 break; 756 } 757 758 return (B_FALSE); 759 } 760 761 /* 762 * smb_ofile_set_flags 763 * 764 * Return value: 765 * 766 * Current flags value 767 * 768 */ 769 void 770 smb_ofile_set_flags( 771 smb_ofile_t *of, 772 uint32_t flags) 773 { 774 ASSERT(of); 775 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 776 ASSERT(of->f_refcnt); 777 778 mutex_enter(&of->f_mutex); 779 of->f_flags |= flags; 780 mutex_exit(&of->f_mutex); 781 } 782 783 /* 784 * smb_ofile_seek 785 * 786 * Return value: 787 * 788 * 0 Success 789 * EINVAL Unknown mode 790 * EOVERFLOW offset too big 791 * 792 */ 793 int 794 smb_ofile_seek( 795 smb_ofile_t *of, 796 ushort_t mode, 797 int32_t off, 798 uint32_t *retoff) 799 { 800 u_offset_t newoff = 0; 801 int rc = 0; 802 smb_attr_t attr; 803 804 ASSERT(of); 805 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 806 ASSERT(of->f_refcnt); 807 808 mutex_enter(&of->f_mutex); 809 switch (mode) { 810 case SMB_SEEK_SET: 811 if (off < 0) 812 newoff = 0; 813 else 814 newoff = (u_offset_t)off; 815 break; 816 817 case SMB_SEEK_CUR: 818 if (off < 0 && (-off) > of->f_seek_pos) 819 newoff = 0; 820 else 821 newoff = of->f_seek_pos + (u_offset_t)off; 822 break; 823 824 case SMB_SEEK_END: 825 bzero(&attr, sizeof (smb_attr_t)); 826 attr.sa_mask |= SMB_AT_SIZE; 827 rc = smb_fsop_getattr(NULL, zone_kcred(), of->f_node, &attr); 828 if (rc != 0) { 829 mutex_exit(&of->f_mutex); 830 return (rc); 831 } 832 if (off < 0 && (-off) > attr.sa_vattr.va_size) 833 newoff = 0; 834 else 835 newoff = attr.sa_vattr.va_size + (u_offset_t)off; 836 break; 837 838 default: 839 mutex_exit(&of->f_mutex); 840 return (EINVAL); 841 } 842 843 /* 844 * See comments at the beginning of smb_seek.c. 845 * If the offset is greater than UINT_MAX, we will return an error. 846 */ 847 848 if (newoff > UINT_MAX) { 849 rc = EOVERFLOW; 850 } else { 851 of->f_seek_pos = newoff; 852 *retoff = (uint32_t)newoff; 853 } 854 mutex_exit(&of->f_mutex); 855 return (rc); 856 } 857 858 /* 859 * smb_ofile_flush 860 * 861 * If writes on this file are not synchronous, flush it using the NFSv3 862 * commit interface. 863 * 864 * XXX - todo: Flush named pipe should drain writes. 865 */ 866 void 867 smb_ofile_flush(struct smb_request *sr, struct smb_ofile *of) 868 { 869 switch (of->f_ftype) { 870 case SMB_FTYPE_DISK: 871 if ((of->f_node->flags & NODE_FLAGS_WRITE_THROUGH) == 0) 872 (void) smb_fsop_commit(sr, of->f_cr, of->f_node); 873 break; 874 default: 875 break; 876 } 877 } 878 879 /* 880 * smb_ofile_is_open 881 */ 882 boolean_t 883 smb_ofile_is_open(smb_ofile_t *of) 884 { 885 boolean_t rc; 886 887 SMB_OFILE_VALID(of); 888 889 mutex_enter(&of->f_mutex); 890 rc = smb_ofile_is_open_locked(of); 891 mutex_exit(&of->f_mutex); 892 return (rc); 893 } 894 895 /* *************************** Static Functions ***************************** */ 896 897 /* 898 * Determine whether or not an ofile is open. 899 * This function must be called with the mutex held. 900 */ 901 static boolean_t 902 smb_ofile_is_open_locked(smb_ofile_t *of) 903 { 904 switch (of->f_state) { 905 case SMB_OFILE_STATE_OPEN: 906 return (B_TRUE); 907 908 case SMB_OFILE_STATE_CLOSING: 909 case SMB_OFILE_STATE_CLOSED: 910 return (B_FALSE); 911 912 default: 913 ASSERT(0); 914 return (B_FALSE); 915 } 916 } 917 918 /* 919 * This function closes the file passed in (if appropriate) and returns the 920 * next open file in the list of open files of the tree of the open file passed 921 * in. It requires that the list of open files of the tree be entered in 922 * RW_READER mode before being called. 923 */ 924 static smb_ofile_t * 925 smb_ofile_close_and_next(smb_ofile_t *of) 926 { 927 smb_ofile_t *next_of; 928 smb_tree_t *tree; 929 930 ASSERT(of); 931 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 932 933 mutex_enter(&of->f_mutex); 934 switch (of->f_state) { 935 case SMB_OFILE_STATE_OPEN: 936 /* The file is still open. */ 937 of->f_refcnt++; 938 ASSERT(of->f_refcnt); 939 tree = of->f_tree; 940 mutex_exit(&of->f_mutex); 941 smb_llist_exit(&of->f_tree->t_ofile_list); 942 smb_ofile_close(of, 0); 943 smb_ofile_release(of); 944 smb_llist_enter(&tree->t_ofile_list, RW_READER); 945 next_of = smb_llist_head(&tree->t_ofile_list); 946 break; 947 case SMB_OFILE_STATE_CLOSING: 948 case SMB_OFILE_STATE_CLOSED: 949 /* 950 * The ofile exists but is closed or 951 * in the process being closed. 952 */ 953 mutex_exit(&of->f_mutex); 954 next_of = smb_llist_next(&of->f_tree->t_ofile_list, of); 955 break; 956 default: 957 ASSERT(0); 958 mutex_exit(&of->f_mutex); 959 next_of = smb_llist_next(&of->f_tree->t_ofile_list, of); 960 break; 961 } 962 return (next_of); 963 } 964 965 /* 966 * Delete an ofile. 967 * 968 * Remove the ofile from the tree list before freeing resources 969 * associated with the ofile. 970 */ 971 void 972 smb_ofile_delete(void *arg) 973 { 974 smb_tree_t *tree; 975 smb_ofile_t *of = (smb_ofile_t *)arg; 976 977 SMB_OFILE_VALID(of); 978 ASSERT(of->f_refcnt == 0); 979 ASSERT(of->f_state == SMB_OFILE_STATE_CLOSED); 980 ASSERT(!SMB_OFILE_OPLOCK_GRANTED(of)); 981 982 tree = of->f_tree; 983 smb_llist_enter(&tree->t_ofile_list, RW_WRITER); 984 smb_llist_remove(&tree->t_ofile_list, of); 985 smb_idpool_free(&tree->t_fid_pool, of->f_fid); 986 atomic_dec_32(&tree->t_session->s_file_cnt); 987 smb_llist_exit(&tree->t_ofile_list); 988 989 /* 990 * Remove this ofile from the node's n_ofile_list so it 991 * can't be found by list walkers like notify or oplock. 992 * Keep the node ref. until later in this function so 993 * of->f_node remains valid while we destroy the ofile. 994 */ 995 if (of->f_ftype == SMB_FTYPE_DISK || 996 of->f_ftype == SMB_FTYPE_PRINTER) { 997 ASSERT(of->f_node != NULL); 998 /* 999 * Note smb_ofile_close did smb_node_dec_open_ofiles() 1000 */ 1001 smb_node_rem_ofile(of->f_node, of); 1002 } 1003 1004 mutex_enter(&of->f_mutex); 1005 mutex_exit(&of->f_mutex); 1006 1007 switch (of->f_ftype) { 1008 case SMB_FTYPE_BYTE_PIPE: 1009 case SMB_FTYPE_MESG_PIPE: 1010 smb_opipe_dealloc(of->f_pipe); 1011 of->f_pipe = NULL; 1012 break; 1013 case SMB_FTYPE_DISK: 1014 ASSERT(of->f_notify.nc_subscribed == B_FALSE); 1015 MBC_FLUSH(&of->f_notify.nc_buffer); 1016 if (of->f_odir != NULL) 1017 smb_odir_release(of->f_odir); 1018 /* FALLTHROUGH */ 1019 case SMB_FTYPE_PRINTER: 1020 /* 1021 * Did smb_node_rem_ofile above. 1022 */ 1023 ASSERT(of->f_node != NULL); 1024 smb_node_release(of->f_node); 1025 break; 1026 default: 1027 ASSERT(!"f_ftype"); 1028 break; 1029 } 1030 1031 of->f_magic = (uint32_t)~SMB_OFILE_MAGIC; 1032 list_destroy(&of->f_notify.nc_waiters); 1033 mutex_destroy(&of->f_mutex); 1034 smb_user_release(of->f_user); 1035 crfree(of->f_cr); 1036 kmem_cache_free(smb_cache_ofile, of); 1037 } 1038 1039 /* 1040 * smb_ofile_access 1041 * 1042 * This function will check to see if the access requested is granted. 1043 * Returns NT status codes. 1044 */ 1045 uint32_t 1046 smb_ofile_access(smb_ofile_t *of, cred_t *cr, uint32_t access) 1047 { 1048 1049 if ((of == NULL) || (cr == zone_kcred())) 1050 return (NT_STATUS_SUCCESS); 1051 1052 /* 1053 * If the request is for something 1054 * I don't grant it is an error 1055 */ 1056 if (~(of->f_granted_access) & access) { 1057 if (!(of->f_granted_access & ACCESS_SYSTEM_SECURITY) && 1058 (access & ACCESS_SYSTEM_SECURITY)) { 1059 return (NT_STATUS_PRIVILEGE_NOT_HELD); 1060 } 1061 return (NT_STATUS_ACCESS_DENIED); 1062 } 1063 1064 return (NT_STATUS_SUCCESS); 1065 } 1066 1067 /* 1068 * smb_ofile_share_check 1069 * 1070 * Check if ofile was opened with share access NONE (0). 1071 * Returns: B_TRUE - share access non-zero 1072 * B_FALSE - share access NONE 1073 */ 1074 boolean_t 1075 smb_ofile_share_check(smb_ofile_t *of) 1076 { 1077 return (!SMB_DENY_ALL(of->f_share_access)); 1078 } 1079 1080 /* 1081 * check file sharing rules for current open request 1082 * against existing open instances of the same file 1083 * 1084 * Returns NT_STATUS_SHARING_VIOLATION if there is any 1085 * sharing conflict, otherwise returns NT_STATUS_SUCCESS. 1086 */ 1087 uint32_t 1088 smb_ofile_open_check(smb_ofile_t *of, uint32_t desired_access, 1089 uint32_t share_access) 1090 { 1091 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 1092 1093 mutex_enter(&of->f_mutex); 1094 1095 if (of->f_state != SMB_OFILE_STATE_OPEN) { 1096 mutex_exit(&of->f_mutex); 1097 return (NT_STATUS_INVALID_HANDLE); 1098 } 1099 1100 /* if it's just meta data */ 1101 if ((of->f_granted_access & FILE_DATA_ALL) == 0) { 1102 mutex_exit(&of->f_mutex); 1103 return (NT_STATUS_SUCCESS); 1104 } 1105 1106 /* 1107 * Check requested share access against the 1108 * open granted (desired) access 1109 */ 1110 if (SMB_DENY_DELETE(share_access) && (of->f_granted_access & DELETE)) { 1111 mutex_exit(&of->f_mutex); 1112 return (NT_STATUS_SHARING_VIOLATION); 1113 } 1114 1115 if (SMB_DENY_READ(share_access) && 1116 (of->f_granted_access & (FILE_READ_DATA | FILE_EXECUTE))) { 1117 mutex_exit(&of->f_mutex); 1118 return (NT_STATUS_SHARING_VIOLATION); 1119 } 1120 1121 if (SMB_DENY_WRITE(share_access) && 1122 (of->f_granted_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) { 1123 mutex_exit(&of->f_mutex); 1124 return (NT_STATUS_SHARING_VIOLATION); 1125 } 1126 1127 /* check requested desired access against the open share access */ 1128 if (SMB_DENY_DELETE(of->f_share_access) && (desired_access & DELETE)) { 1129 mutex_exit(&of->f_mutex); 1130 return (NT_STATUS_SHARING_VIOLATION); 1131 } 1132 1133 if (SMB_DENY_READ(of->f_share_access) && 1134 (desired_access & (FILE_READ_DATA | FILE_EXECUTE))) { 1135 mutex_exit(&of->f_mutex); 1136 return (NT_STATUS_SHARING_VIOLATION); 1137 } 1138 1139 if (SMB_DENY_WRITE(of->f_share_access) && 1140 (desired_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) { 1141 mutex_exit(&of->f_mutex); 1142 return (NT_STATUS_SHARING_VIOLATION); 1143 } 1144 1145 mutex_exit(&of->f_mutex); 1146 return (NT_STATUS_SUCCESS); 1147 } 1148 1149 /* 1150 * smb_ofile_rename_check 1151 * 1152 * This does the work described in MS-FSA 2.1.5.1.2.2 (Algorithm 1153 * to Check Sharing Access to an Existing Stream or Directory), 1154 * where the "open in-progress" has DesiredAccess = DELETE and 1155 * SharingMode = SHARE_READ | SHARE_WRITE | SHARE_DELETE. 1156 */ 1157 1158 uint32_t 1159 smb_ofile_rename_check(smb_ofile_t *of) 1160 { 1161 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 1162 1163 mutex_enter(&of->f_mutex); 1164 1165 if (of->f_state != SMB_OFILE_STATE_OPEN) { 1166 mutex_exit(&of->f_mutex); 1167 return (NT_STATUS_INVALID_HANDLE); 1168 } 1169 1170 if ((of->f_granted_access & FILE_DATA_ALL) == 0) { 1171 mutex_exit(&of->f_mutex); 1172 return (NT_STATUS_SUCCESS); 1173 } 1174 1175 if ((of->f_share_access & FILE_SHARE_DELETE) == 0) { 1176 mutex_exit(&of->f_mutex); 1177 return (NT_STATUS_SHARING_VIOLATION); 1178 } 1179 1180 mutex_exit(&of->f_mutex); 1181 return (NT_STATUS_SUCCESS); 1182 } 1183 1184 /* 1185 * smb_ofile_delete_check 1186 * 1187 * An open file can be deleted only if opened for 1188 * accessing meta data. Share modes aren't important 1189 * in this case. 1190 * 1191 * NOTE: there is another mechanism for deleting an 1192 * open file that NT clients usually use. 1193 * That's setting "Delete on close" flag for an open 1194 * file. In this way the file will be deleted after 1195 * last close. This flag can be set by SmbTrans2SetFileInfo 1196 * with FILE_DISPOSITION_INFO information level. 1197 * For setting this flag, the file should be opened by 1198 * DELETE access in the FID that is passed in the Trans2 1199 * request. 1200 */ 1201 1202 uint32_t 1203 smb_ofile_delete_check(smb_ofile_t *of) 1204 { 1205 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 1206 1207 mutex_enter(&of->f_mutex); 1208 1209 if (of->f_state != SMB_OFILE_STATE_OPEN) { 1210 mutex_exit(&of->f_mutex); 1211 return (NT_STATUS_INVALID_HANDLE); 1212 } 1213 1214 if (of->f_granted_access & 1215 (FILE_READ_DATA | FILE_WRITE_DATA | 1216 FILE_APPEND_DATA | FILE_EXECUTE | DELETE)) { 1217 mutex_exit(&of->f_mutex); 1218 return (NT_STATUS_SHARING_VIOLATION); 1219 } 1220 1221 mutex_exit(&of->f_mutex); 1222 return (NT_STATUS_SUCCESS); 1223 } 1224 1225 cred_t * 1226 smb_ofile_getcred(smb_ofile_t *of) 1227 { 1228 return (of->f_cr); 1229 } 1230 1231 /* 1232 * smb_ofile_set_delete_on_close 1233 * 1234 * Set the DeleteOnClose flag on the smb file. When the file is closed, 1235 * the flag will be transferred to the smb node, which will commit the 1236 * delete operation and inhibit subsequent open requests. 1237 * 1238 * When DeleteOnClose is set on an smb_node, the common open code will 1239 * reject subsequent open requests for the file. Observation of Windows 1240 * 2000 indicates that subsequent opens should be allowed (assuming 1241 * there would be no sharing violation) until the file is closed using 1242 * the fid on which the DeleteOnClose was requested. 1243 */ 1244 void 1245 smb_ofile_set_delete_on_close(smb_ofile_t *of) 1246 { 1247 mutex_enter(&of->f_mutex); 1248 of->f_flags |= SMB_OFLAGS_SET_DELETE_ON_CLOSE; 1249 mutex_exit(&of->f_mutex); 1250 } 1251 1252 /* 1253 * Encode open file information into a buffer; needed in user space to 1254 * support RPC requests. 1255 */ 1256 static int 1257 smb_ofile_netinfo_encode(smb_ofile_t *of, uint8_t *buf, size_t buflen, 1258 uint32_t *nbytes) 1259 { 1260 smb_netfileinfo_t fi; 1261 int rc; 1262 1263 rc = smb_ofile_netinfo_init(of, &fi); 1264 if (rc == 0) { 1265 rc = smb_netfileinfo_encode(&fi, buf, buflen, nbytes); 1266 smb_ofile_netinfo_fini(&fi); 1267 } 1268 1269 return (rc); 1270 } 1271 1272 static int 1273 smb_ofile_netinfo_init(smb_ofile_t *of, smb_netfileinfo_t *fi) 1274 { 1275 smb_user_t *user; 1276 smb_tree_t *tree; 1277 smb_node_t *node; 1278 char *path; 1279 char *buf; 1280 int rc; 1281 1282 ASSERT(of); 1283 user = of->f_user; 1284 tree = of->f_tree; 1285 ASSERT(user); 1286 ASSERT(tree); 1287 1288 buf = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 1289 1290 switch (of->f_ftype) { 1291 case SMB_FTYPE_DISK: 1292 node = of->f_node; 1293 ASSERT(node); 1294 1295 fi->fi_permissions = of->f_granted_access; 1296 fi->fi_numlocks = smb_lock_get_lock_count(node, of); 1297 1298 path = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 1299 1300 if (node != tree->t_snode) { 1301 rc = smb_node_getshrpath(node, tree, path, MAXPATHLEN); 1302 if (rc != 0) 1303 (void) strlcpy(path, node->od_name, MAXPATHLEN); 1304 } 1305 1306 (void) snprintf(buf, MAXPATHLEN, "%s:%s", tree->t_sharename, 1307 path); 1308 kmem_free(path, MAXPATHLEN); 1309 break; 1310 1311 case SMB_FTYPE_MESG_PIPE: 1312 ASSERT(of->f_pipe); 1313 1314 fi->fi_permissions = FILE_READ_DATA | FILE_WRITE_DATA | 1315 FILE_EXECUTE; 1316 fi->fi_numlocks = 0; 1317 (void) snprintf(buf, MAXPATHLEN, "\\PIPE\\%s", 1318 of->f_pipe->p_name); 1319 break; 1320 1321 default: 1322 kmem_free(buf, MAXPATHLEN); 1323 return (-1); 1324 } 1325 1326 fi->fi_fid = of->f_fid; 1327 fi->fi_uniqid = of->f_uniqid; 1328 fi->fi_pathlen = strlen(buf) + 1; 1329 fi->fi_path = smb_mem_strdup(buf); 1330 kmem_free(buf, MAXPATHLEN); 1331 1332 fi->fi_namelen = user->u_domain_len + user->u_name_len + 2; 1333 fi->fi_username = kmem_alloc(fi->fi_namelen, KM_SLEEP); 1334 (void) snprintf(fi->fi_username, fi->fi_namelen, "%s\\%s", 1335 user->u_domain, user->u_name); 1336 return (0); 1337 } 1338 1339 static void 1340 smb_ofile_netinfo_fini(smb_netfileinfo_t *fi) 1341 { 1342 if (fi == NULL) 1343 return; 1344 1345 if (fi->fi_path) 1346 smb_mem_free(fi->fi_path); 1347 if (fi->fi_username) 1348 kmem_free(fi->fi_username, fi->fi_namelen); 1349 1350 bzero(fi, sizeof (smb_netfileinfo_t)); 1351 } 1352 1353 /* 1354 * A query of user and group quotas may span multiple requests. 1355 * f_quota_resume is used to determine where the query should 1356 * be resumed, in a subsequent request. f_quota_resume contains 1357 * the SID of the last quota entry returned to the client. 1358 */ 1359 void 1360 smb_ofile_set_quota_resume(smb_ofile_t *ofile, char *resume) 1361 { 1362 ASSERT(ofile); 1363 mutex_enter(&ofile->f_mutex); 1364 if (resume == NULL) 1365 bzero(ofile->f_quota_resume, SMB_SID_STRSZ); 1366 else 1367 (void) strlcpy(ofile->f_quota_resume, resume, SMB_SID_STRSZ); 1368 mutex_exit(&ofile->f_mutex); 1369 } 1370 1371 void 1372 smb_ofile_get_quota_resume(smb_ofile_t *ofile, char *buf, int bufsize) 1373 { 1374 ASSERT(ofile); 1375 mutex_enter(&ofile->f_mutex); 1376 (void) strlcpy(buf, ofile->f_quota_resume, bufsize); 1377 mutex_exit(&ofile->f_mutex); 1378 } 1379