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 /* 23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2017 Nexenta Systems, Inc. All rights reserved. 25 */ 26 27 /* 28 * This module provides the common open functionality to the various 29 * open and create SMB interface functions. 30 */ 31 32 #include <sys/types.h> 33 #include <sys/cmn_err.h> 34 #include <sys/fcntl.h> 35 #include <sys/nbmlock.h> 36 #include <smbsrv/string.h> 37 #include <smbsrv/smb2_kproto.h> 38 #include <smbsrv/smb_fsops.h> 39 #include <smbsrv/smbinfo.h> 40 41 int smb_session_ofile_max = 32768; 42 43 static volatile uint32_t smb_fids = 0; 44 #define SMB_UNIQ_FID() atomic_inc_32_nv(&smb_fids) 45 46 static uint32_t smb_open_subr(smb_request_t *); 47 extern uint32_t smb_is_executable(char *); 48 static void smb_delete_new_object(smb_request_t *); 49 static int smb_set_open_attributes(smb_request_t *, smb_ofile_t *); 50 static void smb_open_oplock_break(smb_request_t *, smb_node_t *); 51 static boolean_t smb_open_attr_only(smb_arg_open_t *); 52 static boolean_t smb_open_overwrite(smb_arg_open_t *); 53 54 /* 55 * smb_access_generic_to_file 56 * 57 * Search MSDN for IoCreateFile to see following mapping. 58 * 59 * GENERIC_READ STANDARD_RIGHTS_READ, FILE_READ_DATA, 60 * FILE_READ_ATTRIBUTES and FILE_READ_EA 61 * 62 * GENERIC_WRITE STANDARD_RIGHTS_WRITE, FILE_WRITE_DATA, 63 * FILE_WRITE_ATTRIBUTES, FILE_WRITE_EA, and FILE_APPEND_DATA 64 * 65 * GENERIC_EXECUTE STANDARD_RIGHTS_EXECUTE, SYNCHRONIZE, and FILE_EXECUTE. 66 */ 67 static uint32_t 68 smb_access_generic_to_file(uint32_t desired_access) 69 { 70 uint32_t access = 0; 71 72 if (desired_access & GENERIC_ALL) 73 return (FILE_ALL_ACCESS & ~SYNCHRONIZE); 74 75 if (desired_access & GENERIC_EXECUTE) { 76 desired_access &= ~GENERIC_EXECUTE; 77 access |= (STANDARD_RIGHTS_EXECUTE | 78 SYNCHRONIZE | FILE_EXECUTE); 79 } 80 81 if (desired_access & GENERIC_WRITE) { 82 desired_access &= ~GENERIC_WRITE; 83 access |= (FILE_GENERIC_WRITE & ~SYNCHRONIZE); 84 } 85 86 if (desired_access & GENERIC_READ) { 87 desired_access &= ~GENERIC_READ; 88 access |= FILE_GENERIC_READ; 89 } 90 91 return (access | desired_access); 92 } 93 94 /* 95 * smb_omode_to_amask 96 * 97 * This function converts open modes used by Open and Open AndX 98 * commands to desired access bits used by NT Create AndX command. 99 */ 100 uint32_t 101 smb_omode_to_amask(uint32_t desired_access) 102 { 103 switch (desired_access & SMB_DA_ACCESS_MASK) { 104 case SMB_DA_ACCESS_READ: 105 return (FILE_GENERIC_READ); 106 107 case SMB_DA_ACCESS_WRITE: 108 return (FILE_GENERIC_WRITE); 109 110 case SMB_DA_ACCESS_READ_WRITE: 111 return (FILE_GENERIC_READ | FILE_GENERIC_WRITE); 112 113 case SMB_DA_ACCESS_EXECUTE: 114 return (FILE_GENERIC_READ | FILE_GENERIC_EXECUTE); 115 116 default: 117 return (FILE_GENERIC_ALL); 118 } 119 } 120 121 /* 122 * smb_denymode_to_sharemode 123 * 124 * This function converts deny modes used by Open and Open AndX 125 * commands to share access bits used by NT Create AndX command. 126 */ 127 uint32_t 128 smb_denymode_to_sharemode(uint32_t desired_access, char *fname) 129 { 130 switch (desired_access & SMB_DA_SHARE_MASK) { 131 case SMB_DA_SHARE_COMPATIBILITY: 132 if (smb_is_executable(fname)) 133 return (FILE_SHARE_READ | FILE_SHARE_WRITE); 134 135 return (FILE_SHARE_ALL); 136 137 case SMB_DA_SHARE_EXCLUSIVE: 138 return (FILE_SHARE_NONE); 139 140 case SMB_DA_SHARE_DENY_WRITE: 141 return (FILE_SHARE_READ); 142 143 case SMB_DA_SHARE_DENY_READ: 144 return (FILE_SHARE_WRITE); 145 146 case SMB_DA_SHARE_DENY_NONE: 147 default: 148 return (FILE_SHARE_READ | FILE_SHARE_WRITE); 149 } 150 } 151 152 /* 153 * smb_ofun_to_crdisposition 154 * 155 * This function converts open function values used by Open and Open AndX 156 * commands to create disposition values used by NT Create AndX command. 157 */ 158 uint32_t 159 smb_ofun_to_crdisposition(uint16_t ofun) 160 { 161 static int ofun_cr_map[3][2] = 162 { 163 { -1, FILE_CREATE }, 164 { FILE_OPEN, FILE_OPEN_IF }, 165 { FILE_OVERWRITE, FILE_OVERWRITE_IF } 166 }; 167 168 int row = ofun & SMB_OFUN_OPEN_MASK; 169 int col = (ofun & SMB_OFUN_CREATE_MASK) >> 4; 170 171 if (row == 3) 172 return (FILE_MAXIMUM_DISPOSITION + 1); 173 174 return (ofun_cr_map[row][col]); 175 } 176 177 /* 178 * Retry opens to avoid spurious sharing violations, due to timing 179 * issues between closes and opens. The client that already has the 180 * file open may be in the process of closing it. 181 */ 182 uint32_t 183 smb_common_open(smb_request_t *sr) 184 { 185 smb_arg_open_t *parg; 186 uint32_t status = NT_STATUS_SUCCESS; 187 int count; 188 189 parg = kmem_alloc(sizeof (*parg), KM_SLEEP); 190 bcopy(&sr->arg.open, parg, sizeof (*parg)); 191 192 for (count = 0; count <= 4; count++) { 193 if (count != 0) 194 delay(MSEC_TO_TICK(400)); 195 196 status = smb_open_subr(sr); 197 if (status != NT_STATUS_SHARING_VIOLATION) 198 break; 199 200 bcopy(parg, &sr->arg.open, sizeof (*parg)); 201 } 202 203 if (status == NT_STATUS_NO_SUCH_FILE) 204 status = NT_STATUS_OBJECT_NAME_NOT_FOUND; 205 206 kmem_free(parg, sizeof (*parg)); 207 return (status); 208 } 209 210 /* 211 * smb_open_subr 212 * 213 * Notes on write-through behaviour. It looks like pre-LM0.12 versions 214 * of the protocol specify the write-through mode when a file is opened, 215 * (SmbOpen, SmbOpenAndX) so the write calls (SmbWrite, SmbWriteAndClose, 216 * SmbWriteAndUnlock) don't need to contain a write-through flag. 217 * 218 * With LM0.12, the open calls (SmbCreateAndX, SmbNtTransactCreate) 219 * don't indicate which write-through mode to use. Instead the write 220 * calls (SmbWriteAndX, SmbWriteRaw) specify the mode on a per call 221 * basis. 222 * 223 * We don't care which open call was used to get us here, we just need 224 * to ensure that the write-through mode flag is copied from the open 225 * parameters to the node. We test the omode write-through flag in all 226 * write functions. 227 * 228 * This function returns NT status codes. 229 * 230 * The following rules apply when processing a file open request: 231 * 232 * - Oplocks must be broken prior to share checking as the break may 233 * cause other clients to close the file, which would affect sharing 234 * checks. 235 * 236 * - Share checks must take place prior to access checks for correct 237 * Windows semantics and to prevent unnecessary NFS delegation recalls. 238 * 239 * - Oplocks must be acquired after open to ensure the correct 240 * synchronization with NFS delegation and FEM installation. 241 * 242 * DOS readonly bit rules 243 * 244 * 1. The creator of a readonly file can write to/modify the size of the file 245 * using the original create fid, even though the file will appear as readonly 246 * to all other fids and via a CIFS getattr call. 247 * 248 * 2. A setinfo operation (using either an open fid or a path) to set/unset 249 * readonly will be successful regardless of whether a creator of a readonly 250 * file has an open fid. 251 * 252 * 3. The DOS readonly bit affects only data and some metadata. 253 * The following metadata can be changed regardless of the readonly bit: 254 * - security descriptors 255 * - DOS attributes 256 * - timestamps 257 * 258 * In the current implementation, the file size cannot be changed (except for 259 * the exceptions in #1 and #2, above). 260 * 261 * 262 * DOS attribute rules 263 * 264 * These rules are specific to creating / opening files and directories. 265 * How the attribute value (specifically ZERO or FILE_ATTRIBUTE_NORMAL) 266 * should be interpreted may differ in other requests. 267 * 268 * - An attribute value equal to ZERO or FILE_ATTRIBUTE_NORMAL means that the 269 * file's attributes should be cleared. 270 * - If FILE_ATTRIBUTE_NORMAL is specified with any other attributes, 271 * FILE_ATTRIBUTE_NORMAL is ignored. 272 * 273 * 1. Creating a new file 274 * - The request attributes + FILE_ATTRIBUTE_ARCHIVE are applied to the file. 275 * 276 * 2. Creating a new directory 277 * - The request attributes + FILE_ATTRIBUTE_DIRECTORY are applied to the file. 278 * - FILE_ATTRIBUTE_ARCHIVE does not get set. 279 * 280 * 3. Overwriting an existing file 281 * - the request attributes are used as search attributes. If the existing 282 * file does not meet the search criteria access is denied. 283 * - otherwise, applies attributes + FILE_ATTRIBUTE_ARCHIVE. 284 * 285 * 4. Opening an existing file or directory 286 * The request attributes are ignored. 287 */ 288 static uint32_t 289 smb_open_subr(smb_request_t *sr) 290 { 291 boolean_t created = B_FALSE; 292 boolean_t last_comp_found = B_FALSE; 293 smb_node_t *node = NULL; 294 smb_node_t *dnode = NULL; 295 smb_node_t *cur_node = NULL; 296 smb_arg_open_t *op = &sr->sr_open; 297 int rc; 298 smb_ofile_t *of; 299 smb_attr_t new_attr; 300 int max_requested = 0; 301 uint32_t max_allowed; 302 uint32_t status = NT_STATUS_SUCCESS; 303 int is_dir; 304 smb_error_t err; 305 boolean_t is_stream = B_FALSE; 306 int lookup_flags = SMB_FOLLOW_LINKS; 307 uint32_t uniq_fid; 308 smb_pathname_t *pn = &op->fqi.fq_path; 309 smb_server_t *sv = sr->sr_server; 310 311 /* Get out now if we've been cancelled. */ 312 mutex_enter(&sr->sr_mutex); 313 if (sr->sr_state != SMB_REQ_STATE_ACTIVE) { 314 mutex_exit(&sr->sr_mutex); 315 return (NT_STATUS_CANCELLED); 316 } 317 mutex_exit(&sr->sr_mutex); 318 319 is_dir = (op->create_options & FILE_DIRECTORY_FILE) ? 1 : 0; 320 321 /* 322 * If the object being created or opened is a directory 323 * the Disposition parameter must be one of FILE_CREATE, 324 * FILE_OPEN, or FILE_OPEN_IF 325 */ 326 if (is_dir) { 327 if ((op->create_disposition != FILE_CREATE) && 328 (op->create_disposition != FILE_OPEN_IF) && 329 (op->create_disposition != FILE_OPEN)) { 330 return (NT_STATUS_INVALID_PARAMETER); 331 } 332 } 333 334 if (op->desired_access & MAXIMUM_ALLOWED) { 335 max_requested = 1; 336 op->desired_access &= ~MAXIMUM_ALLOWED; 337 } 338 op->desired_access = smb_access_generic_to_file(op->desired_access); 339 340 if (sr->session->s_file_cnt >= smb_session_ofile_max) { 341 ASSERT(sr->uid_user); 342 cmn_err(CE_NOTE, "smbsrv[%s\\%s]: TOO_MANY_OPENED_FILES", 343 sr->uid_user->u_domain, sr->uid_user->u_name); 344 return (NT_STATUS_TOO_MANY_OPENED_FILES); 345 } 346 347 /* This must be NULL at this point */ 348 sr->fid_ofile = NULL; 349 350 op->devstate = 0; 351 352 switch (sr->tid_tree->t_res_type & STYPE_MASK) { 353 case STYPE_DISKTREE: 354 case STYPE_PRINTQ: 355 break; 356 357 case STYPE_IPC: 358 /* 359 * Security descriptors for pipes are not implemented, 360 * so just setup a reasonable access mask. 361 */ 362 op->desired_access = (READ_CONTROL | SYNCHRONIZE | 363 FILE_READ_DATA | FILE_READ_ATTRIBUTES | 364 FILE_WRITE_DATA | FILE_APPEND_DATA); 365 366 /* 367 * Limit the number of open pipe instances. 368 */ 369 if ((rc = smb_threshold_enter(&sv->sv_opipe_ct)) != 0) { 370 status = RPC_NT_SERVER_TOO_BUSY; 371 return (status); 372 } 373 374 /* 375 * No further processing for IPC, we need to either 376 * raise an exception or return success here. 377 */ 378 uniq_fid = SMB_UNIQ_FID(); 379 status = smb_opipe_open(sr, uniq_fid); 380 smb_threshold_exit(&sv->sv_opipe_ct); 381 return (status); 382 383 default: 384 return (NT_STATUS_BAD_DEVICE_TYPE); 385 } 386 387 smb_pathname_init(sr, pn, pn->pn_path); 388 if (!smb_pathname_validate(sr, pn)) 389 return (sr->smb_error.status); 390 391 if (strlen(pn->pn_path) >= SMB_MAXPATHLEN) { 392 return (NT_STATUS_OBJECT_PATH_INVALID); 393 } 394 395 if (is_dir) { 396 if (!smb_validate_dirname(sr, pn)) 397 return (sr->smb_error.status); 398 } else { 399 if (!smb_validate_object_name(sr, pn)) 400 return (sr->smb_error.status); 401 } 402 403 cur_node = op->fqi.fq_dnode ? 404 op->fqi.fq_dnode : sr->tid_tree->t_snode; 405 406 rc = smb_pathname_reduce(sr, sr->user_cr, pn->pn_path, 407 sr->tid_tree->t_snode, cur_node, &op->fqi.fq_dnode, 408 op->fqi.fq_last_comp); 409 if (rc != 0) { 410 return (smb_errno2status(rc)); 411 } 412 413 /* 414 * If the access mask has only DELETE set (ignore 415 * FILE_READ_ATTRIBUTES), then assume that this 416 * is a request to delete the link (if a link) 417 * and do not follow links. Otherwise, follow 418 * the link to the target. 419 */ 420 if ((op->desired_access & ~FILE_READ_ATTRIBUTES) == DELETE) 421 lookup_flags &= ~SMB_FOLLOW_LINKS; 422 423 rc = smb_fsop_lookup_name(sr, zone_kcred(), lookup_flags, 424 sr->tid_tree->t_snode, op->fqi.fq_dnode, op->fqi.fq_last_comp, 425 &op->fqi.fq_fnode); 426 427 if (rc == 0) { 428 last_comp_found = B_TRUE; 429 /* 430 * Need the DOS attributes below, where we 431 * check the search attributes (sattr). 432 */ 433 op->fqi.fq_fattr.sa_mask = SMB_AT_DOSATTR; 434 rc = smb_node_getattr(sr, op->fqi.fq_fnode, zone_kcred(), 435 NULL, &op->fqi.fq_fattr); 436 if (rc != 0) { 437 smb_node_release(op->fqi.fq_fnode); 438 smb_node_release(op->fqi.fq_dnode); 439 return (NT_STATUS_INTERNAL_ERROR); 440 } 441 } else if (rc == ENOENT) { 442 last_comp_found = B_FALSE; 443 op->fqi.fq_fnode = NULL; 444 rc = 0; 445 } else { 446 smb_node_release(op->fqi.fq_dnode); 447 return (smb_errno2status(rc)); 448 } 449 450 451 /* 452 * The uniq_fid is a CIFS-server-wide unique identifier for an ofile 453 * which is used to uniquely identify open instances for the 454 * VFS share reservation and POSIX locks. 455 */ 456 457 uniq_fid = SMB_UNIQ_FID(); 458 459 if (last_comp_found) { 460 461 node = op->fqi.fq_fnode; 462 dnode = op->fqi.fq_dnode; 463 464 if (!smb_node_is_file(node) && !smb_node_is_dir(node) && 465 !smb_node_is_symlink(node)) { 466 smb_node_release(node); 467 smb_node_release(dnode); 468 return (NT_STATUS_ACCESS_DENIED); 469 } 470 471 /* 472 * Reject this request if either: 473 * - the target IS a directory and the client requires that 474 * it must NOT be (required by Lotus Notes) 475 * - the target is NOT a directory and client requires that 476 * it MUST be. 477 */ 478 if (smb_node_is_dir(node)) { 479 if (op->create_options & FILE_NON_DIRECTORY_FILE) { 480 smb_node_release(node); 481 smb_node_release(dnode); 482 return (NT_STATUS_FILE_IS_A_DIRECTORY); 483 } 484 } else { 485 if ((op->create_options & FILE_DIRECTORY_FILE) || 486 (op->nt_flags & NT_CREATE_FLAG_OPEN_TARGET_DIR)) { 487 smb_node_release(node); 488 smb_node_release(dnode); 489 return (NT_STATUS_NOT_A_DIRECTORY); 490 } 491 } 492 493 /* 494 * No more open should be accepted when "Delete on close" 495 * flag is set. 496 */ 497 if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) { 498 smb_node_release(node); 499 smb_node_release(dnode); 500 return (NT_STATUS_DELETE_PENDING); 501 } 502 503 /* 504 * Specified file already exists so the operation should fail. 505 */ 506 if (op->create_disposition == FILE_CREATE) { 507 smb_node_release(node); 508 smb_node_release(dnode); 509 return (NT_STATUS_OBJECT_NAME_COLLISION); 510 } 511 512 /* 513 * Windows seems to check read-only access before file 514 * sharing check. 515 * 516 * Check to see if the file is currently readonly (irrespective 517 * of whether this open will make it readonly). 518 */ 519 if (SMB_PATHFILE_IS_READONLY(sr, node)) { 520 /* Files data only */ 521 if (!smb_node_is_dir(node)) { 522 if (op->desired_access & (FILE_WRITE_DATA | 523 FILE_APPEND_DATA)) { 524 smb_node_release(node); 525 smb_node_release(dnode); 526 return (NT_STATUS_ACCESS_DENIED); 527 } 528 if (op->create_options & FILE_DELETE_ON_CLOSE) { 529 smb_node_release(node); 530 smb_node_release(dnode); 531 return (NT_STATUS_CANNOT_DELETE); 532 } 533 } 534 } 535 536 if ((op->create_disposition == FILE_SUPERSEDE) || 537 (op->create_disposition == FILE_OVERWRITE_IF) || 538 (op->create_disposition == FILE_OVERWRITE)) { 539 540 if (!smb_sattr_check(op->fqi.fq_fattr.sa_dosattr, 541 op->dattr)) { 542 smb_node_release(node); 543 smb_node_release(dnode); 544 return (NT_STATUS_ACCESS_DENIED); 545 } 546 547 if (smb_node_is_dir(node)) { 548 smb_node_release(node); 549 smb_node_release(dnode); 550 return (NT_STATUS_ACCESS_DENIED); 551 } 552 } 553 554 /* MS-FSA 2.1.5.1.2 */ 555 if (op->create_disposition == FILE_SUPERSEDE) 556 op->desired_access |= DELETE; 557 if ((op->create_disposition == FILE_OVERWRITE_IF) || 558 (op->create_disposition == FILE_OVERWRITE)) 559 op->desired_access |= FILE_WRITE_DATA; 560 561 status = smb_fsop_access(sr, sr->user_cr, node, 562 op->desired_access); 563 if (status != NT_STATUS_SUCCESS) { 564 smb_node_release(node); 565 smb_node_release(dnode); 566 567 /* SMB1 specific? NT_STATUS_PRIVILEGE_NOT_HELD */ 568 if (status == NT_STATUS_PRIVILEGE_NOT_HELD) { 569 return (status); 570 } else { 571 return (NT_STATUS_ACCESS_DENIED); 572 } 573 } 574 575 if (max_requested) { 576 smb_fsop_eaccess(sr, sr->user_cr, node, &max_allowed); 577 op->desired_access |= max_allowed; 578 } 579 /* 580 * According to MS "dochelp" mail in Mar 2015, any handle 581 * on which read or write access is granted implicitly 582 * gets "read attributes", even if it was not requested. 583 * This avoids unexpected access failures later that 584 * would happen if these were not granted. 585 */ 586 if ((op->desired_access & FILE_DATA_ALL) != 0) { 587 op->desired_access |= (READ_CONTROL | 588 FILE_READ_ATTRIBUTES); 589 } 590 591 /* 592 * Oplock break is done prior to sharing checks as the break 593 * may cause other clients to close the file which would 594 * affect the sharing checks, and may delete the file due to 595 * DELETE_ON_CLOSE. This may block, so set the file opening 596 * count before oplock stuff. 597 */ 598 smb_node_inc_opening_count(node); 599 smb_open_oplock_break(sr, node); 600 601 if ((node->flags & NODE_FLAGS_DELETE_COMMITTED) != 0) { 602 /* 603 * Breaking the oplock caused the file to be deleted, 604 * so let's bail and pretend the file wasn't found 605 */ 606 smb_node_dec_opening_count(node); 607 smb_node_release(node); 608 last_comp_found = B_FALSE; 609 goto create; 610 } 611 612 smb_node_wrlock(node); 613 614 /* 615 * Check for sharing violations 616 */ 617 status = smb_fsop_shrlock(sr->user_cr, node, uniq_fid, 618 op->desired_access, op->share_access); 619 if (status == NT_STATUS_SHARING_VIOLATION) { 620 smb_node_unlock(node); 621 smb_node_dec_opening_count(node); 622 smb_node_release(node); 623 smb_node_release(dnode); 624 return (status); 625 } 626 627 /* 628 * Go ahead with modifications as necessary. 629 */ 630 switch (op->create_disposition) { 631 case FILE_SUPERSEDE: 632 case FILE_OVERWRITE_IF: 633 case FILE_OVERWRITE: 634 op->dattr |= FILE_ATTRIBUTE_ARCHIVE; 635 /* Don't apply readonly until smb_set_open_attributes */ 636 if (op->dattr & FILE_ATTRIBUTE_READONLY) { 637 op->dattr &= ~FILE_ATTRIBUTE_READONLY; 638 op->created_readonly = B_TRUE; 639 } 640 641 /* 642 * Truncate the file data here. 643 * We set alloc_size = op->dsize later, 644 * after we have an ofile. See: 645 * smb_set_open_attributes 646 */ 647 bzero(&new_attr, sizeof (new_attr)); 648 new_attr.sa_dosattr = op->dattr; 649 new_attr.sa_vattr.va_size = 0; 650 new_attr.sa_mask = SMB_AT_DOSATTR | SMB_AT_SIZE; 651 rc = smb_fsop_setattr(sr, sr->user_cr, node, &new_attr); 652 if (rc != 0) { 653 smb_fsop_unshrlock(sr->user_cr, node, uniq_fid); 654 smb_node_unlock(node); 655 smb_node_dec_opening_count(node); 656 smb_node_release(node); 657 smb_node_release(dnode); 658 return (smb_errno2status(rc)); 659 } 660 661 /* 662 * If file is being replaced, remove existing streams 663 */ 664 if (SMB_IS_STREAM(node) == 0) { 665 status = smb_fsop_remove_streams(sr, 666 sr->user_cr, node); 667 if (status != 0) { 668 smb_fsop_unshrlock(sr->user_cr, node, 669 uniq_fid); 670 smb_node_unlock(node); 671 smb_node_dec_opening_count(node); 672 smb_node_release(node); 673 smb_node_release(dnode); 674 return (status); 675 } 676 } 677 678 op->action_taken = SMB_OACT_TRUNCATED; 679 break; 680 681 default: 682 /* 683 * FILE_OPEN or FILE_OPEN_IF. 684 */ 685 /* 686 * Ignore any user-specified alloc_size for 687 * existing files, to avoid truncation in 688 * smb_set_open_attributes 689 */ 690 op->dsize = 0L; 691 op->action_taken = SMB_OACT_OPENED; 692 break; 693 } 694 } else { 695 create: 696 /* Last component was not found. */ 697 dnode = op->fqi.fq_dnode; 698 699 if (is_dir == 0) 700 is_stream = smb_is_stream_name(pn->pn_path); 701 702 if ((op->create_disposition == FILE_OPEN) || 703 (op->create_disposition == FILE_OVERWRITE)) { 704 smb_node_release(dnode); 705 return (NT_STATUS_OBJECT_NAME_NOT_FOUND); 706 } 707 708 if (pn->pn_fname && smb_is_invalid_filename(pn->pn_fname)) { 709 smb_node_release(dnode); 710 return (NT_STATUS_OBJECT_NAME_INVALID); 711 } 712 713 /* 714 * Don't create in directories marked "Delete on close". 715 */ 716 if (dnode->flags & NODE_FLAGS_DELETE_ON_CLOSE) { 717 smb_node_release(dnode); 718 return (NT_STATUS_DELETE_PENDING); 719 } 720 721 /* 722 * lock the parent dir node in case another create 723 * request to the same parent directory comes in. 724 */ 725 smb_node_wrlock(dnode); 726 727 /* 728 * Create always sets the DOS attributes, type, and mode 729 * in the if/else below (different for file vs directory). 730 * Don't set the readonly bit until smb_set_open_attributes 731 * or that would prevent this open. Note that op->dattr 732 * needs to be what smb_set_open_attributes will use, 733 * except for the readonly bit. 734 */ 735 bzero(&new_attr, sizeof (new_attr)); 736 new_attr.sa_mask = SMB_AT_DOSATTR | SMB_AT_TYPE | SMB_AT_MODE; 737 if (op->dattr & FILE_ATTRIBUTE_READONLY) { 738 op->dattr &= ~FILE_ATTRIBUTE_READONLY; 739 op->created_readonly = B_TRUE; 740 } 741 742 /* 743 * SMB create can specify the create time. 744 */ 745 if ((op->crtime.tv_sec != 0) && 746 (op->crtime.tv_sec != UINT_MAX)) { 747 new_attr.sa_mask |= SMB_AT_CRTIME; 748 new_attr.sa_crtime = op->crtime; 749 } 750 751 if (is_dir == 0) { 752 op->dattr |= FILE_ATTRIBUTE_ARCHIVE; 753 new_attr.sa_dosattr = op->dattr; 754 new_attr.sa_vattr.va_type = VREG; 755 if (is_stream) 756 new_attr.sa_vattr.va_mode = S_IRUSR | S_IWUSR; 757 else 758 new_attr.sa_vattr.va_mode = 759 S_IRUSR | S_IRGRP | S_IROTH | 760 S_IWUSR | S_IWGRP | S_IWOTH; 761 762 /* 763 * We set alloc_size = op->dsize later, 764 * (in smb_set_open_attributes) after we 765 * have an ofile on which to save that. 766 * 767 * Legacy Open&X sets size to alloc_size 768 * when creating a new file. 769 */ 770 if (sr->smb_com == SMB_COM_OPEN_ANDX) { 771 new_attr.sa_vattr.va_size = op->dsize; 772 new_attr.sa_mask |= SMB_AT_SIZE; 773 } 774 775 rc = smb_fsop_create(sr, sr->user_cr, dnode, 776 op->fqi.fq_last_comp, &new_attr, &op->fqi.fq_fnode); 777 778 if (rc != 0) { 779 smb_node_unlock(dnode); 780 smb_node_release(dnode); 781 return (smb_errno2status(rc)); 782 } 783 784 node = op->fqi.fq_fnode; 785 smb_node_inc_opening_count(node); 786 smb_node_wrlock(node); 787 788 status = smb_fsop_shrlock(sr->user_cr, node, uniq_fid, 789 op->desired_access, op->share_access); 790 791 if (status == NT_STATUS_SHARING_VIOLATION) { 792 smb_node_unlock(node); 793 smb_node_dec_opening_count(node); 794 smb_delete_new_object(sr); 795 smb_node_release(node); 796 smb_node_unlock(dnode); 797 smb_node_release(dnode); 798 return (status); 799 } 800 } else { 801 op->dattr |= FILE_ATTRIBUTE_DIRECTORY; 802 new_attr.sa_dosattr = op->dattr; 803 new_attr.sa_vattr.va_type = VDIR; 804 new_attr.sa_vattr.va_mode = 0777; 805 806 rc = smb_fsop_mkdir(sr, sr->user_cr, dnode, 807 op->fqi.fq_last_comp, &new_attr, &op->fqi.fq_fnode); 808 if (rc != 0) { 809 smb_node_unlock(dnode); 810 smb_node_release(dnode); 811 return (smb_errno2status(rc)); 812 } 813 814 node = op->fqi.fq_fnode; 815 smb_node_inc_opening_count(node); 816 smb_node_wrlock(node); 817 } 818 819 created = B_TRUE; 820 op->action_taken = SMB_OACT_CREATED; 821 822 if (max_requested) { 823 smb_fsop_eaccess(sr, sr->user_cr, node, &max_allowed); 824 op->desired_access |= max_allowed; 825 } 826 /* 827 * We created this object (we own it) so grant 828 * read_control + read_attributes on this handle, 829 * even if that was not requested. This avoids 830 * unexpected access failures later. 831 */ 832 op->desired_access |= (READ_CONTROL | FILE_READ_ATTRIBUTES); 833 } 834 835 status = NT_STATUS_SUCCESS; 836 837 of = smb_ofile_open(sr, node, op, SMB_FTYPE_DISK, uniq_fid, 838 &err); 839 if (of == NULL) { 840 status = err.status; 841 } 842 843 /* 844 * We might have blocked in smb_ofile_open long enough so a 845 * tree disconnect might have happened. In that case, we've 846 * just added an ofile to a tree that's disconnecting, and 847 * need to undo that to avoid interfering with tear-down of 848 * the tree connection. 849 */ 850 if (status == NT_STATUS_SUCCESS && 851 !smb_tree_is_connected(sr->tid_tree)) { 852 status = NT_STATUS_INVALID_PARAMETER; 853 } 854 855 /* 856 * This MUST be done after ofile creation, so that explicitly 857 * set timestamps can be remembered on the ofile, and setting 858 * the readonly flag won't affect access via this open. 859 */ 860 if (status == NT_STATUS_SUCCESS) { 861 if ((rc = smb_set_open_attributes(sr, of)) != 0) { 862 status = smb_errno2status(rc); 863 } 864 } 865 866 if (status == NT_STATUS_SUCCESS) { 867 /* 868 * We've already done access checks above, 869 * and want this call to succeed even when 870 * !(desired_access & FILE_READ_ATTRIBUTES), 871 * so pass kcred here. 872 */ 873 op->fqi.fq_fattr.sa_mask = SMB_AT_ALL; 874 rc = smb_node_getattr(sr, node, zone_kcred(), of, 875 &op->fqi.fq_fattr); 876 if (rc != 0) { 877 status = NT_STATUS_INTERNAL_ERROR; 878 } 879 } 880 881 /* 882 * smb_fsop_unshrlock is a no-op if node is a directory 883 * smb_fsop_unshrlock is done in smb_ofile_close 884 */ 885 if (status != NT_STATUS_SUCCESS) { 886 if (of == NULL) { 887 smb_fsop_unshrlock(sr->user_cr, node, uniq_fid); 888 } else { 889 smb_ofile_close(of, 0); 890 smb_ofile_release(of); 891 } 892 if (created) 893 smb_delete_new_object(sr); 894 smb_node_unlock(node); 895 smb_node_dec_opening_count(node); 896 smb_node_release(node); 897 if (created) 898 smb_node_unlock(dnode); 899 smb_node_release(dnode); 900 return (status); 901 } 902 903 /* 904 * Propagate the write-through mode from the open params 905 * to the node: see the notes in the function header. 906 */ 907 if (sr->sr_cfg->skc_sync_enable || 908 (op->create_options & FILE_WRITE_THROUGH)) 909 node->flags |= NODE_FLAGS_WRITE_THROUGH; 910 911 /* 912 * Set up the fileid and dosattr in open_param for response 913 */ 914 op->fileid = op->fqi.fq_fattr.sa_vattr.va_nodeid; 915 op->dattr = op->fqi.fq_fattr.sa_dosattr; 916 917 /* 918 * Set up the file type in open_param for the response 919 */ 920 op->ftype = SMB_FTYPE_DISK; 921 sr->smb_fid = of->f_fid; 922 sr->fid_ofile = of; 923 924 if (smb_node_is_file(node)) { 925 smb_oplock_acquire(sr, node, of); 926 op->dsize = op->fqi.fq_fattr.sa_vattr.va_size; 927 } else { 928 /* directory or symlink */ 929 op->op_oplock_level = SMB_OPLOCK_NONE; 930 op->dsize = 0; 931 } 932 933 smb_node_dec_opening_count(node); 934 935 smb_node_unlock(node); 936 if (created) 937 smb_node_unlock(dnode); 938 939 smb_node_release(node); 940 smb_node_release(dnode); 941 942 return (NT_STATUS_SUCCESS); 943 } 944 945 /* 946 * smb_open_oplock_break 947 * 948 * If the node has an ofile opened with share access none, 949 * (smb_node_share_check = FALSE) only break BATCH oplock. 950 * Otherwise: 951 * If overwriting, break to SMB_OPLOCK_NONE, else 952 * If opening for anything other than attribute access, 953 * break oplock to LEVEL_II. 954 */ 955 static void 956 smb_open_oplock_break(smb_request_t *sr, smb_node_t *node) 957 { 958 smb_arg_open_t *op = &sr->sr_open; 959 uint32_t flags = 0; 960 int rc = 0; 961 962 if (sr->session->dialect >= SMB_VERS_2_BASE && 963 sr->smb2_async == B_FALSE) 964 flags |= SMB_OPLOCK_BREAK_NOWAIT; 965 966 if (!smb_node_share_check(node)) 967 flags |= SMB_OPLOCK_BREAK_BATCH; 968 969 if (smb_open_overwrite(op)) { 970 flags |= SMB_OPLOCK_BREAK_TO_NONE; 971 rc = smb_oplock_break(sr, node, flags); 972 } else if (!smb_open_attr_only(op)) { 973 flags |= SMB_OPLOCK_BREAK_TO_LEVEL_II; 974 rc = smb_oplock_break(sr, node, flags); 975 } 976 977 if (sr->session->dialect >= SMB_VERS_2_BASE && 978 rc == EAGAIN) { 979 (void) smb2sr_go_async(sr); 980 flags &= ~SMB_OPLOCK_BREAK_NOWAIT; 981 (void) smb_oplock_break(sr, node, flags); 982 } 983 } 984 985 /* 986 * smb_open_attr_only 987 * 988 * Determine if file is being opened for attribute access only. 989 * This is used to determine whether it is necessary to break 990 * existing oplocks on the file. 991 */ 992 static boolean_t 993 smb_open_attr_only(smb_arg_open_t *op) 994 { 995 if (((op->desired_access & ~(FILE_READ_ATTRIBUTES | 996 FILE_WRITE_ATTRIBUTES | SYNCHRONIZE | READ_CONTROL)) == 0) && 997 (op->create_disposition != FILE_SUPERSEDE) && 998 (op->create_disposition != FILE_OVERWRITE)) { 999 return (B_TRUE); 1000 } 1001 return (B_FALSE); 1002 } 1003 1004 static boolean_t 1005 smb_open_overwrite(smb_arg_open_t *op) 1006 { 1007 if ((op->create_disposition == FILE_SUPERSEDE) || 1008 (op->create_disposition == FILE_OVERWRITE_IF) || 1009 (op->create_disposition == FILE_OVERWRITE)) { 1010 return (B_TRUE); 1011 } 1012 return (B_FALSE); 1013 } 1014 1015 /* 1016 * smb_set_open_attributes 1017 * 1018 * Last write time: 1019 * - If the last_write time specified in the open params is not 0 or -1, 1020 * use it as file's mtime. This will be considered an explicitly set 1021 * timestamps, not reset by subsequent writes. 1022 * 1023 * DOS attributes 1024 * - If we created_readonly, we now store the real DOS attributes 1025 * (including the readonly bit) so subsequent opens will see it. 1026 * 1027 * Returns: errno 1028 */ 1029 static int 1030 smb_set_open_attributes(smb_request_t *sr, smb_ofile_t *of) 1031 { 1032 smb_attr_t attr; 1033 smb_arg_open_t *op = &sr->sr_open; 1034 smb_node_t *node = of->f_node; 1035 int rc = 0; 1036 1037 bzero(&attr, sizeof (smb_attr_t)); 1038 1039 if (op->created_readonly) { 1040 attr.sa_dosattr = op->dattr | FILE_ATTRIBUTE_READONLY; 1041 attr.sa_mask |= SMB_AT_DOSATTR; 1042 } 1043 1044 if (op->dsize != 0) { 1045 attr.sa_allocsz = op->dsize; 1046 attr.sa_mask |= SMB_AT_ALLOCSZ; 1047 } 1048 1049 if ((op->mtime.tv_sec != 0) && (op->mtime.tv_sec != UINT_MAX)) { 1050 attr.sa_vattr.va_mtime = op->mtime; 1051 attr.sa_mask |= SMB_AT_MTIME; 1052 } 1053 1054 /* 1055 * Used to have code here to set mtime, ctime, atime 1056 * when the open op->create_disposition is any of: 1057 * FILE_SUPERSEDE, FILE_OVERWRITE_IF, FILE_OVERWRITE. 1058 * We know that in those cases we will have set the 1059 * file size, in which case the file system will 1060 * update those times, so we don't have to. 1061 * 1062 * However, keep track of the fact that we modified 1063 * the file via this handle, so we can do the evil, 1064 * gratuitious mtime update on close that Windows 1065 * clients expect. 1066 */ 1067 if (op->action_taken == SMB_OACT_TRUNCATED) 1068 of->f_written = B_TRUE; 1069 1070 if (attr.sa_mask != 0) 1071 rc = smb_node_setattr(sr, node, of->f_cr, of, &attr); 1072 1073 return (rc); 1074 } 1075 1076 /* 1077 * This function is used to delete a newly created object (file or 1078 * directory) if an error occurs after creation of the object. 1079 */ 1080 static void 1081 smb_delete_new_object(smb_request_t *sr) 1082 { 1083 smb_arg_open_t *op = &sr->sr_open; 1084 smb_fqi_t *fqi = &(op->fqi); 1085 uint32_t flags = 0; 1086 1087 if (SMB_TREE_IS_CASEINSENSITIVE(sr)) 1088 flags |= SMB_IGNORE_CASE; 1089 if (SMB_TREE_SUPPORTS_CATIA(sr)) 1090 flags |= SMB_CATIA; 1091 1092 if (op->create_options & FILE_DIRECTORY_FILE) 1093 (void) smb_fsop_rmdir(sr, sr->user_cr, fqi->fq_dnode, 1094 fqi->fq_last_comp, flags); 1095 else 1096 (void) smb_fsop_remove(sr, sr->user_cr, fqi->fq_dnode, 1097 fqi->fq_last_comp, flags); 1098 } 1099