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