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