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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * General Structures Layout 28 * ------------------------- 29 * 30 * This is a simplified diagram showing the relationship between most of the 31 * main structures. 32 * 33 * +-------------------+ 34 * | SMB_INFO | 35 * +-------------------+ 36 * | 37 * | 38 * v 39 * +-------------------+ +-------------------+ +-------------------+ 40 * | SESSION |<----->| SESSION |......| SESSION | 41 * +-------------------+ +-------------------+ +-------------------+ 42 * | 43 * | 44 * v 45 * +-------------------+ +-------------------+ +-------------------+ 46 * | USER |<----->| USER |......| USER | 47 * +-------------------+ +-------------------+ +-------------------+ 48 * | 49 * | 50 * v 51 * +-------------------+ +-------------------+ +-------------------+ 52 * | TREE |<----->| TREE |......| TREE | 53 * +-------------------+ +-------------------+ +-------------------+ 54 * | | 55 * | | 56 * | v 57 * | +-------+ +-------+ +-------+ 58 * | | OFILE |<----->| OFILE |......| OFILE | 59 * | +-------+ +-------+ +-------+ 60 * | 61 * | 62 * v 63 * +-------+ +------+ +------+ 64 * | ODIR |<----->| ODIR |......| ODIR | 65 * +-------+ +------+ +------+ 66 * 67 * 68 * Ofile State Machine 69 * ------------------ 70 * 71 * +-------------------------+ T0 72 * | SMB_OFILE_STATE_OPEN |<----------- Creation/Allocation 73 * +-------------------------+ 74 * | 75 * | T1 76 * | 77 * v 78 * +-------------------------+ 79 * | SMB_OFILE_STATE_CLOSING | 80 * +-------------------------+ 81 * | 82 * | T2 83 * | 84 * v 85 * +-------------------------+ T3 86 * | SMB_OFILE_STATE_CLOSED |----------> Deletion/Free 87 * +-------------------------+ 88 * 89 * SMB_OFILE_STATE_OPEN 90 * 91 * While in this state: 92 * - The ofile is queued in the list of ofiles of its tree. 93 * - References will be given out if the ofile is looked up. 94 * 95 * SMB_OFILE_STATE_CLOSING 96 * 97 * While in this state: 98 * - The ofile is queued in the list of ofiles of its tree. 99 * - References will not be given out if the ofile is looked up. 100 * - The file is closed and the locks held are being released. 101 * - The resources associated with the ofile remain. 102 * 103 * SMB_OFILE_STATE_CLOSED 104 * 105 * While in this state: 106 * - The ofile is queued in the list of ofiles of its tree. 107 * - References will not be given out if the ofile is looked up. 108 * - The resources associated with the ofile remain. 109 * 110 * Transition T0 111 * 112 * This transition occurs in smb_ofile_open(). A new ofile is created and 113 * added to the list of ofiles of a tree. 114 * 115 * Transition T1 116 * 117 * This transition occurs in smb_ofile_close(). 118 * 119 * Transition T2 120 * 121 * This transition occurs in smb_ofile_release(). The resources associated 122 * with the ofile are freed as well as the ofile structure. For the 123 * transition to occur, the ofile must be in the SMB_OFILE_STATE_CLOSED 124 * state and the reference count be zero. 125 * 126 * Comments 127 * -------- 128 * 129 * The state machine of the ofile structures is controlled by 3 elements: 130 * - The list of ofiles of the tree it belongs to. 131 * - The mutex embedded in the structure itself. 132 * - The reference count. 133 * 134 * There's a mutex embedded in the ofile structure used to protect its fields 135 * and there's a lock embedded in the list of ofiles of a tree. To 136 * increment or to decrement the reference count the mutex must be entered. 137 * To insert the ofile into the list of ofiles of the tree and to remove 138 * the ofile from it, the lock must be entered in RW_WRITER mode. 139 * 140 * Rules of access to a ofile structure: 141 * 142 * 1) In order to avoid deadlocks, when both (mutex and lock of the ofile 143 * list) have to be entered, the lock must be entered first. 144 * 145 * 2) All actions applied to an ofile require a reference count. 146 * 147 * 3) There are 2 ways of getting a reference count. One is when the ofile 148 * is opened. The other one when the ofile is looked up. This translates 149 * into 2 functions: smb_ofile_open() and smb_ofile_lookup_by_fid(). 150 * 151 * It should be noted that the reference count of an ofile registers the 152 * number of references to the ofile in other structures (such as an smb 153 * request). The reference count is not incremented in these 2 instances: 154 * 155 * 1) The ofile is open. An ofile is anchored by his state. If there's 156 * no activity involving an ofile currently open, the reference count 157 * of that ofile is zero. 158 * 159 * 2) The ofile is queued in the list of ofiles of its tree. The fact of 160 * being queued in that list is NOT registered by incrementing the 161 * reference count. 162 */ 163 #include <smbsrv/smb_kproto.h> 164 #include <smbsrv/smb_fsops.h> 165 166 static boolean_t smb_ofile_is_open_locked(smb_ofile_t *); 167 static void smb_ofile_delete(smb_ofile_t *); 168 static smb_ofile_t *smb_ofile_close_and_next(smb_ofile_t *); 169 static void smb_ofile_set_close_attrs(smb_ofile_t *, uint32_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_tree_t *tree, 181 smb_node_t *node, 182 uint16_t pid, 183 struct open_param *op, 184 uint16_t ftype, 185 uint32_t uniqid, 186 smb_error_t *err) 187 { 188 smb_ofile_t *of; 189 uint16_t fid; 190 smb_attr_t attr; 191 192 if (smb_idpool_alloc(&tree->t_fid_pool, &fid)) { 193 err->status = NT_STATUS_TOO_MANY_OPENED_FILES; 194 err->errcls = ERRDOS; 195 err->errcode = ERROR_TOO_MANY_OPEN_FILES; 196 return (NULL); 197 } 198 199 of = kmem_cache_alloc(tree->t_server->si_cache_ofile, KM_SLEEP); 200 bzero(of, sizeof (smb_ofile_t)); 201 of->f_magic = SMB_OFILE_MAGIC; 202 of->f_refcnt = 1; 203 of->f_fid = fid; 204 of->f_uniqid = uniqid; 205 of->f_opened_by_pid = pid; 206 of->f_granted_access = op->desired_access; 207 of->f_share_access = op->share_access; 208 of->f_create_options = op->create_options; 209 of->f_cr = (op->create_options & FILE_OPEN_FOR_BACKUP_INTENT) ? 210 smb_user_getprivcred(tree->t_user) : tree->t_user->u_cred; 211 crhold(of->f_cr); 212 of->f_ftype = ftype; 213 of->f_server = tree->t_server; 214 of->f_session = tree->t_user->u_session; 215 of->f_user = tree->t_user; 216 of->f_tree = tree; 217 of->f_node = node; 218 of->f_explicit_times = 0; 219 mutex_init(&of->f_mutex, NULL, MUTEX_DEFAULT, NULL); 220 of->f_state = SMB_OFILE_STATE_OPEN; 221 222 223 if (ftype == SMB_FTYPE_MESG_PIPE) { 224 of->f_pipe = kmem_zalloc(sizeof (smb_opipe_t), KM_SLEEP); 225 } else { 226 ASSERT(ftype == SMB_FTYPE_DISK); /* Regular file, not a pipe */ 227 ASSERT(node); 228 229 if (of->f_granted_access == FILE_EXECUTE) 230 of->f_flags |= SMB_OFLAGS_EXECONLY; 231 232 bzero(&attr, sizeof (smb_attr_t)); 233 attr.sa_mask |= SMB_AT_UID; 234 if (smb_fsop_getattr(NULL, kcred, node, &attr) != 0) { 235 of->f_magic = 0; 236 mutex_destroy(&of->f_mutex); 237 crfree(of->f_cr); 238 smb_idpool_free(&tree->t_fid_pool, of->f_fid); 239 kmem_cache_free(tree->t_server->si_cache_ofile, of); 240 err->status = NT_STATUS_INTERNAL_ERROR; 241 err->errcls = ERRDOS; 242 err->errcode = ERROR_INTERNAL_ERROR; 243 return (NULL); 244 } 245 if (crgetuid(of->f_cr) == attr.sa_vattr.va_uid) { 246 /* 247 * Add this bit for the file's owner even if it's not 248 * specified in the request (Windows behavior). 249 */ 250 of->f_granted_access |= FILE_READ_ATTRIBUTES; 251 } 252 253 if (node->vp->v_type == VREG) { 254 of->f_mode = 255 smb_fsop_amask_to_omode(of->f_granted_access); 256 if (smb_fsop_open(node, of->f_mode, of->f_cr) != 0) { 257 of->f_magic = 0; 258 mutex_destroy(&of->f_mutex); 259 crfree(of->f_cr); 260 smb_idpool_free(&tree->t_fid_pool, of->f_fid); 261 kmem_cache_free(tree->t_server->si_cache_ofile, 262 of); 263 err->status = NT_STATUS_ACCESS_DENIED; 264 err->errcls = ERRDOS; 265 err->errcode = ERROR_ACCESS_DENIED; 266 return (NULL); 267 } 268 } 269 270 if (tree->t_flags & SMB_TREE_READONLY) 271 of->f_flags |= SMB_OFLAGS_READONLY; 272 273 if (op->created_readonly) 274 node->readonly_creator = of; 275 276 smb_node_inc_open_ofiles(node); 277 smb_node_add_ofile(node, of); 278 smb_node_ref(node); 279 } 280 smb_llist_enter(&tree->t_ofile_list, RW_WRITER); 281 smb_llist_insert_tail(&tree->t_ofile_list, of); 282 smb_llist_exit(&tree->t_ofile_list); 283 atomic_inc_32(&tree->t_open_files); 284 atomic_inc_32(&tree->t_server->sv_open_files); 285 atomic_inc_32(&of->f_session->s_file_cnt); 286 287 return (of); 288 } 289 290 /* 291 * smb_ofile_close 292 */ 293 void 294 smb_ofile_close(smb_ofile_t *of, uint32_t last_wtime) 295 { 296 ASSERT(of); 297 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 298 uint32_t flags = 0; 299 300 mutex_enter(&of->f_mutex); 301 ASSERT(of->f_refcnt); 302 switch (of->f_state) { 303 case SMB_OFILE_STATE_OPEN: { 304 305 of->f_state = SMB_OFILE_STATE_CLOSING; 306 mutex_exit(&of->f_mutex); 307 308 if (of->f_ftype == SMB_FTYPE_MESG_PIPE) { 309 smb_opipe_close(of); 310 } else { 311 smb_ofile_set_close_attrs(of, last_wtime); 312 313 if (of->f_flags & SMB_OFLAGS_SET_DELETE_ON_CLOSE) { 314 if (smb_tree_has_feature(of->f_tree, 315 SMB_TREE_CATIA)) { 316 flags |= SMB_CATIA; 317 } 318 (void) smb_node_set_delete_on_close(of->f_node, 319 of->f_cr, flags); 320 } 321 smb_fsop_unshrlock(of->f_cr, of->f_node, of->f_uniqid); 322 smb_node_destroy_lock_by_ofile(of->f_node, of); 323 324 if (of->f_node->vp->v_type == VREG) 325 (void) smb_fsop_close(of->f_node, of->f_mode, 326 of->f_cr); 327 328 /* 329 * Cancel any notify change requests related 330 * to this open instance. 331 */ 332 if (of->f_node->flags & NODE_FLAGS_NOTIFY_CHANGE) 333 smb_process_file_notify_change_queue(of); 334 } 335 atomic_dec_32(&of->f_tree->t_open_files); 336 atomic_dec_32(&of->f_tree->t_server->sv_open_files); 337 338 mutex_enter(&of->f_mutex); 339 ASSERT(of->f_refcnt); 340 ASSERT(of->f_state == SMB_OFILE_STATE_CLOSING); 341 of->f_state = SMB_OFILE_STATE_CLOSED; 342 mutex_exit(&of->f_mutex); 343 if (of->f_node != NULL) { 344 smb_node_dec_open_ofiles(of->f_node); 345 if (of->f_oplock_granted) { 346 smb_oplock_release(of->f_node, of); 347 of->f_oplock_granted = B_FALSE; 348 } 349 } 350 return; 351 } 352 case SMB_OFILE_STATE_CLOSED: 353 case SMB_OFILE_STATE_CLOSING: 354 break; 355 356 default: 357 ASSERT(0); 358 break; 359 } 360 mutex_exit(&of->f_mutex); 361 } 362 363 /* 364 * smb_ofile_close_all 365 * 366 * 367 */ 368 void 369 smb_ofile_close_all( 370 smb_tree_t *tree) 371 { 372 smb_ofile_t *of; 373 374 ASSERT(tree); 375 ASSERT(tree->t_magic == SMB_TREE_MAGIC); 376 377 smb_llist_enter(&tree->t_ofile_list, RW_READER); 378 of = smb_llist_head(&tree->t_ofile_list); 379 while (of) { 380 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 381 ASSERT(of->f_tree == tree); 382 of = smb_ofile_close_and_next(of); 383 } 384 smb_llist_exit(&tree->t_ofile_list); 385 } 386 387 /* 388 * smb_ofiles_close_by_pid 389 * 390 * 391 */ 392 void 393 smb_ofile_close_all_by_pid( 394 smb_tree_t *tree, 395 uint16_t pid) 396 { 397 smb_ofile_t *of; 398 399 ASSERT(tree); 400 ASSERT(tree->t_magic == SMB_TREE_MAGIC); 401 402 smb_llist_enter(&tree->t_ofile_list, RW_READER); 403 of = smb_llist_head(&tree->t_ofile_list); 404 while (of) { 405 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 406 ASSERT(of->f_tree == tree); 407 if (of->f_opened_by_pid == pid) { 408 of = smb_ofile_close_and_next(of); 409 } else { 410 of = smb_llist_next(&tree->t_ofile_list, of); 411 } 412 } 413 smb_llist_exit(&tree->t_ofile_list); 414 } 415 416 /* 417 * If the enumeration request is for ofile data, handle it here. 418 * Otherwise, return. 419 * 420 * This function should be called with a hold on the ofile. 421 */ 422 int 423 smb_ofile_enum(smb_ofile_t *of, smb_svcenum_t *svcenum) 424 { 425 uint8_t *pb; 426 uint_t nbytes; 427 int rc; 428 429 ASSERT(of); 430 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 431 ASSERT(of->f_refcnt); 432 433 if (svcenum->se_type != SMB_SVCENUM_TYPE_FILE) 434 return (0); 435 436 if (svcenum->se_nskip > 0) { 437 svcenum->se_nskip--; 438 return (0); 439 } 440 441 if (svcenum->se_nitems >= svcenum->se_nlimit) { 442 svcenum->se_nitems = svcenum->se_nlimit; 443 return (0); 444 } 445 446 pb = &svcenum->se_buf[svcenum->se_bused]; 447 448 rc = smb_ofile_netinfo_encode(of, pb, svcenum->se_bavail, 449 &nbytes); 450 if (rc == 0) { 451 svcenum->se_bavail -= nbytes; 452 svcenum->se_bused += nbytes; 453 svcenum->se_nitems++; 454 } 455 456 return (rc); 457 } 458 459 /* 460 * Take a reference on an open file. 461 */ 462 boolean_t 463 smb_ofile_hold(smb_ofile_t *of) 464 { 465 ASSERT(of); 466 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 467 468 mutex_enter(&of->f_mutex); 469 470 if (smb_ofile_is_open_locked(of)) { 471 of->f_refcnt++; 472 mutex_exit(&of->f_mutex); 473 return (B_TRUE); 474 } 475 476 mutex_exit(&of->f_mutex); 477 return (B_FALSE); 478 } 479 480 /* 481 * smb_ofile_release 482 * 483 */ 484 void 485 smb_ofile_release(smb_ofile_t *of) 486 { 487 boolean_t rb; 488 489 ASSERT(of); 490 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 491 492 mutex_enter(&of->f_mutex); 493 if (of->f_oplock_exit) { 494 mutex_exit(&of->f_mutex); 495 rb = smb_oplock_broadcast(of->f_node); 496 mutex_enter(&of->f_mutex); 497 if (rb) 498 of->f_oplock_exit = B_FALSE; 499 } 500 ASSERT(of->f_refcnt); 501 of->f_refcnt--; 502 switch (of->f_state) { 503 case SMB_OFILE_STATE_OPEN: 504 case SMB_OFILE_STATE_CLOSING: 505 break; 506 507 case SMB_OFILE_STATE_CLOSED: 508 if (of->f_refcnt == 0) { 509 mutex_exit(&of->f_mutex); 510 smb_ofile_delete(of); 511 return; 512 } 513 break; 514 515 default: 516 ASSERT(0); 517 break; 518 } 519 mutex_exit(&of->f_mutex); 520 } 521 522 /* 523 * smb_ofile_lookup_by_fid 524 * 525 * Find the open file whose fid matches the one specified in the request. 526 * If we can't find the fid or the shares (trees) don't match, we have a 527 * bad fid. 528 */ 529 smb_ofile_t * 530 smb_ofile_lookup_by_fid( 531 smb_tree_t *tree, 532 uint16_t fid) 533 { 534 smb_llist_t *of_list; 535 smb_ofile_t *of; 536 537 ASSERT(tree->t_magic == SMB_TREE_MAGIC); 538 539 of_list = &tree->t_ofile_list; 540 541 smb_llist_enter(of_list, RW_READER); 542 of = smb_llist_head(of_list); 543 while (of) { 544 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 545 ASSERT(of->f_tree == tree); 546 if (of->f_fid == fid) { 547 mutex_enter(&of->f_mutex); 548 if (of->f_state != SMB_OFILE_STATE_OPEN) { 549 mutex_exit(&of->f_mutex); 550 smb_llist_exit(of_list); 551 return (NULL); 552 } 553 of->f_refcnt++; 554 mutex_exit(&of->f_mutex); 555 break; 556 } 557 of = smb_llist_next(of_list, of); 558 } 559 smb_llist_exit(of_list); 560 return (of); 561 } 562 563 /* 564 * smb_ofile_lookup_by_uniqid 565 * 566 * Find the open file whose uniqid matches the one specified in the request. 567 */ 568 smb_ofile_t * 569 smb_ofile_lookup_by_uniqid(smb_tree_t *tree, uint32_t uniqid) 570 { 571 smb_llist_t *of_list; 572 smb_ofile_t *of; 573 574 ASSERT(tree->t_magic == SMB_TREE_MAGIC); 575 576 of_list = &tree->t_ofile_list; 577 smb_llist_enter(of_list, RW_READER); 578 of = smb_llist_head(of_list); 579 580 while (of) { 581 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 582 ASSERT(of->f_tree == tree); 583 584 if (of->f_uniqid == uniqid) { 585 if (smb_ofile_hold(of)) { 586 smb_llist_exit(of_list); 587 return (of); 588 } 589 } 590 591 of = smb_llist_next(of_list, of); 592 } 593 594 smb_llist_exit(of_list); 595 return (NULL); 596 } 597 598 /* 599 * Disallow NetFileClose on certain ofiles to avoid side-effects. 600 * Closing a tree root is not allowed: use NetSessionDel or NetShareDel. 601 * Closing SRVSVC connections is not allowed because this NetFileClose 602 * request may depend on this ofile. 603 */ 604 boolean_t 605 smb_ofile_disallow_fclose(smb_ofile_t *of) 606 { 607 ASSERT(of); 608 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 609 ASSERT(of->f_refcnt); 610 611 switch (of->f_ftype) { 612 case SMB_FTYPE_DISK: 613 ASSERT(of->f_tree); 614 return (of->f_node == of->f_tree->t_snode); 615 616 case SMB_FTYPE_MESG_PIPE: 617 ASSERT(of->f_pipe); 618 if (smb_strcasecmp(of->f_pipe->p_name, "SRVSVC", 0) == 0) 619 return (B_TRUE); 620 break; 621 default: 622 break; 623 } 624 625 return (B_FALSE); 626 } 627 628 /* 629 * smb_ofile_set_flags 630 * 631 * Return value: 632 * 633 * Current flags value 634 * 635 */ 636 void 637 smb_ofile_set_flags( 638 smb_ofile_t *of, 639 uint32_t flags) 640 { 641 ASSERT(of); 642 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 643 ASSERT(of->f_refcnt); 644 645 mutex_enter(&of->f_mutex); 646 of->f_flags |= flags; 647 mutex_exit(&of->f_mutex); 648 } 649 /* 650 * smb_ofile_seek 651 * 652 * Return value: 653 * 654 * 0 Success 655 * EINVAL Unknown mode 656 * EOVERFLOW offset too big 657 * 658 */ 659 int 660 smb_ofile_seek( 661 smb_ofile_t *of, 662 ushort_t mode, 663 int32_t off, 664 uint32_t *retoff) 665 { 666 u_offset_t newoff = 0; 667 int rc = 0; 668 smb_attr_t attr; 669 670 ASSERT(of); 671 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 672 ASSERT(of->f_refcnt); 673 674 mutex_enter(&of->f_mutex); 675 switch (mode) { 676 case SMB_SEEK_SET: 677 if (off < 0) 678 newoff = 0; 679 else 680 newoff = (u_offset_t)off; 681 break; 682 683 case SMB_SEEK_CUR: 684 if (off < 0 && (-off) > of->f_seek_pos) 685 newoff = 0; 686 else 687 newoff = of->f_seek_pos + (u_offset_t)off; 688 break; 689 690 case SMB_SEEK_END: 691 bzero(&attr, sizeof (smb_attr_t)); 692 attr.sa_mask |= SMB_AT_SIZE; 693 rc = smb_fsop_getattr(NULL, kcred, of->f_node, &attr); 694 if (rc != 0) { 695 mutex_exit(&of->f_mutex); 696 return (rc); 697 } 698 if (off < 0 && (-off) > attr.sa_vattr.va_size) 699 newoff = 0; 700 else 701 newoff = attr.sa_vattr.va_size + (u_offset_t)off; 702 break; 703 704 default: 705 mutex_exit(&of->f_mutex); 706 return (EINVAL); 707 } 708 709 /* 710 * See comments at the beginning of smb_seek.c. 711 * If the offset is greater than UINT_MAX, we will return an error. 712 */ 713 714 if (newoff > UINT_MAX) { 715 rc = EOVERFLOW; 716 } else { 717 of->f_seek_pos = newoff; 718 *retoff = (uint32_t)newoff; 719 } 720 mutex_exit(&of->f_mutex); 721 return (rc); 722 } 723 724 /* 725 * smb_ofile_is_open 726 */ 727 boolean_t 728 smb_ofile_is_open(smb_ofile_t *of) 729 { 730 boolean_t rc; 731 732 SMB_OFILE_VALID(of); 733 734 mutex_enter(&of->f_mutex); 735 rc = smb_ofile_is_open_locked(of); 736 mutex_exit(&of->f_mutex); 737 return (rc); 738 } 739 740 void 741 smb_ofile_set_oplock_granted(smb_ofile_t *of) 742 { 743 SMB_OFILE_VALID(of); 744 mutex_enter(&of->f_mutex); 745 ASSERT(!of->f_oplock_granted); 746 of->f_oplock_granted = B_TRUE; 747 of->f_oplock_exit = B_TRUE; 748 mutex_exit(&of->f_mutex); 749 } 750 751 /* 752 * smb_ofile_pending_write_time 753 * 754 * Flag write times as pending - to be set on close, setattr 755 * or delayed write timer. 756 */ 757 void 758 smb_ofile_set_write_time_pending(smb_ofile_t *of) 759 { 760 SMB_OFILE_VALID(of); 761 mutex_enter(&of->f_mutex); 762 of->f_flags |= SMB_OFLAGS_TIMESTAMPS_PENDING; 763 mutex_exit(&of->f_mutex); 764 } 765 766 /* 767 * smb_ofile_write_time_pending 768 * 769 * Get and reset the write times pending flag. 770 */ 771 boolean_t 772 smb_ofile_write_time_pending(smb_ofile_t *of) 773 { 774 boolean_t rc = B_FALSE; 775 776 SMB_OFILE_VALID(of); 777 mutex_enter(&of->f_mutex); 778 if (of->f_flags & SMB_OFLAGS_TIMESTAMPS_PENDING) { 779 rc = B_TRUE; 780 of->f_flags &= ~SMB_OFLAGS_TIMESTAMPS_PENDING; 781 } 782 mutex_exit(&of->f_mutex); 783 784 return (rc); 785 } 786 787 /* 788 * smb_ofile_set_explicit_time_flag 789 * 790 * Note the timestamps specified in "what", as having been 791 * explicity set for the ofile. 792 */ 793 void 794 smb_ofile_set_explicit_times(smb_ofile_t *of, uint32_t what) 795 { 796 SMB_OFILE_VALID(of); 797 mutex_enter(&of->f_mutex); 798 of->f_explicit_times |= (what & SMB_AT_TIMES); 799 mutex_exit(&of->f_mutex); 800 } 801 802 uint32_t 803 smb_ofile_explicit_times(smb_ofile_t *of) 804 { 805 uint32_t rc; 806 807 SMB_OFILE_VALID(of); 808 mutex_enter(&of->f_mutex); 809 rc = of->f_explicit_times; 810 mutex_exit(&of->f_mutex); 811 812 return (rc); 813 } 814 815 /* *************************** Static Functions ***************************** */ 816 817 /* 818 * Determine whether or not an ofile is open. 819 * This function must be called with the mutex held. 820 */ 821 static boolean_t 822 smb_ofile_is_open_locked(smb_ofile_t *of) 823 { 824 switch (of->f_state) { 825 case SMB_OFILE_STATE_OPEN: 826 return (B_TRUE); 827 828 case SMB_OFILE_STATE_CLOSING: 829 case SMB_OFILE_STATE_CLOSED: 830 return (B_FALSE); 831 832 default: 833 ASSERT(0); 834 return (B_FALSE); 835 } 836 } 837 838 /* 839 * smb_ofile_set_close_attrs 840 * 841 * Updates timestamps, size and readonly bit. 842 * The last_wtime is specified in the request received 843 * from the client. If it is neither 0 nor -1, this time 844 * should be used as the file's mtime. It must first be 845 * converted from the server's localtime (as received in 846 * the client's request) to GMT. 847 * 848 * Call smb_node_setattr even if no attributes are being 849 * explicitly set, to set any pending attributes. 850 */ 851 static void 852 smb_ofile_set_close_attrs(smb_ofile_t *of, uint32_t last_wtime) 853 { 854 smb_node_t *node = of->f_node; 855 smb_attr_t attr; 856 857 bzero(&attr, sizeof (smb_attr_t)); 858 859 /* For files created readonly, propagate readonly bit */ 860 if (node->readonly_creator == of) { 861 attr.sa_mask |= SMB_AT_DOSATTR; 862 if (smb_fsop_getattr(NULL, kcred, node, &attr) && 863 (attr.sa_dosattr & FILE_ATTRIBUTE_READONLY)) { 864 attr.sa_mask = 0; 865 } else { 866 attr.sa_dosattr |= FILE_ATTRIBUTE_READONLY; 867 } 868 869 node->readonly_creator = NULL; 870 } 871 872 /* apply last_wtime if specified */ 873 if (last_wtime != 0 && last_wtime != 0xFFFFFFFF) { 874 attr.sa_vattr.va_mtime.tv_sec = 875 last_wtime + of->f_server->si_gmtoff; 876 attr.sa_mask |= SMB_AT_MTIME; 877 } 878 879 (void) smb_node_setattr(NULL, node, of->f_cr, of, &attr); 880 } 881 882 /* 883 * smb_ofile_close_and_next 884 * 885 * This function closes the file passed in (if appropriate) and returns the 886 * next open file in the list of open files of the tree of the open file passed 887 * in. It requires that the list of open files of the tree be entered in 888 * RW_READER mode before being called. 889 */ 890 static smb_ofile_t * 891 smb_ofile_close_and_next(smb_ofile_t *of) 892 { 893 smb_ofile_t *next_of; 894 smb_tree_t *tree; 895 896 ASSERT(of); 897 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 898 899 mutex_enter(&of->f_mutex); 900 switch (of->f_state) { 901 case SMB_OFILE_STATE_OPEN: 902 /* The file is still open. */ 903 of->f_refcnt++; 904 ASSERT(of->f_refcnt); 905 tree = of->f_tree; 906 mutex_exit(&of->f_mutex); 907 smb_llist_exit(&of->f_tree->t_ofile_list); 908 smb_ofile_close(of, 0); 909 smb_ofile_release(of); 910 smb_llist_enter(&tree->t_ofile_list, RW_READER); 911 next_of = smb_llist_head(&tree->t_ofile_list); 912 break; 913 case SMB_OFILE_STATE_CLOSING: 914 case SMB_OFILE_STATE_CLOSED: 915 /* 916 * The ofile exists but is closed or 917 * in the process being closed. 918 */ 919 mutex_exit(&of->f_mutex); 920 next_of = smb_llist_next(&of->f_tree->t_ofile_list, of); 921 break; 922 default: 923 ASSERT(0); 924 mutex_exit(&of->f_mutex); 925 next_of = smb_llist_next(&of->f_tree->t_ofile_list, of); 926 break; 927 } 928 return (next_of); 929 } 930 931 /* 932 * smb_ofile_delete 933 * 934 * 935 */ 936 static void 937 smb_ofile_delete(smb_ofile_t *of) 938 { 939 ASSERT(of); 940 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 941 ASSERT(of->f_refcnt == 0); 942 ASSERT(of->f_state == SMB_OFILE_STATE_CLOSED); 943 944 /* 945 * Let's remove the ofile from the list of ofiles of the tree. This has 946 * to be done before any resources associated with the ofile are 947 * released. 948 */ 949 smb_llist_enter(&of->f_tree->t_ofile_list, RW_WRITER); 950 smb_llist_remove(&of->f_tree->t_ofile_list, of); 951 smb_llist_exit(&of->f_tree->t_ofile_list); 952 atomic_dec_32(&of->f_session->s_file_cnt); 953 954 if (of->f_ftype == SMB_FTYPE_MESG_PIPE) { 955 kmem_free(of->f_pipe, sizeof (smb_opipe_t)); 956 of->f_pipe = NULL; 957 } else { 958 ASSERT(of->f_ftype == SMB_FTYPE_DISK); 959 ASSERT(of->f_node != NULL); 960 smb_node_rem_ofile(of->f_node, of); 961 smb_node_release(of->f_node); 962 } 963 964 of->f_magic = (uint32_t)~SMB_OFILE_MAGIC; 965 mutex_destroy(&of->f_mutex); 966 crfree(of->f_cr); 967 smb_idpool_free(&of->f_tree->t_fid_pool, of->f_fid); 968 kmem_cache_free(of->f_tree->t_server->si_cache_ofile, of); 969 } 970 971 /* 972 * smb_ofile_access 973 * 974 * This function will check to see if the access requested is granted. 975 * Returns NT status codes. 976 */ 977 uint32_t 978 smb_ofile_access(smb_ofile_t *of, cred_t *cr, uint32_t access) 979 { 980 981 if ((of == NULL) || (cr == kcred)) 982 return (NT_STATUS_SUCCESS); 983 984 /* 985 * If the request is for something 986 * I don't grant it is an error 987 */ 988 if (~(of->f_granted_access) & access) { 989 if (!(of->f_granted_access & ACCESS_SYSTEM_SECURITY) && 990 (access & ACCESS_SYSTEM_SECURITY)) { 991 return (NT_STATUS_PRIVILEGE_NOT_HELD); 992 } 993 return (NT_STATUS_ACCESS_DENIED); 994 } 995 996 return (NT_STATUS_SUCCESS); 997 } 998 999 1000 /* 1001 * smb_ofile_open_check 1002 * 1003 * check file sharing rules for current open request 1004 * against existing open instances of the same file 1005 * 1006 * Returns NT_STATUS_SHARING_VIOLATION if there is any 1007 * sharing conflict, otherwise returns NT_STATUS_SUCCESS. 1008 */ 1009 uint32_t 1010 smb_ofile_open_check( 1011 smb_ofile_t *of, 1012 cred_t *cr, 1013 uint32_t desired_access, 1014 uint32_t share_access) 1015 { 1016 smb_node_t *node; 1017 1018 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 1019 1020 node = of->f_node; 1021 1022 mutex_enter(&of->f_mutex); 1023 1024 if (of->f_state != SMB_OFILE_STATE_OPEN) { 1025 mutex_exit(&of->f_mutex); 1026 return (NT_STATUS_INVALID_HANDLE); 1027 } 1028 1029 /* 1030 * It appears that share modes are not relevant to 1031 * directories, but this check will remain as it is not 1032 * clear whether it was originally put here for a reason. 1033 */ 1034 if (smb_node_is_dir(node)) { 1035 if (SMB_DENY_RW(of->f_share_access) && 1036 (node->n_orig_uid != crgetuid(cr))) { 1037 mutex_exit(&of->f_mutex); 1038 return (NT_STATUS_SHARING_VIOLATION); 1039 } 1040 1041 mutex_exit(&of->f_mutex); 1042 return (NT_STATUS_SUCCESS); 1043 } 1044 1045 /* if it's just meta data */ 1046 if ((of->f_granted_access & FILE_DATA_ALL) == 0) { 1047 mutex_exit(&of->f_mutex); 1048 return (NT_STATUS_SUCCESS); 1049 } 1050 1051 /* 1052 * Check requested share access against the 1053 * open granted (desired) access 1054 */ 1055 if (SMB_DENY_DELETE(share_access) && (of->f_granted_access & DELETE)) { 1056 mutex_exit(&of->f_mutex); 1057 return (NT_STATUS_SHARING_VIOLATION); 1058 } 1059 1060 if (SMB_DENY_READ(share_access) && 1061 (of->f_granted_access & (FILE_READ_DATA | FILE_EXECUTE))) { 1062 mutex_exit(&of->f_mutex); 1063 return (NT_STATUS_SHARING_VIOLATION); 1064 } 1065 1066 if (SMB_DENY_WRITE(share_access) && 1067 (of->f_granted_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) { 1068 mutex_exit(&of->f_mutex); 1069 return (NT_STATUS_SHARING_VIOLATION); 1070 } 1071 1072 /* check requested desired access against the open share access */ 1073 if (SMB_DENY_DELETE(of->f_share_access) && (desired_access & DELETE)) { 1074 mutex_exit(&of->f_mutex); 1075 return (NT_STATUS_SHARING_VIOLATION); 1076 } 1077 1078 if (SMB_DENY_READ(of->f_share_access) && 1079 (desired_access & (FILE_READ_DATA | FILE_EXECUTE))) { 1080 mutex_exit(&of->f_mutex); 1081 return (NT_STATUS_SHARING_VIOLATION); 1082 } 1083 1084 if (SMB_DENY_WRITE(of->f_share_access) && 1085 (desired_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) { 1086 mutex_exit(&of->f_mutex); 1087 return (NT_STATUS_SHARING_VIOLATION); 1088 } 1089 1090 mutex_exit(&of->f_mutex); 1091 return (NT_STATUS_SUCCESS); 1092 } 1093 1094 /* 1095 * smb_ofile_rename_check 1096 * 1097 * An open file can be renamed if 1098 * 1099 * 1. isn't opened for data writing or deleting 1100 * 1101 * 2. Opened with "Deny Delete" share mode 1102 * But not opened for data reading or executing 1103 * (opened for accessing meta data) 1104 */ 1105 1106 uint32_t 1107 smb_ofile_rename_check(smb_ofile_t *of) 1108 { 1109 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 1110 1111 mutex_enter(&of->f_mutex); 1112 1113 if (of->f_state != SMB_OFILE_STATE_OPEN) { 1114 mutex_exit(&of->f_mutex); 1115 return (NT_STATUS_INVALID_HANDLE); 1116 } 1117 1118 if (of->f_granted_access & 1119 (FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE)) { 1120 mutex_exit(&of->f_mutex); 1121 return (NT_STATUS_SHARING_VIOLATION); 1122 } 1123 1124 if ((of->f_share_access & FILE_SHARE_DELETE) == 0) { 1125 if (of->f_granted_access & 1126 (FILE_READ_DATA | FILE_EXECUTE)) { 1127 mutex_exit(&of->f_mutex); 1128 return (NT_STATUS_SHARING_VIOLATION); 1129 } 1130 } 1131 1132 mutex_exit(&of->f_mutex); 1133 return (NT_STATUS_SUCCESS); 1134 } 1135 1136 /* 1137 * smb_ofile_delete_check 1138 * 1139 * An open file can be deleted only if opened for 1140 * accessing meta data. Share modes aren't important 1141 * in this case. 1142 * 1143 * NOTE: there is another mechanism for deleting an 1144 * open file that NT clients usually use. 1145 * That's setting "Delete on close" flag for an open 1146 * file. In this way the file will be deleted after 1147 * last close. This flag can be set by SmbTrans2SetFileInfo 1148 * with FILE_DISPOSITION_INFO information level. 1149 * For setting this flag, the file should be opened by 1150 * DELETE access in the FID that is passed in the Trans2 1151 * request. 1152 */ 1153 1154 uint32_t 1155 smb_ofile_delete_check(smb_ofile_t *of) 1156 { 1157 ASSERT(of->f_magic == SMB_OFILE_MAGIC); 1158 1159 mutex_enter(&of->f_mutex); 1160 1161 if (of->f_state != SMB_OFILE_STATE_OPEN) { 1162 mutex_exit(&of->f_mutex); 1163 return (NT_STATUS_INVALID_HANDLE); 1164 } 1165 1166 if (of->f_granted_access & 1167 (FILE_READ_DATA | FILE_WRITE_DATA | 1168 FILE_APPEND_DATA | FILE_EXECUTE | DELETE)) { 1169 mutex_exit(&of->f_mutex); 1170 return (NT_STATUS_SHARING_VIOLATION); 1171 } 1172 1173 mutex_exit(&of->f_mutex); 1174 return (NT_STATUS_SUCCESS); 1175 } 1176 1177 cred_t * 1178 smb_ofile_getcred(smb_ofile_t *of) 1179 { 1180 return (of->f_cr); 1181 } 1182 1183 /* 1184 * smb_ofile_set_delete_on_close 1185 * 1186 * Set the DeleteOnClose flag on the smb file. When the file is closed, 1187 * the flag will be transferred to the smb node, which will commit the 1188 * delete operation and inhibit subsequent open requests. 1189 * 1190 * When DeleteOnClose is set on an smb_node, the common open code will 1191 * reject subsequent open requests for the file. Observation of Windows 1192 * 2000 indicates that subsequent opens should be allowed (assuming 1193 * there would be no sharing violation) until the file is closed using 1194 * the fid on which the DeleteOnClose was requested. 1195 */ 1196 void 1197 smb_ofile_set_delete_on_close(smb_ofile_t *of) 1198 { 1199 mutex_enter(&of->f_mutex); 1200 of->f_flags |= SMB_OFLAGS_SET_DELETE_ON_CLOSE; 1201 mutex_exit(&of->f_mutex); 1202 } 1203 1204 /* 1205 * Encode open file information into a buffer; needed in user space to 1206 * support RPC requests. 1207 */ 1208 static int 1209 smb_ofile_netinfo_encode(smb_ofile_t *of, uint8_t *buf, size_t buflen, 1210 uint32_t *nbytes) 1211 { 1212 smb_netfileinfo_t fi; 1213 int rc; 1214 1215 rc = smb_ofile_netinfo_init(of, &fi); 1216 if (rc == 0) { 1217 rc = smb_netfileinfo_encode(&fi, buf, buflen, nbytes); 1218 smb_ofile_netinfo_fini(&fi); 1219 } 1220 1221 return (rc); 1222 } 1223 1224 static int 1225 smb_ofile_netinfo_init(smb_ofile_t *of, smb_netfileinfo_t *fi) 1226 { 1227 smb_user_t *user; 1228 smb_tree_t *tree; 1229 smb_node_t *node; 1230 char *path; 1231 char *buf; 1232 int rc; 1233 1234 ASSERT(of); 1235 user = of->f_user; 1236 tree = of->f_tree; 1237 ASSERT(user); 1238 ASSERT(tree); 1239 1240 buf = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 1241 1242 switch (of->f_ftype) { 1243 case SMB_FTYPE_DISK: 1244 node = of->f_node; 1245 ASSERT(node); 1246 1247 fi->fi_permissions = of->f_granted_access; 1248 fi->fi_numlocks = smb_lock_get_lock_count(node); 1249 1250 path = kmem_zalloc(MAXPATHLEN, KM_SLEEP); 1251 1252 if (node != tree->t_snode) { 1253 rc = vnodetopath(tree->t_snode->vp, node->vp, path, 1254 MAXPATHLEN, kcred); 1255 if (rc == 0) 1256 (void) strsubst(path, '/', '\\'); 1257 else 1258 (void) strlcpy(path, node->od_name, MAXPATHLEN); 1259 } 1260 1261 (void) snprintf(buf, MAXPATHLEN, "%s:%s", tree->t_sharename, 1262 path); 1263 kmem_free(path, MAXPATHLEN); 1264 break; 1265 1266 case SMB_FTYPE_MESG_PIPE: 1267 ASSERT(of->f_pipe); 1268 1269 fi->fi_permissions = FILE_READ_DATA | FILE_WRITE_DATA | 1270 FILE_EXECUTE; 1271 fi->fi_numlocks = 0; 1272 (void) snprintf(buf, MAXPATHLEN, "\\PIPE\\%s", 1273 of->f_pipe->p_name); 1274 break; 1275 1276 default: 1277 kmem_free(buf, MAXPATHLEN); 1278 return (-1); 1279 } 1280 1281 fi->fi_fid = of->f_fid; 1282 fi->fi_uniqid = of->f_uniqid; 1283 fi->fi_pathlen = strlen(buf) + 1; 1284 fi->fi_path = smb_strdup(buf); 1285 kmem_free(buf, MAXPATHLEN); 1286 1287 fi->fi_namelen = user->u_domain_len + user->u_name_len + 2; 1288 fi->fi_username = kmem_alloc(fi->fi_namelen, KM_SLEEP); 1289 (void) snprintf(fi->fi_username, fi->fi_namelen, "%s\\%s", 1290 user->u_domain, user->u_name); 1291 return (0); 1292 } 1293 1294 static void 1295 smb_ofile_netinfo_fini(smb_netfileinfo_t *fi) 1296 { 1297 if (fi == NULL) 1298 return; 1299 1300 if (fi->fi_path) 1301 smb_mfree(fi->fi_path); 1302 if (fi->fi_username) 1303 kmem_free(fi->fi_username, fi->fi_namelen); 1304 1305 bzero(fi, sizeof (smb_netfileinfo_t)); 1306 } 1307