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