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