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