3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
24 * Copyright 2016 Syneto S.R.L. All rights reserved.
25 * Copyright (c) 2016 by Delphix. All rights reserved.
26 */
27
28 /*
29 * General Structures Layout
30 * -------------------------
31 *
32 * This is a simplified diagram showing the relationship between most of the
33 * main structures.
34 *
35 * +-------------------+
36 * | SMB_INFO |
37 * +-------------------+
38 * |
39 * |
40 * v
41 * +-------------------+ +-------------------+ +-------------------+
42 * | SESSION |<----->| SESSION |......| SESSION |
43 * +-------------------+ +-------------------+ +-------------------+
44 * | |
45 * | |
54 * | TREE |<----->| TREE |......| TREE |
55 * +-------------------+ +-------------------+ +-------------------+
56 * | |
57 * | |
58 * | v
59 * | +-------+ +-------+ +-------+
60 * | | OFILE |<----->| OFILE |......| OFILE |
61 * | +-------+ +-------+ +-------+
62 * |
63 * |
64 * v
65 * +-------+ +------+ +------+
66 * | ODIR |<----->| ODIR |......| ODIR |
67 * +-------+ +------+ +------+
68 *
69 *
70 * Ofile State Machine
71 * ------------------
72 *
73 * +-------------------------+ T0
74 * | SMB_OFILE_STATE_OPEN |<----------- Creation/Allocation
75 * +-------------------------+
76 * |
77 * | T1
78 * |
79 * v
80 * +-------------------------+
81 * | SMB_OFILE_STATE_CLOSING |
82 * +-------------------------+
83 * |
84 * | T2
85 * |
86 * v
87 * +-------------------------+ T3
88 * | SMB_OFILE_STATE_CLOSED |----------> Deletion/Free
89 * +-------------------------+
90 *
91 * SMB_OFILE_STATE_OPEN
92 *
93 * While in this state:
94 * - The ofile is queued in the list of ofiles of its tree.
95 * - References will be given out if the ofile is looked up.
96 *
97 * SMB_OFILE_STATE_CLOSING
98 *
99 * While in this state:
100 * - The ofile is queued in the list of ofiles of its tree.
101 * - References will not be given out if the ofile is looked up.
102 * - The file is closed and the locks held are being released.
103 * - The resources associated with the ofile remain.
104 *
105 * SMB_OFILE_STATE_CLOSED
106 *
107 * While in this state:
108 * - The ofile is queued in the list of ofiles of its tree.
109 * - References will not be given out if the ofile is looked up.
110 * - The resources associated with the ofile remain.
111 *
112 * Transition T0
113 *
114 * This transition occurs in smb_ofile_open(). A new ofile is created and
115 * added to the list of ofiles of a tree.
116 *
117 * Transition T1
118 *
119 * This transition occurs in smb_ofile_close().
120 *
121 * Transition T2
122 *
123 * This transition occurs in smb_ofile_release(). The resources associated
124 * with the ofile are freed as well as the ofile structure. For the
125 * transition to occur, the ofile must be in the SMB_OFILE_STATE_CLOSED
126 * state and the reference count be zero.
127 *
128 * Comments
129 * --------
130 *
131 * The state machine of the ofile structures is controlled by 3 elements:
132 * - The list of ofiles of the tree it belongs to.
133 * - The mutex embedded in the structure itself.
134 * - The reference count.
135 *
136 * There's a mutex embedded in the ofile structure used to protect its fields
137 * and there's a lock embedded in the list of ofiles of a tree. To
138 * increment or to decrement the reference count the mutex must be entered.
139 * To insert the ofile into the list of ofiles of the tree and to remove
140 * the ofile from it, the lock must be entered in RW_WRITER mode.
141 *
142 * Rules of access to a ofile structure:
143 *
144 * 1) In order to avoid deadlocks, when both (mutex and lock of the ofile
145 * list) have to be entered, the lock must be entered first.
146 *
147 * 2) All actions applied to an ofile require a reference count.
148 *
149 * 3) There are 2 ways of getting a reference count. One is when the ofile
150 * is opened. The other one when the ofile is looked up. This translates
151 * into 2 functions: smb_ofile_open() and smb_ofile_lookup_by_fid().
152 *
153 * It should be noted that the reference count of an ofile registers the
154 * number of references to the ofile in other structures (such as an smb
155 * request). The reference count is not incremented in these 2 instances:
156 *
157 * 1) The ofile is open. An ofile is anchored by its state. If there's
158 * no activity involving an ofile currently open, the reference count
159 * of that ofile is zero.
160 *
161 * 2) The ofile is queued in the list of ofiles of its tree. The fact of
162 * being queued in that list is NOT registered by incrementing the
163 * reference count.
164 */
165 #include <smbsrv/smb_kproto.h>
166 #include <smbsrv/smb_fsops.h>
167
168 static boolean_t smb_ofile_is_open_locked(smb_ofile_t *);
169 static smb_ofile_t *smb_ofile_close_and_next(smb_ofile_t *);
170 static int smb_ofile_netinfo_encode(smb_ofile_t *, uint8_t *, size_t,
171 uint32_t *);
172 static int smb_ofile_netinfo_init(smb_ofile_t *, smb_netfileinfo_t *);
173 static void smb_ofile_netinfo_fini(smb_netfileinfo_t *);
174
175 /*
176 * smb_ofile_open
177 */
178 smb_ofile_t *
179 smb_ofile_open(
180 smb_request_t *sr,
181 smb_node_t *node,
182 struct open_param *op,
183 uint16_t ftype,
184 uint32_t uniqid,
185 smb_error_t *err)
186 {
187 smb_tree_t *tree = sr->tid_tree;
188 smb_ofile_t *of;
189 uint16_t fid;
190 smb_attr_t attr;
191 int rc;
192 enum errstates { EMPTY, FIDALLOC, CRHELD, MUTEXINIT };
193 enum errstates state = EMPTY;
194
195 if (smb_idpool_alloc(&tree->t_fid_pool, &fid)) {
196 err->status = NT_STATUS_TOO_MANY_OPENED_FILES;
197 err->errcls = ERRDOS;
198 err->errcode = ERROR_TOO_MANY_OPEN_FILES;
199 return (NULL);
200 }
201 state = FIDALLOC;
202
203 of = kmem_cache_alloc(smb_cache_ofile, KM_SLEEP);
204 bzero(of, sizeof (smb_ofile_t));
205 of->f_magic = SMB_OFILE_MAGIC;
206 of->f_refcnt = 1;
207 of->f_fid = fid;
208 of->f_uniqid = uniqid;
209 of->f_opened_by_pid = sr->smb_pid;
210 of->f_granted_access = op->desired_access;
211 of->f_share_access = op->share_access;
212 of->f_create_options = op->create_options;
213 of->f_cr = (op->create_options & FILE_OPEN_FOR_BACKUP_INTENT) ?
214 smb_user_getprivcred(sr->uid_user) : sr->uid_user->u_cred;
215 crhold(of->f_cr);
216 state = CRHELD;
217 of->f_ftype = ftype;
218 of->f_server = tree->t_server;
219 of->f_session = tree->t_session;
220 /*
221 * grab a ref for of->f_user
222 * released in smb_ofile_delete()
223 */
224 smb_user_hold_internal(sr->uid_user);
225 of->f_user = sr->uid_user;
226 of->f_tree = tree;
227 of->f_node = node;
228
229 mutex_init(&of->f_mutex, NULL, MUTEX_DEFAULT, NULL);
230 state = MUTEXINIT;
231 of->f_state = SMB_OFILE_STATE_OPEN;
232
233 if (ftype == SMB_FTYPE_MESG_PIPE) {
234 /* See smb_opipe_open. */
235 of->f_pipe = op->pipe;
236 smb_server_inc_pipes(of->f_server);
237 } else {
238 ASSERT(ftype == SMB_FTYPE_DISK); /* Regular file, not a pipe */
239 ASSERT(node);
240
241 /*
242 * Note that the common open path often adds bits like
243 * READ_CONTROL, so the logic "is this open exec-only"
244 * needs to look at only the FILE_DATA_ALL bits.
245 */
246 if ((of->f_granted_access & FILE_DATA_ALL) == FILE_EXECUTE)
247 of->f_flags |= SMB_OFLAGS_EXECONLY;
248
249 bzero(&attr, sizeof (smb_attr_t));
250 attr.sa_mask = SMB_AT_UID | SMB_AT_DOSATTR;
251 rc = smb_node_getattr(NULL, node, of->f_cr, NULL, &attr);
252 if (rc != 0) {
253 err->status = NT_STATUS_INTERNAL_ERROR;
254 err->errcls = ERRDOS;
255 err->errcode = ERROR_INTERNAL_ERROR;
256 goto errout;
257 }
258 if (crgetuid(of->f_cr) == attr.sa_vattr.va_uid) {
259 /*
260 * Add this bit for the file's owner even if it's not
261 * specified in the request (Windows behavior).
262 */
263 of->f_granted_access |= FILE_READ_ATTRIBUTES;
264 }
265
266 if (smb_node_is_file(node)) {
267 of->f_mode =
268 smb_fsop_amask_to_omode(of->f_granted_access);
269 if (smb_fsop_open(node, of->f_mode, of->f_cr) != 0) {
270 err->status = NT_STATUS_ACCESS_DENIED;
271 err->errcls = ERRDOS;
272 err->errcode = ERROR_ACCESS_DENIED;
273 goto errout;
274 }
275 }
276
277 if (tree->t_flags & SMB_TREE_READONLY)
278 of->f_flags |= SMB_OFLAGS_READONLY;
279
280 /*
281 * Note that if we created_readonly, that
282 * will _not_ yet show in attr.sa_dosattr
283 * so creating a readonly file gives the
284 * caller a writable handle as it should.
285 */
286 if (attr.sa_dosattr & FILE_ATTRIBUTE_READONLY)
287 of->f_flags |= SMB_OFLAGS_READONLY;
288
289 smb_node_inc_open_ofiles(node);
290 smb_node_add_ofile(node, of);
291 smb_node_ref(node);
292 smb_server_inc_files(of->f_server);
293 }
294 smb_llist_enter(&tree->t_ofile_list, RW_WRITER);
295 smb_llist_insert_tail(&tree->t_ofile_list, of);
296 smb_llist_exit(&tree->t_ofile_list);
297 atomic_inc_32(&tree->t_open_files);
298 atomic_inc_32(&of->f_session->s_file_cnt);
299 return (of);
300
301 errout:
302 switch (state) {
303 case MUTEXINIT:
304 mutex_destroy(&of->f_mutex);
305 smb_user_release(of->f_user);
306 /*FALLTHROUGH*/
307 case CRHELD:
308 crfree(of->f_cr);
309 of->f_magic = 0;
310 kmem_cache_free(smb_cache_ofile, of);
311 /*FALLTHROUGH*/
312 case FIDALLOC:
313 smb_idpool_free(&tree->t_fid_pool, fid);
314 /*FALLTHROUGH*/
315 case EMPTY:
316 break;
317 }
318 return (NULL);
319 }
320
321 /*
322 * smb_ofile_close
323 */
324 void
325 smb_ofile_close(smb_ofile_t *of, int32_t mtime_sec)
326 {
327 smb_attr_t *pa;
328 timestruc_t now;
329 uint32_t flags = 0;
330
331 SMB_OFILE_VALID(of);
332
333 mutex_enter(&of->f_mutex);
334 ASSERT(of->f_refcnt);
335 if (of->f_state != SMB_OFILE_STATE_OPEN) {
336 mutex_exit(&of->f_mutex);
337 return;
338 }
339 of->f_state = SMB_OFILE_STATE_CLOSING;
340 mutex_exit(&of->f_mutex);
341
342 switch (of->f_ftype) {
343 case SMB_FTYPE_BYTE_PIPE:
344 case SMB_FTYPE_MESG_PIPE:
345 smb_opipe_close(of);
346 smb_server_dec_pipes(of->f_server);
347 break;
348
349 case SMB_FTYPE_DISK:
350 case SMB_FTYPE_PRINTER:
351 /*
352 * In here we make changes to of->f_pending_attr
353 * while not holding of->f_mutex. This is OK
354 * because we've changed f_state to CLOSING,
355 * so no more threads will take this path.
356 */
357 pa = &of->f_pending_attr;
358 if (mtime_sec != 0) {
359 pa->sa_vattr.va_mtime.tv_sec = mtime_sec;
360 pa->sa_mask |= SMB_AT_MTIME;
361 }
362
363 /*
364 * If we have ever modified data via this handle
365 * (write or truncate) and if the mtime was not
366 * set via this handle, update the mtime again
367 * during the close. Windows expects this.
368 * [ MS-FSA 2.1.5.4 "Update Timestamps" ]
369 */
370 if (of->f_written &&
371 (pa->sa_mask & SMB_AT_MTIME) == 0) {
372 pa->sa_mask |= SMB_AT_MTIME;
373 gethrestime(&now);
374 pa->sa_vattr.va_mtime = now;
375 }
376
377 if (of->f_flags & SMB_OFLAGS_SET_DELETE_ON_CLOSE) {
378 if (smb_tree_has_feature(of->f_tree,
379 SMB_TREE_CATIA)) {
380 flags |= SMB_CATIA;
381 }
382 (void) smb_node_set_delete_on_close(of->f_node,
383 of->f_cr, flags);
384 }
385 smb_fsop_unshrlock(of->f_cr, of->f_node, of->f_uniqid);
386 smb_node_destroy_lock_by_ofile(of->f_node, of);
387
388 if (smb_node_is_file(of->f_node)) {
389 (void) smb_fsop_close(of->f_node, of->f_mode,
390 of->f_cr);
391 smb_oplock_release(of->f_node, of);
392 } else {
393 /*
394 * If there was an odir, close it.
395 */
396 if (of->f_odir != NULL)
397 smb_odir_close(of->f_odir);
398 }
399 if (smb_node_dec_open_ofiles(of->f_node) == 0) {
400 /*
401 * Last close. The f_pending_attr has
402 * only times (atime,ctime,mtime) so
403 * we can borrow it to commit the
404 * n_pending_dosattr from the node.
405 */
406 pa->sa_dosattr =
407 of->f_node->n_pending_dosattr;
408 if (pa->sa_dosattr != 0)
409 pa->sa_mask |= SMB_AT_DOSATTR;
410 /* Let's leave this zero when not in use. */
411 of->f_node->n_allocsz = 0;
412 }
413 if (pa->sa_mask != 0) {
414 /*
415 * Commit any pending attributes from
416 * the ofile we're closing. Note that
417 * we pass NULL as the ofile to setattr
418 * so it will write to the file system
419 * and not keep anything on the ofile.
420 * This clears n_pending_dosattr if
421 * there are no opens, otherwise the
422 * dosattr will be pending again.
423 */
424 (void) smb_node_setattr(NULL, of->f_node,
425 of->f_cr, NULL, pa);
426 }
427
428 /*
429 * Cancel any notify change requests that
430 * may be using this open instance.
431 */
432 if (of->f_node->n_fcn.fcn_count)
433 smb_notify_file_closed(of);
434
435 smb_server_dec_files(of->f_server);
436 break;
437 }
438 atomic_dec_32(&of->f_tree->t_open_files);
439
440 mutex_enter(&of->f_mutex);
441 ASSERT(of->f_refcnt);
442 ASSERT(of->f_state == SMB_OFILE_STATE_CLOSING);
443 of->f_state = SMB_OFILE_STATE_CLOSED;
444 mutex_exit(&of->f_mutex);
445 }
446
447 /*
448 * smb_ofile_close_all
449 *
450 *
451 */
452 void
453 smb_ofile_close_all(
454 smb_tree_t *tree)
455 {
456 smb_ofile_t *of;
457
458 ASSERT(tree);
459 ASSERT(tree->t_magic == SMB_TREE_MAGIC);
460
461 smb_llist_enter(&tree->t_ofile_list, RW_READER);
462 of = smb_llist_head(&tree->t_ofile_list);
463 while (of) {
464 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
465 ASSERT(of->f_tree == tree);
466 of = smb_ofile_close_and_next(of);
467 }
468 smb_llist_exit(&tree->t_ofile_list);
469 }
470
471 /*
472 * smb_ofiles_close_by_pid
473 *
474 *
475 */
476 void
477 smb_ofile_close_all_by_pid(
478 smb_tree_t *tree,
479 uint16_t pid)
480 {
481 smb_ofile_t *of;
482
483 ASSERT(tree);
484 ASSERT(tree->t_magic == SMB_TREE_MAGIC);
485
486 smb_llist_enter(&tree->t_ofile_list, RW_READER);
487 of = smb_llist_head(&tree->t_ofile_list);
488 while (of) {
489 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
490 ASSERT(of->f_tree == tree);
491 if (of->f_opened_by_pid == pid) {
492 of = smb_ofile_close_and_next(of);
493 } else {
494 of = smb_llist_next(&tree->t_ofile_list, of);
495 }
496 }
497 smb_llist_exit(&tree->t_ofile_list);
498 }
499
500 /*
501 * If the enumeration request is for ofile data, handle it here.
502 * Otherwise, return.
503 *
504 * This function should be called with a hold on the ofile.
505 */
506 int
507 smb_ofile_enum(smb_ofile_t *of, smb_svcenum_t *svcenum)
508 {
509 uint8_t *pb;
510 uint_t nbytes;
511 int rc;
512
513 ASSERT(of);
514 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
515 ASSERT(of->f_refcnt);
516
517 if (svcenum->se_type != SMB_SVCENUM_TYPE_FILE)
524
525 if (svcenum->se_nitems >= svcenum->se_nlimit) {
526 svcenum->se_nitems = svcenum->se_nlimit;
527 return (0);
528 }
529
530 pb = &svcenum->se_buf[svcenum->se_bused];
531
532 rc = smb_ofile_netinfo_encode(of, pb, svcenum->se_bavail,
533 &nbytes);
534 if (rc == 0) {
535 svcenum->se_bavail -= nbytes;
536 svcenum->se_bused += nbytes;
537 svcenum->se_nitems++;
538 }
539
540 return (rc);
541 }
542
543 /*
544 * Take a reference on an open file.
545 */
546 boolean_t
547 smb_ofile_hold(smb_ofile_t *of)
548 {
549 ASSERT(of);
550 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
551
552 mutex_enter(&of->f_mutex);
553
554 if (of->f_state != SMB_OFILE_STATE_OPEN) {
555 mutex_exit(&of->f_mutex);
556 return (B_FALSE);
557 }
558 of->f_refcnt++;
559
560 mutex_exit(&of->f_mutex);
561 return (B_TRUE);
562 }
563
564 /*
565 * Release a reference on a file. If the reference count falls to
566 * zero and the file has been closed, post the object for deletion.
567 * Object deletion is deferred to avoid modifying a list while an
568 * iteration may be in progress.
569 */
570 void
571 smb_ofile_release(smb_ofile_t *of)
572 {
573 SMB_OFILE_VALID(of);
574
575 mutex_enter(&of->f_mutex);
576 ASSERT(of->f_refcnt);
577 of->f_refcnt--;
578 switch (of->f_state) {
579 case SMB_OFILE_STATE_OPEN:
580 case SMB_OFILE_STATE_CLOSING:
581 break;
582
583 case SMB_OFILE_STATE_CLOSED:
584 if (of->f_refcnt == 0)
585 smb_tree_post_ofile(of->f_tree, of);
586 break;
587
588 default:
589 ASSERT(0);
590 break;
591 }
592 mutex_exit(&of->f_mutex);
593 }
594
595 /*
596 * smb_ofile_request_complete
597 *
598 * During oplock acquisition, all other oplock requests on the node
599 * are blocked until the acquire request completes and the response
600 * is on the wire.
601 * Call smb_oplock_broadcast to notify the node that the request
602 * has completed.
603 *
604 * THIS MECHANISM RELIES ON THE FACT THAT THE OFILE IS NOT REMOVED
605 * FROM THE SR UNTIL REQUEST COMPLETION (when the sr is destroyed)
606 */
607 void
608 smb_ofile_request_complete(smb_ofile_t *of)
609 {
610 SMB_OFILE_VALID(of);
611
612 switch (of->f_ftype) {
613 case SMB_FTYPE_DISK:
614 ASSERT(of->f_node);
615 smb_oplock_broadcast(of->f_node);
616 break;
617 case SMB_FTYPE_MESG_PIPE:
618 break;
619 default:
620 break;
621 }
622 }
623
624 /*
625 * smb_ofile_lookup_by_fid
626 *
627 * Find the open file whose fid matches the one specified in the request.
628 * If we can't find the fid or the shares (trees) don't match, we have a
629 * bad fid.
630 */
631 smb_ofile_t *
632 smb_ofile_lookup_by_fid(
633 smb_request_t *sr,
634 uint16_t fid)
635 {
636 smb_tree_t *tree = sr->tid_tree;
637 smb_llist_t *of_list;
638 smb_ofile_t *of;
639
640 ASSERT(tree->t_magic == SMB_TREE_MAGIC);
645 of = smb_llist_head(of_list);
646 while (of) {
647 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
648 ASSERT(of->f_tree == tree);
649 if (of->f_fid == fid)
650 break;
651 of = smb_llist_next(of_list, of);
652 }
653 if (of == NULL)
654 goto out;
655
656 /*
657 * Only allow use of a given FID with the same UID that
658 * was used to open it. MS-CIFS 3.3.5.14
659 */
660 if (of->f_user != sr->uid_user) {
661 of = NULL;
662 goto out;
663 }
664
665 mutex_enter(&of->f_mutex);
666 if (of->f_state != SMB_OFILE_STATE_OPEN) {
667 mutex_exit(&of->f_mutex);
668 of = NULL;
669 goto out;
670 }
671 of->f_refcnt++;
672 mutex_exit(&of->f_mutex);
673
674 out:
675 smb_llist_exit(of_list);
676 return (of);
677 }
678
679 /*
680 * smb_ofile_lookup_by_uniqid
681 *
682 * Find the open file whose uniqid matches the one specified in the request.
683 */
684 smb_ofile_t *
695
696 while (of) {
697 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
698 ASSERT(of->f_tree == tree);
699
700 if (of->f_uniqid == uniqid) {
701 if (smb_ofile_hold(of)) {
702 smb_llist_exit(of_list);
703 return (of);
704 }
705 }
706
707 of = smb_llist_next(of_list, of);
708 }
709
710 smb_llist_exit(of_list);
711 return (NULL);
712 }
713
714 /*
715 * Disallow NetFileClose on certain ofiles to avoid side-effects.
716 * Closing a tree root is not allowed: use NetSessionDel or NetShareDel.
717 * Closing SRVSVC connections is not allowed because this NetFileClose
718 * request may depend on this ofile.
719 */
720 boolean_t
721 smb_ofile_disallow_fclose(smb_ofile_t *of)
722 {
723 ASSERT(of);
724 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
725 ASSERT(of->f_refcnt);
726
727 switch (of->f_ftype) {
728 case SMB_FTYPE_DISK:
729 ASSERT(of->f_tree);
730 return (of->f_node == of->f_tree->t_snode);
731
732 case SMB_FTYPE_MESG_PIPE:
733 ASSERT(of->f_pipe);
734 if (smb_strcasecmp(of->f_pipe->p_name, "SRVSVC", 0) == 0)
867 {
868 boolean_t rc;
869
870 SMB_OFILE_VALID(of);
871
872 mutex_enter(&of->f_mutex);
873 rc = smb_ofile_is_open_locked(of);
874 mutex_exit(&of->f_mutex);
875 return (rc);
876 }
877
878 /* *************************** Static Functions ***************************** */
879
880 /*
881 * Determine whether or not an ofile is open.
882 * This function must be called with the mutex held.
883 */
884 static boolean_t
885 smb_ofile_is_open_locked(smb_ofile_t *of)
886 {
887 switch (of->f_state) {
888 case SMB_OFILE_STATE_OPEN:
889 return (B_TRUE);
890
891 case SMB_OFILE_STATE_CLOSING:
892 case SMB_OFILE_STATE_CLOSED:
893 return (B_FALSE);
894
895 default:
896 ASSERT(0);
897 return (B_FALSE);
898 }
899 }
900
901 /*
902 * This function closes the file passed in (if appropriate) and returns the
903 * next open file in the list of open files of the tree of the open file passed
904 * in. It requires that the list of open files of the tree be entered in
905 * RW_READER mode before being called.
906 */
907 static smb_ofile_t *
908 smb_ofile_close_and_next(smb_ofile_t *of)
909 {
910 smb_ofile_t *next_of;
911 smb_tree_t *tree;
912
913 ASSERT(of);
914 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
915
916 mutex_enter(&of->f_mutex);
917 switch (of->f_state) {
918 case SMB_OFILE_STATE_OPEN:
919 /* The file is still open. */
920 of->f_refcnt++;
921 ASSERT(of->f_refcnt);
922 tree = of->f_tree;
923 mutex_exit(&of->f_mutex);
924 smb_llist_exit(&of->f_tree->t_ofile_list);
925 smb_ofile_close(of, 0);
926 smb_ofile_release(of);
927 smb_llist_enter(&tree->t_ofile_list, RW_READER);
928 next_of = smb_llist_head(&tree->t_ofile_list);
929 break;
930 case SMB_OFILE_STATE_CLOSING:
931 case SMB_OFILE_STATE_CLOSED:
932 /*
933 * The ofile exists but is closed or
934 * in the process being closed.
935 */
936 mutex_exit(&of->f_mutex);
937 next_of = smb_llist_next(&of->f_tree->t_ofile_list, of);
938 break;
939 default:
940 ASSERT(0);
941 mutex_exit(&of->f_mutex);
942 next_of = smb_llist_next(&of->f_tree->t_ofile_list, of);
943 break;
944 }
945 return (next_of);
946 }
947
948 /*
949 * Delete an ofile.
950 *
951 * Remove the ofile from the tree list before freeing resources
952 * associated with the ofile.
953 */
954 void
955 smb_ofile_delete(void *arg)
956 {
957 smb_tree_t *tree;
958 smb_ofile_t *of = (smb_ofile_t *)arg;
959
960 SMB_OFILE_VALID(of);
961 ASSERT(of->f_refcnt == 0);
962 ASSERT(of->f_state == SMB_OFILE_STATE_CLOSED);
963 ASSERT(!SMB_OFILE_OPLOCK_GRANTED(of));
964
965 tree = of->f_tree;
966 smb_llist_enter(&tree->t_ofile_list, RW_WRITER);
967 smb_llist_remove(&tree->t_ofile_list, of);
968 smb_idpool_free(&tree->t_fid_pool, of->f_fid);
969 atomic_dec_32(&tree->t_session->s_file_cnt);
970 smb_llist_exit(&tree->t_ofile_list);
971
972 mutex_enter(&of->f_mutex);
973 mutex_exit(&of->f_mutex);
974
975 switch (of->f_ftype) {
976 case SMB_FTYPE_BYTE_PIPE:
977 case SMB_FTYPE_MESG_PIPE:
978 smb_opipe_dealloc(of->f_pipe);
979 of->f_pipe = NULL;
980 break;
981 case SMB_FTYPE_DISK:
982 if (of->f_odir != NULL)
983 smb_odir_release(of->f_odir);
984 smb_node_rem_ofile(of->f_node, of);
985 smb_node_release(of->f_node);
986 break;
987 default:
988 ASSERT(!"f_ftype");
989 break;
990 }
991
992 of->f_magic = (uint32_t)~SMB_OFILE_MAGIC;
993 mutex_destroy(&of->f_mutex);
994 crfree(of->f_cr);
995 smb_user_release(of->f_user);
996 kmem_cache_free(smb_cache_ofile, of);
997 }
998
999 /*
1000 * smb_ofile_access
1001 *
1002 * This function will check to see if the access requested is granted.
1003 * Returns NT status codes.
1004 */
1005 uint32_t
1006 smb_ofile_access(smb_ofile_t *of, cred_t *cr, uint32_t access)
1007 {
1008
1009 if ((of == NULL) || (cr == zone_kcred()))
1010 return (NT_STATUS_SUCCESS);
1011
1012 /*
1013 * If the request is for something
1014 * I don't grant it is an error
1015 */
1031 * Returns: B_TRUE - share access non-zero
1032 * B_FALSE - share access NONE
1033 */
1034 boolean_t
1035 smb_ofile_share_check(smb_ofile_t *of)
1036 {
1037 return (!SMB_DENY_ALL(of->f_share_access));
1038 }
1039
1040 /*
1041 * check file sharing rules for current open request
1042 * against existing open instances of the same file
1043 *
1044 * Returns NT_STATUS_SHARING_VIOLATION if there is any
1045 * sharing conflict, otherwise returns NT_STATUS_SUCCESS.
1046 */
1047 uint32_t
1048 smb_ofile_open_check(smb_ofile_t *of, uint32_t desired_access,
1049 uint32_t share_access)
1050 {
1051 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
1052
1053 mutex_enter(&of->f_mutex);
1054
1055 if (of->f_state != SMB_OFILE_STATE_OPEN) {
1056 mutex_exit(&of->f_mutex);
1057 return (NT_STATUS_INVALID_HANDLE);
1058 }
1059
1060 /* if it's just meta data */
1061 if ((of->f_granted_access & FILE_DATA_ALL) == 0) {
1062 mutex_exit(&of->f_mutex);
1063 return (NT_STATUS_SUCCESS);
1064 }
1065
1066 /*
1067 * Check requested share access against the
1068 * open granted (desired) access
1069 */
1070 if (SMB_DENY_DELETE(share_access) && (of->f_granted_access & DELETE)) {
1071 mutex_exit(&of->f_mutex);
1072 return (NT_STATUS_SHARING_VIOLATION);
1073 }
1074
1075 if (SMB_DENY_READ(share_access) &&
1076 (of->f_granted_access & (FILE_READ_DATA | FILE_EXECUTE))) {
1077 mutex_exit(&of->f_mutex);
1078 return (NT_STATUS_SHARING_VIOLATION);
1079 }
1080
1081 if (SMB_DENY_WRITE(share_access) &&
1082 (of->f_granted_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) {
1083 mutex_exit(&of->f_mutex);
1084 return (NT_STATUS_SHARING_VIOLATION);
1085 }
1086
1087 /* check requested desired access against the open share access */
1088 if (SMB_DENY_DELETE(of->f_share_access) && (desired_access & DELETE)) {
1089 mutex_exit(&of->f_mutex);
1090 return (NT_STATUS_SHARING_VIOLATION);
1091 }
1092
1093 if (SMB_DENY_READ(of->f_share_access) &&
1094 (desired_access & (FILE_READ_DATA | FILE_EXECUTE))) {
1095 mutex_exit(&of->f_mutex);
1096 return (NT_STATUS_SHARING_VIOLATION);
1097 }
1098
1099 if (SMB_DENY_WRITE(of->f_share_access) &&
1100 (desired_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) {
1101 mutex_exit(&of->f_mutex);
1102 return (NT_STATUS_SHARING_VIOLATION);
1103 }
1104
1105 mutex_exit(&of->f_mutex);
1106 return (NT_STATUS_SUCCESS);
1107 }
1108
1109 /*
1110 * smb_ofile_rename_check
1111 *
1112 * An open file can be renamed if
1113 *
1114 * 1. isn't opened for data writing or deleting
1115 *
1116 * 2. Opened with "Deny Delete" share mode
1117 * But not opened for data reading or executing
1118 * (opened for accessing meta data)
1119 */
1120
1121 uint32_t
1122 smb_ofile_rename_check(smb_ofile_t *of)
1123 {
1124 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
1125
1126 mutex_enter(&of->f_mutex);
1127
1128 if (of->f_state != SMB_OFILE_STATE_OPEN) {
1129 mutex_exit(&of->f_mutex);
1130 return (NT_STATUS_INVALID_HANDLE);
1131 }
1132
1133 if (of->f_granted_access &
1134 (FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE)) {
1135 mutex_exit(&of->f_mutex);
1136 return (NT_STATUS_SHARING_VIOLATION);
1137 }
1138
1139 if ((of->f_share_access & FILE_SHARE_DELETE) == 0) {
1140 if (of->f_granted_access &
1141 (FILE_READ_DATA | FILE_EXECUTE)) {
1142 mutex_exit(&of->f_mutex);
1143 return (NT_STATUS_SHARING_VIOLATION);
1144 }
1145 }
1146
1147 mutex_exit(&of->f_mutex);
1148 return (NT_STATUS_SUCCESS);
1149 }
1150
1151 /*
1152 * smb_ofile_delete_check
1153 *
1154 * An open file can be deleted only if opened for
1155 * accessing meta data. Share modes aren't important
1156 * in this case.
1157 *
1158 * NOTE: there is another mechanism for deleting an
1159 * open file that NT clients usually use.
1160 * That's setting "Delete on close" flag for an open
1161 * file. In this way the file will be deleted after
1162 * last close. This flag can be set by SmbTrans2SetFileInfo
1163 * with FILE_DISPOSITION_INFO information level.
1164 * For setting this flag, the file should be opened by
1165 * DELETE access in the FID that is passed in the Trans2
1166 * request.
1167 */
1168
1169 uint32_t
1170 smb_ofile_delete_check(smb_ofile_t *of)
1171 {
1172 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
1173
1174 mutex_enter(&of->f_mutex);
1175
1176 if (of->f_state != SMB_OFILE_STATE_OPEN) {
1177 mutex_exit(&of->f_mutex);
1178 return (NT_STATUS_INVALID_HANDLE);
1179 }
1180
1181 if (of->f_granted_access &
1182 (FILE_READ_DATA | FILE_WRITE_DATA |
1183 FILE_APPEND_DATA | FILE_EXECUTE | DELETE)) {
1184 mutex_exit(&of->f_mutex);
1185 return (NT_STATUS_SHARING_VIOLATION);
1186 }
1187
1188 mutex_exit(&of->f_mutex);
1189 return (NT_STATUS_SUCCESS);
1190 }
1191
1192 cred_t *
1193 smb_ofile_getcred(smb_ofile_t *of)
1194 {
1195 return (of->f_cr);
1196 }
1197
1198 /*
1199 * smb_ofile_set_delete_on_close
1200 *
1201 * Set the DeleteOnClose flag on the smb file. When the file is closed,
1202 * the flag will be transferred to the smb node, which will commit the
1203 * delete operation and inhibit subsequent open requests.
1204 *
1205 * When DeleteOnClose is set on an smb_node, the common open code will
1206 * reject subsequent open requests for the file. Observation of Windows
1207 * 2000 indicates that subsequent opens should be allowed (assuming
1208 * there would be no sharing violation) until the file is closed using
1209 * the fid on which the DeleteOnClose was requested.
1210 */
1211 void
1212 smb_ofile_set_delete_on_close(smb_ofile_t *of)
1213 {
1214 mutex_enter(&of->f_mutex);
1215 of->f_flags |= SMB_OFLAGS_SET_DELETE_ON_CLOSE;
1216 mutex_exit(&of->f_mutex);
1217 }
1218
1219 /*
1220 * Encode open file information into a buffer; needed in user space to
1221 * support RPC requests.
1222 */
1223 static int
1224 smb_ofile_netinfo_encode(smb_ofile_t *of, uint8_t *buf, size_t buflen,
1225 uint32_t *nbytes)
1226 {
1227 smb_netfileinfo_t fi;
1228 int rc;
1229
1230 rc = smb_ofile_netinfo_init(of, &fi);
1231 if (rc == 0) {
1232 rc = smb_netfileinfo_encode(&fi, buf, buflen, nbytes);
1233 smb_ofile_netinfo_fini(&fi);
|
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 2019 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 * | |
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 * | | | T5
77 * | | +---------------------------+
78 * | | | SMB_OFILE_STATE_RECONNECT |
79 * | | +---------------------------+
80 * | | ^
81 * | v |
82 * | +---------------+ |
83 * | | STATE_SAVE_DH | |
84 * | | STATE_SAVING | |
85 * | +---------------+ |
86 * | | | T4
87 * | T1 | T3 +--------------------------+
88 * | +------>| SMB_OFILE_STATE_ORPHANED |
89 * v +--------------------------+
90 * +-------------------------+ | |
91 * | SMB_OFILE_STATE_CLOSING |<--+ T6 | T7
92 * +-------------------------+ |
93 * | ^ v
94 * | T2 | T8 +-------------------------+
95 * | +-------| SMB_OFILE_STATE_EXPIRED |
96 * v +-------------------------+
97 * +-------------------------+
98 * | SMB_OFILE_STATE_CLOSED |----------> Deletion/Free
99 * +-------------------------+ T9
100 *
101 * SMB_OFILE_STATE_OPEN
102 *
103 * While in this state:
104 * - The ofile is queued in the list of ofiles of its tree.
105 * - References will be given out if the ofile is looked up.
106 *
107 * SMB_OFILE_STATE_SAVE_DH
108 *
109 * Similar to state _CLOSING, but instead of deleting the ofile,
110 * it leaves the ofile in state _ORPHANED (for later reclaim).
111 * Will move to _SAVING after last ref, then _ORPHANED.
112 *
113 * While in this state:
114 * - The ofile has been marked for preservation during a
115 * walk of the tree ofile list to close multiple files.
116 * - References will not be given out if the ofile is looked up,
117 * except for oplock break processing.
118 * - Still affects Sharing Violation rules
119 *
120 * SMB_OFILE_STATE_SAVING
121 *
122 * Transient state used to keep oplock break processing out
123 * while the ofile moves to state _ORPHANED.
124 *
125 * While in this state:
126 * - References will not be given out if the ofile is looked up,
127 * except for oplock break processing.
128 * - Still affects Sharing Violation rules
129 *
130 * SMB_OFILE_STATE_CLOSING
131 *
132 * Close has been requested. Stay in this state until the last
133 * ref. is gone, then move to state _CLOSED
134 *
135 * While in this state:
136 * - The ofile is queued in the list of ofiles of its tree.
137 * - References will not be given out if the ofile is looked up.
138 * - The file is closed and the locks held are being released.
139 * - The resources associated with the ofile remain.
140 *
141 * SMB_OFILE_STATE_CLOSED
142 *
143 * While in this state:
144 * - The ofile is queued in the list of ofiles of its tree.
145 * - References will not be given out if the ofile is looked up.
146 * - The resources associated with the ofile remain.
147 *
148 * SMB_OFILE_STATE_ORPHANED
149 *
150 * While in this state:
151 * - The ofile is queued in the list of ofiles of its tree.
152 * - Can be reclaimed by the original owner
153 * - References will not be given out if the ofile is looked up.
154 * - All the tree, user, and session "up" pointers are NULL!
155 * - Will eventually be "expired" if not reclaimed
156 * - Can be closed if its oplock is broken
157 * - Still affects Sharing Violation rules
158 *
159 * SMB_OFILE_STATE_EXPIRED
160 *
161 * While in this state:
162 * - The ofile is queued in the list of ofiles of its tree.
163 * - References will not be given out if the ofile is looked up.
164 * - The ofile has not been reclaimed and will soon be closed,
165 * due to, for example, the durable handle timer expiring, or its
166 * oplock being broken.
167 * - Cannot be reclaimed at this point
168 *
169 * SMB_OFILE_STATE_RECONNECT
170 *
171 * Transient state used to keep oplock break processing out
172 * while the ofile moves from state _ORPHANED to _OPEN.
173 *
174 * While in this state:
175 * - The ofile is being reclaimed; do not touch it.
176 * - References will not be given out if the ofile is looked up.
177 * - Still affects Sharing Violation rules
178 * - see smb2_dh_reconnect() for which members need to be avoided
179 *
180 * Transition T0
181 *
182 * This transition occurs in smb_ofile_open(). A new ofile is created and
183 * added to the list of ofiles of a tree.
184 *
185 * Transition T1
186 *
187 * This transition occurs in smb_ofile_close(). Note that this only happens
188 * when we determine that an ofile should be closed in spite of its durable
189 * handle properties.
190 *
191 * Transition T2
192 *
193 * This transition occurs in smb_ofile_release(). The resources associated
194 * with the ofile are freed as well as the ofile structure. For the
195 * transition to occur, the ofile must be in the SMB_OFILE_STATE_CLOSED
196 * state and the reference count be zero.
197 *
198 * Transition T3
199 *
200 * This transition occurs in smb_ofile_orphan_dh(). It happens during an
201 * smb2 logoff, or during a session disconnect when certain conditions are
202 * met. The ofile and structures above it will be kept around until the ofile
203 * either gets reclaimed, expires after f_timeout_offset nanoseconds, or its
204 * oplock is broken.
205 *
206 * Transition T4
207 *
208 * This transition occurs in smb2_dh_reconnect(). An smb2 create request
209 * with a DURABLE_HANDLE_RECONNECT(_V2) create context has been
210 * recieved from the original owner. If leases are supported or it's
211 * RECONNECT_V2, reconnect is subject to additional conditions. The ofile
212 * will be unwired from the old, disconnected session, tree, and user,
213 * and wired up to its new context.
214 *
215 * Transition T5
216 *
217 * This transition occurs in smb2_dh_reconnect(). The ofile has been
218 * successfully reclaimed.
219 *
220 * Transition T6
221 *
222 * This transition occurs in smb_ofile_close(). The ofile has been orphaned
223 * while some thread was blocked, and that thread closes the ofile. Can only
224 * happen when the ofile is orphaned due to an SMB2 LOGOFF request.
225 *
226 * Transition T7
227 *
228 * This transition occurs in smb_session_durable_timers() and
229 * smb_oplock_send_brk(). The ofile will soon be closed.
230 * In the former case, f_timeout_offset nanoseconds have passed since
231 * the ofile was orphaned. In the latter, an oplock break occured
232 * on the ofile while it was orphaned.
233 *
234 * Transition T8
235 *
236 * This transition occurs in smb_ofile_close().
237 *
238 * Transition T9
239 *
240 * This transition occurs in smb_ofile_delete().
241 *
242 * Comments
243 * --------
244 *
245 * The state machine of the ofile structures is controlled by 3 elements:
246 * - The list of ofiles of the tree it belongs to.
247 * - The mutex embedded in the structure itself.
248 * - The reference count.
249 *
250 * There's a mutex embedded in the ofile structure used to protect its fields
251 * and there's a lock embedded in the list of ofiles of a tree. To
252 * increment or to decrement the reference count the mutex must be entered.
253 * To insert the ofile into the list of ofiles of the tree and to remove
254 * the ofile from it, the lock must be entered in RW_WRITER mode.
255 *
256 * Rules of access to a ofile structure:
257 *
258 * 1) In order to avoid deadlocks, when both (mutex and lock of the ofile
259 * list) have to be entered, the lock must be entered first. Additionally,
260 * f_mutex must not be held when removing the ofile from sv_persistid_ht.
261 *
262 * 2) All actions applied to an ofile require a reference count.
263 *
264 * 3) There are 2 ways of getting a reference count. One is when the ofile
265 * is opened. The other one when the ofile is looked up. This translates
266 * into 2 functions: smb_ofile_open() and smb_ofile_lookup_by_fid().
267 *
268 * It should be noted that the reference count of an ofile registers the
269 * number of references to the ofile in other structures (such as an smb
270 * request). The reference count is not incremented in these 2 instances:
271 *
272 * 1) The ofile is open. An ofile is anchored by its state. If there's
273 * no activity involving an ofile currently open, the reference count
274 * of that ofile is zero.
275 *
276 * 2) The ofile is queued in the list of ofiles of its tree. The fact of
277 * being queued in that list is NOT registered by incrementing the
278 * reference count.
279 */
280 #include <smbsrv/smb2_kproto.h>
281 #include <smbsrv/smb_fsops.h>
282 #include <sys/time.h>
283 #include <sys/random.h>
284
285 static boolean_t smb_ofile_is_open_locked(smb_ofile_t *);
286 static void smb_ofile_delete(void *arg);
287 static void smb_ofile_save_dh(void *arg);
288
289 static int smb_ofile_netinfo_encode(smb_ofile_t *, uint8_t *, size_t,
290 uint32_t *);
291 static int smb_ofile_netinfo_init(smb_ofile_t *, smb_netfileinfo_t *);
292 static void smb_ofile_netinfo_fini(smb_netfileinfo_t *);
293
294 /*
295 * The uniq_fid is a CIFS-server-wide unique identifier for an ofile
296 * which is used to uniquely identify open instances for the
297 * VFS share reservation and POSIX locks.
298 */
299 static volatile uint32_t smb_fids = 0;
300 #define SMB_UNIQ_FID() atomic_inc_32_nv(&smb_fids)
301
302 /*
303 * smb_ofile_alloc
304 * Allocate an ofile and fill in it's "up" pointers, but
305 * do NOT link it into the tree's list of ofiles or the
306 * node's list of ofiles. An ofile in this state is a
307 * "proposed" open passed to the oplock break code.
308 *
309 * If we don't get as far as smb_ofile_open with this OF,
310 * call smb_ofile_free() to free this object.
311 *
312 * Note: The following sr members may be null during
313 * persistent handle import: session, uid_usr, tid_tree
314 */
315 smb_ofile_t *
316 smb_ofile_alloc(
317 smb_request_t *sr,
318 smb_arg_open_t *op,
319 smb_node_t *node, /* optional (may be NULL) */
320 uint16_t ftype,
321 uint16_t tree_fid)
322 {
323 smb_user_t *user = sr->uid_user; /* optional */
324 smb_tree_t *tree = sr->tid_tree; /* optional */
325 smb_ofile_t *of;
326
327 of = kmem_cache_alloc(smb_cache_ofile, KM_SLEEP);
328 bzero(of, sizeof (smb_ofile_t));
329 of->f_magic = SMB_OFILE_MAGIC;
330
331 mutex_init(&of->f_mutex, NULL, MUTEX_DEFAULT, NULL);
332 list_create(&of->f_notify.nc_waiters, sizeof (smb_request_t),
333 offsetof(smb_request_t, sr_waiters));
334 mutex_init(&of->dh_nvlock, NULL, MUTEX_DEFAULT, NULL);
335
336 of->f_state = SMB_OFILE_STATE_ALLOC;
337 of->f_refcnt = 1;
338 of->f_ftype = ftype;
339 of->f_fid = tree_fid;
340 /* of->f_persistid see smb2_create */
341 of->f_uniqid = SMB_UNIQ_FID();
342 of->f_opened_by_pid = sr->smb_pid;
343 of->f_granted_access = op->desired_access;
344 of->f_share_access = op->share_access;
345 of->f_create_options = op->create_options;
346 if (user != NULL) {
347 if ((op->create_options & FILE_OPEN_FOR_BACKUP_INTENT) != 0)
348 of->f_cr = smb_user_getprivcred(user);
349 else
350 of->f_cr = user->u_cred;
351 crhold(of->f_cr);
352 }
353 of->f_server = sr->sr_server;
354 of->f_session = sr->session; /* may be NULL */
355
356 (void) memset(of->f_lock_seq, -1, SMB_OFILE_LSEQ_MAX);
357
358 of->f_mode = smb_fsop_amask_to_omode(of->f_granted_access);
359 if ((of->f_granted_access & FILE_DATA_ALL) == FILE_EXECUTE)
360 of->f_flags |= SMB_OFLAGS_EXECONLY;
361
362 /*
363 * In case a lease is requested, copy the lease keys now so
364 * any oplock breaks during open don't break those on our
365 * other handles that might have the same lease.
366 */
367 bcopy(op->lease_key, of->TargetOplockKey, SMB_LEASE_KEY_SZ);
368 bcopy(op->parent_lease_key, of->ParentOplockKey, SMB_LEASE_KEY_SZ);
369
370 /*
371 * grab a ref for of->f_user and of->f_tree
372 * We know the user and tree must be "live" because
373 * this SR holds references to them. The node ref. is
374 * held by our caller, until smb_ofile_open puts this
375 * ofile on the node ofile list with smb_node_add_ofile.
376 */
377 if (user != NULL) {
378 smb_user_hold_internal(user);
379 of->f_user = user;
380 }
381 if (tree != NULL) {
382 smb_tree_hold_internal(tree);
383 of->f_tree = tree;
384 }
385 of->f_node = node; /* may be NULL */
386
387 return (of);
388 }
389
390 /*
391 * smb_ofile_open
392 *
393 * Complete an open on an ofile that was previously allocated by
394 * smb_ofile_alloc, by putting it on the tree ofile list and
395 * (if it's a file) the node ofile list.
396 */
397 void
398 smb_ofile_open(
399 smb_request_t *sr,
400 smb_arg_open_t *op,
401 smb_ofile_t *of)
402 {
403 smb_tree_t *tree = sr->tid_tree;
404 smb_node_t *node = of->f_node;
405
406 ASSERT(of->f_state == SMB_OFILE_STATE_ALLOC);
407 of->f_state = SMB_OFILE_STATE_OPEN;
408
409 switch (of->f_ftype) {
410 case SMB_FTYPE_BYTE_PIPE:
411 case SMB_FTYPE_MESG_PIPE:
412 /* See smb_opipe_open. */
413 of->f_pipe = op->pipe;
414 smb_server_inc_pipes(of->f_server);
415 break;
416 case SMB_FTYPE_DISK:
417 case SMB_FTYPE_PRINTER:
418 /* Regular file, not a pipe */
419 ASSERT(node != NULL);
420
421 smb_node_inc_open_ofiles(node);
422 smb_node_add_ofile(node, of);
423 smb_node_ref(node);
424 smb_server_inc_files(of->f_server);
425 break;
426 default:
427 ASSERT(0);
428 }
429 smb_llist_enter(&tree->t_ofile_list, RW_WRITER);
430 smb_llist_insert_tail(&tree->t_ofile_list, of);
431 smb_llist_exit(&tree->t_ofile_list);
432 atomic_inc_32(&tree->t_open_files);
433 atomic_inc_32(&of->f_session->s_file_cnt);
434
435 }
436
437 /*
438 * smb_ofile_close
439 *
440 * Incoming states: (where from)
441 * SMB_OFILE_STATE_OPEN protocol close, smb_ofile_drop
442 * SMB_OFILE_STATE_EXPIRED called via smb2_dh_expire
443 * SMB_OFILE_STATE_ORPHANED smb_server_cleanup_sessions()
444 */
445 void
446 smb_ofile_close(smb_ofile_t *of, int32_t mtime_sec)
447 {
448 smb_attr_t *pa;
449 timestruc_t now;
450
451 SMB_OFILE_VALID(of);
452
453 mutex_enter(&of->f_mutex);
454 ASSERT(of->f_refcnt);
455
456 switch (of->f_state) {
457 case SMB_OFILE_STATE_OPEN:
458 case SMB_OFILE_STATE_ORPHANED:
459 case SMB_OFILE_STATE_EXPIRED:
460 of->f_state = SMB_OFILE_STATE_CLOSING;
461 mutex_exit(&of->f_mutex);
462 break;
463 default:
464 mutex_exit(&of->f_mutex);
465 return;
466 }
467
468 /*
469 * Only one thread here (the one that that set f_state closing)
470 */
471 switch (of->f_ftype) {
472 case SMB_FTYPE_BYTE_PIPE:
473 case SMB_FTYPE_MESG_PIPE:
474 smb_opipe_close(of);
475 smb_server_dec_pipes(of->f_server);
476 break;
477
478 case SMB_FTYPE_DISK:
479 if (of->dh_persist)
480 smb2_dh_close_persistent(of);
481 if (of->f_persistid != 0)
482 smb_ofile_del_persistid(of);
483 if (of->f_lease != NULL)
484 smb2_lease_ofile_close(of);
485 smb_oplock_break_CLOSE(of->f_node, of);
486 /* FALLTHROUGH */
487
488 case SMB_FTYPE_PRINTER: /* or FTYPE_DISK */
489 /*
490 * In here we make changes to of->f_pending_attr
491 * while not holding of->f_mutex. This is OK
492 * because we've changed f_state to CLOSING,
493 * so no more threads will take this path.
494 */
495 pa = &of->f_pending_attr;
496 if (mtime_sec != 0) {
497 pa->sa_vattr.va_mtime.tv_sec = mtime_sec;
498 pa->sa_mask |= SMB_AT_MTIME;
499 }
500
501 /*
502 * If we have ever modified data via this handle
503 * (write or truncate) and if the mtime was not
504 * set via this handle, update the mtime again
505 * during the close. Windows expects this.
506 * [ MS-FSA 2.1.5.4 "Update Timestamps" ]
507 */
508 if (of->f_written &&
509 (pa->sa_mask & SMB_AT_MTIME) == 0) {
510 pa->sa_mask |= SMB_AT_MTIME;
511 gethrestime(&now);
512 pa->sa_vattr.va_mtime = now;
513 }
514
515 if (of->f_flags & SMB_OFLAGS_SET_DELETE_ON_CLOSE) {
516 /* We delete using the on-disk name. */
517 uint32_t flags = SMB_CASE_SENSITIVE;
518 (void) smb_node_set_delete_on_close(of->f_node,
519 of->f_cr, flags);
520 }
521 smb_fsop_unshrlock(of->f_cr, of->f_node, of->f_uniqid);
522 smb_node_destroy_lock_by_ofile(of->f_node, of);
523
524 if (smb_node_is_file(of->f_node)) {
525 (void) smb_fsop_close(of->f_node, of->f_mode,
526 of->f_cr);
527 } else {
528 /*
529 * If there was an odir, close it.
530 */
531 if (of->f_odir != NULL)
532 smb_odir_close(of->f_odir);
533 /*
534 * Cancel any notify change requests that
535 * might be watching this open file (dir),
536 * and unsubscribe it from node events.
537 *
538 * Can't hold f_mutex when calling smb_notify_ofile.
539 * Don't really need it when unsubscribing, but
540 * harmless, and consistent with subscribing.
541 */
542 if (of->f_notify.nc_subscribed)
543 smb_notify_ofile(of,
544 FILE_ACTION_HANDLE_CLOSED, NULL);
545 mutex_enter(&of->f_mutex);
546 if (of->f_notify.nc_subscribed) {
547 of->f_notify.nc_subscribed = B_FALSE;
548 smb_node_fcn_unsubscribe(of->f_node);
549 of->f_notify.nc_filter = 0;
550 }
551 mutex_exit(&of->f_mutex);
552 }
553 if (smb_node_dec_open_ofiles(of->f_node) == 0) {
554 /*
555 * Last close. If we're not deleting
556 * the file, apply any pending attrs.
557 * Leave allocsz zero when no open files,
558 * just to avoid confusion, because it's
559 * only updated when there are opens.
560 * XXX: Just do this on _every_ close.
561 */
562 mutex_enter(&of->f_node->n_mutex);
563 if (of->f_node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
564 smb_node_delete_on_close(of->f_node);
565 pa->sa_mask = 0;
566 }
567 of->f_node->n_allocsz = 0;
568 mutex_exit(&of->f_node->n_mutex);
569 }
570 if (pa->sa_mask != 0) {
571 /*
572 * Commit any pending attributes from
573 * the ofile we're closing. Note that
574 * we pass NULL as the ofile to setattr
575 * so it will write to the file system
576 * and not keep anything on the ofile.
577 */
578 (void) smb_node_setattr(NULL, of->f_node,
579 of->f_cr, NULL, pa);
580 }
581
582 smb_server_dec_files(of->f_server);
583 break;
584 }
585
586 /*
587 * Keep f_state == SMB_OFILE_STATE_CLOSING
588 * until the last ref. is dropped, in
589 * smb_ofile_release()
590 */
591 }
592
593 /*
594 * "Destructor" function for smb_ofile_close_all, and
595 * smb_ofile_close_all_by_pid, called after the llist lock
596 * for tree list has been exited. Our job is to either
597 * close this ofile, or (if durable) set state _SAVE_DH.
598 *
599 * The next interesting thing happens when the last ref.
600 * on this ofile calls smb_ofile_release(), where we
601 * eihter delete the ofile, or (if durable) leave it
602 * in the persistid hash table for possible reclaim.
603 *
604 * This is run via smb_llist_post (after smb_llist_exit)
605 * because smb_ofile_close can block, and we'd rather not
606 * block while holding the ofile list as reader.
607 */
608 static void
609 smb_ofile_drop(void *arg)
610 {
611 smb_ofile_t *of = arg;
612
613 mutex_enter(&of->f_mutex);
614 switch (of->f_state) {
615 case SMB_OFILE_STATE_OPEN:
616 /* DH checks under mutex. */
617 if (of->f_ftype == SMB_FTYPE_DISK &&
618 of->dh_vers != SMB2_NOT_DURABLE &&
619 smb_dh_should_save(of)) {
620 /*
621 * Tell smb_ofile_release() to
622 * make this an _ORPHANED DH.
623 */
624 of->f_state = SMB_OFILE_STATE_SAVE_DH;
625 mutex_exit(&of->f_mutex);
626 break;
627 }
628 /* OK close it. */
629 mutex_exit(&of->f_mutex);
630 smb_ofile_close(of, 0);
631 break;
632
633 default:
634 /* Something else closed it already. */
635 mutex_exit(&of->f_mutex);
636 break;
637 }
638
639 /*
640 * Release the ref acquired during the traversal loop.
641 * Note that on the last ref, this ofile will be
642 * removed from the tree list etc.
643 * See: smb_llist_post, smb_ofile_delete
644 */
645 smb_ofile_release(of);
646 }
647
648 /*
649 * smb_ofile_close_all
650 *
651 *
652 */
653 void
654 smb_ofile_close_all(
655 smb_tree_t *tree,
656 uint32_t pid)
657 {
658 smb_ofile_t *of;
659 smb_llist_t *ll;
660
661 ASSERT(tree);
662 ASSERT(tree->t_magic == SMB_TREE_MAGIC);
663
664 ll = &tree->t_ofile_list;
665
666 smb_llist_enter(ll, RW_READER);
667 for (of = smb_llist_head(ll);
668 of != NULL;
669 of = smb_llist_next(ll, of)) {
670 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
671 ASSERT(of->f_tree == tree);
672 if (pid != 0 && of->f_opened_by_pid != pid)
673 continue;
674 if (smb_ofile_hold(of)) {
675 smb_llist_post(ll, of, smb_ofile_drop);
676 }
677 }
678
679 /*
680 * Drop the lock and process the llist dtor queue.
681 * Calls smb_ofile_drop on ofiles that were open.
682 */
683 smb_llist_exit(ll);
684 }
685
686 /*
687 * If the enumeration request is for ofile data, handle it here.
688 * Otherwise, return.
689 *
690 * This function should be called with a hold on the ofile.
691 */
692 int
693 smb_ofile_enum(smb_ofile_t *of, smb_svcenum_t *svcenum)
694 {
695 uint8_t *pb;
696 uint_t nbytes;
697 int rc;
698
699 ASSERT(of);
700 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
701 ASSERT(of->f_refcnt);
702
703 if (svcenum->se_type != SMB_SVCENUM_TYPE_FILE)
710
711 if (svcenum->se_nitems >= svcenum->se_nlimit) {
712 svcenum->se_nitems = svcenum->se_nlimit;
713 return (0);
714 }
715
716 pb = &svcenum->se_buf[svcenum->se_bused];
717
718 rc = smb_ofile_netinfo_encode(of, pb, svcenum->se_bavail,
719 &nbytes);
720 if (rc == 0) {
721 svcenum->se_bavail -= nbytes;
722 svcenum->se_bused += nbytes;
723 svcenum->se_nitems++;
724 }
725
726 return (rc);
727 }
728
729 /*
730 * Take a reference on an open file, in any of the states:
731 * RECONNECT, SAVE_DH, OPEN, ORPHANED.
732 * Return TRUE if ref taken. Used for oplock breaks.
733 *
734 * Note: When the oplock break code calls this, it holds the
735 * node ofile list lock and node oplock mutex. When we see
736 * an ofile in states RECONNECT or SAVING, we know the ofile
737 * is gaining or losing it's tree, and that happens quickly,
738 * so we just wait for that work to finish. However, the
739 * waiting for state transitions here means we have to be
740 * careful not to re-enter the node list lock or otherwise
741 * block on things that could cause a deadlock. Waiting
742 * just on of->f_mutex here is OK.
743 */
744 boolean_t
745 smb_ofile_hold_olbrk(smb_ofile_t *of)
746 {
747 boolean_t ret = B_FALSE;
748
749 ASSERT(of);
750 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
751
752 mutex_enter(&of->f_mutex);
753
754 again:
755 switch (of->f_state) {
756 case SMB_OFILE_STATE_RECONNECT:
757 case SMB_OFILE_STATE_SAVING:
758 cv_wait(&of->f_cv, &of->f_mutex);
759 goto again;
760
761 case SMB_OFILE_STATE_OPEN:
762 case SMB_OFILE_STATE_ORPHANED:
763 case SMB_OFILE_STATE_SAVE_DH:
764 of->f_refcnt++;
765 ret = B_TRUE;
766 break;
767
768 default:
769 break;
770 }
771 mutex_exit(&of->f_mutex);
772
773 return (ret);
774 }
775
776 /*
777 * Take a reference on an open file.
778 */
779 boolean_t
780 smb_ofile_hold(smb_ofile_t *of)
781 {
782 ASSERT(of);
783 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
784
785 mutex_enter(&of->f_mutex);
786
787 if (of->f_state != SMB_OFILE_STATE_OPEN) {
788 mutex_exit(&of->f_mutex);
789 return (B_FALSE);
790 }
791 of->f_refcnt++;
792
793 mutex_exit(&of->f_mutex);
794 return (B_TRUE);
795 }
796
797 /*
798 * Release a reference on a file. If the reference count falls to
799 * zero and the file has been closed, post the object for deletion.
800 * Object deletion is deferred to avoid modifying a list while an
801 * iteration may be in progress.
802 *
803 * We're careful to avoid dropping f_session etc. until the last
804 * reference goes away. The oplock break code depends on that
805 * not changing while it holds a ref. on an ofile.
806 */
807 void
808 smb_ofile_release(smb_ofile_t *of)
809 {
810 smb_tree_t *tree = of->f_tree;
811 boolean_t delete = B_FALSE;
812
813 SMB_OFILE_VALID(of);
814
815 mutex_enter(&of->f_mutex);
816 ASSERT(of->f_refcnt > 0);
817 of->f_refcnt--;
818
819 switch (of->f_state) {
820 case SMB_OFILE_STATE_OPEN:
821 case SMB_OFILE_STATE_ORPHANED:
822 case SMB_OFILE_STATE_EXPIRED:
823 break;
824
825 case SMB_OFILE_STATE_SAVE_DH:
826 ASSERT(tree != NULL);
827 if (of->f_refcnt == 0) {
828 of->f_state = SMB_OFILE_STATE_SAVING;
829 smb_llist_post(&tree->t_ofile_list, of,
830 smb_ofile_save_dh);
831 }
832 break;
833
834 case SMB_OFILE_STATE_CLOSING:
835 /* Note, tree == NULL on _ORPHANED */
836 if (of->f_refcnt == 0) {
837 of->f_state = SMB_OFILE_STATE_CLOSED;
838 if (tree == NULL) {
839 /* Skip smb_llist_post */
840 delete = B_TRUE;
841 break;
842 }
843 smb_llist_post(&tree->t_ofile_list, of,
844 smb_ofile_delete);
845 }
846 break;
847
848 default:
849 ASSERT(0);
850 break;
851 }
852 mutex_exit(&of->f_mutex);
853
854 /*
855 * When we drop the last ref. on an expired DH, it's no longer
856 * in any tree, so skip the smb_llist_post and just call
857 * smb_ofile_delete directly.
858 */
859 if (delete) {
860 smb_ofile_delete(of);
861 }
862 }
863
864 /*
865 * smb_ofile_lookup_by_fid
866 *
867 * Find the open file whose fid matches the one specified in the request.
868 * If we can't find the fid or the shares (trees) don't match, we have a
869 * bad fid.
870 */
871 smb_ofile_t *
872 smb_ofile_lookup_by_fid(
873 smb_request_t *sr,
874 uint16_t fid)
875 {
876 smb_tree_t *tree = sr->tid_tree;
877 smb_llist_t *of_list;
878 smb_ofile_t *of;
879
880 ASSERT(tree->t_magic == SMB_TREE_MAGIC);
885 of = smb_llist_head(of_list);
886 while (of) {
887 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
888 ASSERT(of->f_tree == tree);
889 if (of->f_fid == fid)
890 break;
891 of = smb_llist_next(of_list, of);
892 }
893 if (of == NULL)
894 goto out;
895
896 /*
897 * Only allow use of a given FID with the same UID that
898 * was used to open it. MS-CIFS 3.3.5.14
899 */
900 if (of->f_user != sr->uid_user) {
901 of = NULL;
902 goto out;
903 }
904
905 /* inline smb_ofile_hold() */
906 mutex_enter(&of->f_mutex);
907 if (of->f_state != SMB_OFILE_STATE_OPEN) {
908 mutex_exit(&of->f_mutex);
909 of = NULL;
910 goto out;
911 }
912 of->f_refcnt++;
913 mutex_exit(&of->f_mutex);
914
915 out:
916 smb_llist_exit(of_list);
917 return (of);
918 }
919
920 /*
921 * smb_ofile_lookup_by_uniqid
922 *
923 * Find the open file whose uniqid matches the one specified in the request.
924 */
925 smb_ofile_t *
936
937 while (of) {
938 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
939 ASSERT(of->f_tree == tree);
940
941 if (of->f_uniqid == uniqid) {
942 if (smb_ofile_hold(of)) {
943 smb_llist_exit(of_list);
944 return (of);
945 }
946 }
947
948 of = smb_llist_next(of_list, of);
949 }
950
951 smb_llist_exit(of_list);
952 return (NULL);
953 }
954
955 /*
956 * Durable ID (or persistent ID)
957 */
958
959 static smb_ofile_t *
960 smb_ofile_hold_cb(smb_ofile_t *of)
961 {
962 smb_ofile_t *ret = of;
963
964 mutex_enter(&of->f_mutex);
965 if (of->f_state == SMB_OFILE_STATE_ORPHANED)
966 /* inline smb_ofile_hold() */
967 of->f_refcnt++;
968 else
969 ret = NULL;
970
971 mutex_exit(&of->f_mutex);
972 return (ret);
973 }
974
975 /*
976 * Lookup an ofile by persistent ID, and return ONLY if in state ORPHANED
977 * This is used by SMB2 create "reclaim".
978 */
979 smb_ofile_t *
980 smb_ofile_lookup_by_persistid(smb_request_t *sr, uint64_t persistid)
981 {
982 smb_hash_t *hash;
983 smb_bucket_t *bucket;
984 smb_llist_t *ll;
985 smb_ofile_t *of;
986 uint_t idx;
987
988 if (persistid == 0)
989 return (NULL);
990
991 hash = sr->sr_server->sv_persistid_ht;
992 idx = smb_hash_uint64(hash, persistid);
993 bucket = &hash->buckets[idx];
994 ll = &bucket->b_list;
995
996 smb_llist_enter(ll, RW_READER);
997 of = smb_llist_head(ll);
998 while (of != NULL) {
999 if (of->f_persistid == persistid)
1000 break;
1001 of = smb_llist_next(ll, of);
1002 }
1003 if (of != NULL)
1004 of = smb_ofile_hold_cb(of);
1005 smb_llist_exit(ll);
1006
1007 return (of);
1008 }
1009
1010 /*
1011 * Create a (unique) durable/persistent ID for a new ofile,
1012 * and add this ofile to the persistid hash table. This ID
1013 * is referred to as the persistent ID in the protocol spec,
1014 * so that's what we call it too, though the persistence may
1015 * vary. "Durable" handles are persistent across reconnects
1016 * but not server reboots. Persistent handles are persistent
1017 * across server reboots too.
1018 *
1019 * Note that persistent IDs need to be unique for the lifetime of
1020 * any given ofile. For normal (non-persistent) ofiles we can just
1021 * use a persistent ID derived from the ofile memory address, as
1022 * these don't ever live beyond the current OS boot lifetime.
1023 *
1024 * Persistent handles are re-imported after server restart, and
1025 * generally have a different memory address after import than
1026 * they had in the previous OS boot lifetime, so for these we
1027 * use a randomly assigned value that won't conflict with any
1028 * non-persistent (durable) handles. Ensuring that a randomly
1029 * generated ID is unique requres a search of the ofiles in one
1030 * hash bucket, which we'd rather avoid for non-persistent opens.
1031 *
1032 * The solution used here is to divide the persistent ID space
1033 * in half (odd and even values) where durable opens use an ID
1034 * derived from the ofile address (which is always even), and
1035 * persistent opens use an ID generated randomly (always odd).
1036 *
1037 * smb_ofile_set_persistid_dh() sets a durable handle ID and
1038 * smb_ofile_set_persistid_ph() sets a persistent handle ID.
1039 */
1040 void
1041 smb_ofile_set_persistid_dh(smb_ofile_t *of)
1042 {
1043 smb_hash_t *hash = of->f_server->sv_persistid_ht;
1044 smb_bucket_t *bucket;
1045 smb_llist_t *ll;
1046 uint64_t persistid;
1047 uint_t idx;
1048
1049 persistid = (uintptr_t)of;
1050 /* Avoid showing object addresses */
1051 persistid ^= ((uintptr_t)&smb_cache_ofile);
1052 /* make sure it's even */
1053 persistid &= ~((uint64_t)1);
1054
1055 idx = smb_hash_uint64(hash, persistid);
1056 bucket = &hash->buckets[idx];
1057 ll = &bucket->b_list;
1058 smb_llist_enter(ll, RW_WRITER);
1059 if (of->f_persistid == 0) {
1060 of->f_persistid = persistid;
1061 smb_llist_insert_tail(ll, of);
1062 }
1063 smb_llist_exit(ll);
1064 }
1065
1066 void
1067 smb_ofile_set_persistid_ph(smb_ofile_t *of)
1068 {
1069 uint64_t persistid;
1070 int rc;
1071
1072 top:
1073 (void) random_get_pseudo_bytes((uint8_t *)&persistid,
1074 sizeof (persistid));
1075 if (persistid == 0) {
1076 cmn_err(CE_NOTE, "random gave all zeros!");
1077 goto top;
1078 }
1079 /* make sure it's odd */
1080 persistid |= (uint64_t)1;
1081
1082 /*
1083 * Try inserting with this persistent ID.
1084 */
1085 rc = smb_ofile_insert_persistid(of, persistid);
1086 if (rc == EEXIST)
1087 goto top;
1088 if (rc != 0) {
1089 cmn_err(CE_NOTE, "set persistid rc=%d", rc);
1090 }
1091 }
1092
1093 /*
1094 * Insert an ofile into the persistid hash table.
1095 * If the persistent ID is in use, error.
1096 */
1097 int
1098 smb_ofile_insert_persistid(smb_ofile_t *new_of, uint64_t persistid)
1099 {
1100 smb_hash_t *hash = new_of->f_server->sv_persistid_ht;
1101 smb_bucket_t *bucket;
1102 smb_llist_t *ll;
1103 smb_ofile_t *of;
1104 uint_t idx;
1105
1106 ASSERT(persistid != 0);
1107
1108 /*
1109 * Look to see if this key alreay exists.
1110 */
1111 idx = smb_hash_uint64(hash, persistid);
1112 bucket = &hash->buckets[idx];
1113 ll = &bucket->b_list;
1114
1115 smb_llist_enter(ll, RW_WRITER);
1116 of = smb_llist_head(ll);
1117 while (of != NULL) {
1118 if (of->f_persistid == persistid) {
1119 /* already in use */
1120 smb_llist_exit(ll);
1121 return (EEXIST);
1122 }
1123 of = smb_llist_next(ll, of);
1124 }
1125
1126 /* Not found, so OK to insert. */
1127 if (new_of->f_persistid == 0) {
1128 new_of->f_persistid = persistid;
1129 smb_llist_insert_tail(ll, new_of);
1130 }
1131 smb_llist_exit(ll);
1132
1133 return (0);
1134 }
1135
1136 void
1137 smb_ofile_del_persistid(smb_ofile_t *of)
1138 {
1139 smb_hash_t *hash = of->f_server->sv_persistid_ht;
1140 smb_bucket_t *bucket;
1141 smb_llist_t *ll;
1142 uint_t idx;
1143
1144 idx = smb_hash_uint64(hash, of->f_persistid);
1145 bucket = &hash->buckets[idx];
1146 ll = &bucket->b_list;
1147 smb_llist_enter(ll, RW_WRITER);
1148 if (of->f_persistid != 0) {
1149 smb_llist_remove(ll, of);
1150 of->f_persistid = 0;
1151 }
1152 smb_llist_exit(ll);
1153 }
1154
1155
1156 /*
1157 * Disallow NetFileClose on certain ofiles to avoid side-effects.
1158 * Closing a tree root is not allowed: use NetSessionDel or NetShareDel.
1159 * Closing SRVSVC connections is not allowed because this NetFileClose
1160 * request may depend on this ofile.
1161 */
1162 boolean_t
1163 smb_ofile_disallow_fclose(smb_ofile_t *of)
1164 {
1165 ASSERT(of);
1166 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
1167 ASSERT(of->f_refcnt);
1168
1169 switch (of->f_ftype) {
1170 case SMB_FTYPE_DISK:
1171 ASSERT(of->f_tree);
1172 return (of->f_node == of->f_tree->t_snode);
1173
1174 case SMB_FTYPE_MESG_PIPE:
1175 ASSERT(of->f_pipe);
1176 if (smb_strcasecmp(of->f_pipe->p_name, "SRVSVC", 0) == 0)
1309 {
1310 boolean_t rc;
1311
1312 SMB_OFILE_VALID(of);
1313
1314 mutex_enter(&of->f_mutex);
1315 rc = smb_ofile_is_open_locked(of);
1316 mutex_exit(&of->f_mutex);
1317 return (rc);
1318 }
1319
1320 /* *************************** Static Functions ***************************** */
1321
1322 /*
1323 * Determine whether or not an ofile is open.
1324 * This function must be called with the mutex held.
1325 */
1326 static boolean_t
1327 smb_ofile_is_open_locked(smb_ofile_t *of)
1328 {
1329 ASSERT(MUTEX_HELD(&of->f_mutex));
1330
1331 switch (of->f_state) {
1332 case SMB_OFILE_STATE_OPEN:
1333 case SMB_OFILE_STATE_SAVE_DH:
1334 case SMB_OFILE_STATE_SAVING:
1335 case SMB_OFILE_STATE_ORPHANED:
1336 case SMB_OFILE_STATE_RECONNECT:
1337 return (B_TRUE);
1338
1339 case SMB_OFILE_STATE_CLOSING:
1340 case SMB_OFILE_STATE_CLOSED:
1341 case SMB_OFILE_STATE_EXPIRED:
1342 return (B_FALSE);
1343
1344 default:
1345 ASSERT(0);
1346 return (B_FALSE);
1347 }
1348 }
1349
1350 /*
1351 * smb_ofile_save_dh
1352 *
1353 * Called via smb_llist_post (after smb_llist_exit) when the last ref.
1354 * on this ofile has gone, and this ofile is a "durable handle" (DH)
1355 * that has state we've decided to save.
1356 *
1357 * This does parts of what smb_ofile_delete would do, including:
1358 * remove the ofile from the tree ofile list and related.
1359 *
1360 * We leave the ofile in state ORPHANED, ready for reconnect
1361 * or expiration via smb2_dh_expire (see smb_ofile_delete).
1362 */
1363 static void
1364 smb_ofile_save_dh(void *arg)
1365 {
1366 smb_ofile_t *of = (smb_ofile_t *)arg;
1367 smb_tree_t *tree = of->f_tree;
1368
1369 SMB_OFILE_VALID(of);
1370 ASSERT(of->f_refcnt == 0);
1371 ASSERT(of->f_ftype == SMB_FTYPE_DISK);
1372 ASSERT(of->f_state == SMB_OFILE_STATE_SAVING);
1373
1374 atomic_dec_32(&of->f_session->s_file_cnt);
1375 atomic_dec_32(&of->f_tree->t_open_files);
1376 smb_llist_enter(&tree->t_ofile_list, RW_WRITER);
1377 smb_llist_remove(&tree->t_ofile_list, of);
1378 smb_llist_exit(&tree->t_ofile_list);
1379
1380 /*
1381 * This ofile is no longer on t_ofile_list, however...
1382 *
1383 * This is called via smb_llist_post, which means it may run
1384 * BEFORE smb_ofile_release drops f_mutex (if another thread
1385 * flushes the delete queue before we do). Synchronize.
1386 */
1387 mutex_enter(&of->f_mutex);
1388 DTRACE_PROBE1(ofile__exit, smb_ofile_t, of);
1389 mutex_exit(&of->f_mutex);
1390
1391 /*
1392 * Keep f_notify state, lease, and
1393 * keep on node ofile list.
1394 * Keep of->f_cr until reclaim.
1395 */
1396
1397 ASSERT(of->f_fid != 0);
1398 smb_idpool_free(&tree->t_fid_pool, of->f_fid);
1399 of->f_fid = 0;
1400 smb_tree_release(of->f_tree);
1401 of->f_tree = NULL;
1402 smb_user_release(of->f_user);
1403 of->f_user = NULL;
1404 of->f_session = NULL;
1405
1406 /*
1407 * Make it "orphaned" so it can now be reclaimed.
1408 * Note that smb_ofile_hold_olbrk() may have blocked
1409 * for state SMB_OFILE_STATE_SAVING, so wake it.
1410 */
1411 mutex_enter(&of->f_mutex);
1412 of->dh_expire_time = gethrtime() + of->dh_timeout_offset;
1413 of->f_state = SMB_OFILE_STATE_ORPHANED;
1414 cv_broadcast(&of->f_cv);
1415 mutex_exit(&of->f_mutex);
1416 }
1417
1418 /*
1419 * Delete an ofile.
1420 *
1421 * Approximately the inverse of smb_ofile_alloc()
1422 * Called via smb_llist_post (after smb_llist_exit)
1423 * when the last ref. on this ofile has gone.
1424 *
1425 * Normally,this removes the ofile from the tree list and
1426 * then frees resources held on the ofile. However, when
1427 * we're expiring an orphaned durable handle, the linkage
1428 * into the tree lists etc. have already been destroyed.
1429 * This case is distinguished by of->f_tree == NULL.
1430 */
1431 static void
1432 smb_ofile_delete(void *arg)
1433 {
1434 smb_ofile_t *of = (smb_ofile_t *)arg;
1435 smb_tree_t *tree = of->f_tree;
1436
1437 SMB_OFILE_VALID(of);
1438 ASSERT(of->f_refcnt == 0);
1439 ASSERT(of->f_state == SMB_OFILE_STATE_CLOSED);
1440
1441 if (tree != NULL) {
1442 ASSERT(of->f_user != NULL);
1443 ASSERT(of->f_session != NULL);
1444 atomic_dec_32(&of->f_session->s_file_cnt);
1445 atomic_dec_32(&of->f_tree->t_open_files);
1446 smb_llist_enter(&tree->t_ofile_list, RW_WRITER);
1447 smb_llist_remove(&tree->t_ofile_list, of);
1448 smb_llist_exit(&tree->t_ofile_list);
1449 }
1450
1451 /*
1452 * Remove this ofile from the node's n_ofile_list so it
1453 * can't be found by list walkers like notify or oplock.
1454 * Keep the node ref. until later in this function so
1455 * of->f_node remains valid while we destroy the ofile.
1456 */
1457 if (of->f_ftype == SMB_FTYPE_DISK ||
1458 of->f_ftype == SMB_FTYPE_PRINTER) {
1459 ASSERT(of->f_node != NULL);
1460 /*
1461 * Note smb_ofile_close did smb_node_dec_open_ofiles()
1462 */
1463 smb_node_rem_ofile(of->f_node, of);
1464 }
1465
1466 /*
1467 * This ofile is no longer on any lists, however...
1468 *
1469 * This is called via smb_llist_post, which means it may run
1470 * BEFORE smb_ofile_release drops f_mutex (if another thread
1471 * flushes the delete queue before we do). Synchronize.
1472 */
1473 mutex_enter(&of->f_mutex);
1474 of->f_state = SMB_OFILE_STATE_ALLOC;
1475 DTRACE_PROBE1(ofile__exit, smb_ofile_t, of);
1476 mutex_exit(&of->f_mutex);
1477
1478 switch (of->f_ftype) {
1479 case SMB_FTYPE_BYTE_PIPE:
1480 case SMB_FTYPE_MESG_PIPE:
1481 smb_opipe_dealloc(of->f_pipe);
1482 of->f_pipe = NULL;
1483 break;
1484 case SMB_FTYPE_DISK:
1485 ASSERT(of->f_notify.nc_subscribed == B_FALSE);
1486 MBC_FLUSH(&of->f_notify.nc_buffer);
1487 if (of->f_odir != NULL)
1488 smb_odir_release(of->f_odir);
1489 if (of->f_lease != NULL) {
1490 smb2_lease_rele(of->f_lease);
1491 of->f_lease = NULL;
1492 }
1493 /* FALLTHROUGH */
1494 case SMB_FTYPE_PRINTER:
1495 /*
1496 * Did smb_node_rem_ofile above.
1497 */
1498 ASSERT(of->f_node != NULL);
1499 smb_node_release(of->f_node);
1500 break;
1501 default:
1502 ASSERT(!"f_ftype");
1503 break;
1504 }
1505
1506 smb_ofile_free(of);
1507 }
1508
1509 void
1510 smb_ofile_free(smb_ofile_t *of)
1511 {
1512 smb_tree_t *tree = of->f_tree;
1513
1514 ASSERT(of->f_state == SMB_OFILE_STATE_ALLOC);
1515
1516 /* Make sure it's not in the persistid hash. */
1517 ASSERT(of->f_persistid == 0);
1518
1519 if (tree != NULL) {
1520 if (of->f_fid != 0)
1521 smb_idpool_free(&tree->t_fid_pool, of->f_fid);
1522 smb_tree_release(of->f_tree);
1523 smb_user_release(of->f_user);
1524 }
1525
1526 if (of->f_cr != NULL)
1527 crfree(of->f_cr);
1528
1529 of->f_magic = (uint32_t)~SMB_OFILE_MAGIC;
1530 list_destroy(&of->f_notify.nc_waiters);
1531 mutex_destroy(&of->dh_nvlock);
1532 mutex_destroy(&of->f_mutex);
1533 kmem_cache_free(smb_cache_ofile, of);
1534 }
1535
1536 /*
1537 * smb_ofile_access
1538 *
1539 * This function will check to see if the access requested is granted.
1540 * Returns NT status codes.
1541 */
1542 uint32_t
1543 smb_ofile_access(smb_ofile_t *of, cred_t *cr, uint32_t access)
1544 {
1545
1546 if ((of == NULL) || (cr == zone_kcred()))
1547 return (NT_STATUS_SUCCESS);
1548
1549 /*
1550 * If the request is for something
1551 * I don't grant it is an error
1552 */
1568 * Returns: B_TRUE - share access non-zero
1569 * B_FALSE - share access NONE
1570 */
1571 boolean_t
1572 smb_ofile_share_check(smb_ofile_t *of)
1573 {
1574 return (!SMB_DENY_ALL(of->f_share_access));
1575 }
1576
1577 /*
1578 * check file sharing rules for current open request
1579 * against existing open instances of the same file
1580 *
1581 * Returns NT_STATUS_SHARING_VIOLATION if there is any
1582 * sharing conflict, otherwise returns NT_STATUS_SUCCESS.
1583 */
1584 uint32_t
1585 smb_ofile_open_check(smb_ofile_t *of, uint32_t desired_access,
1586 uint32_t share_access)
1587 {
1588 uint32_t ret;
1589
1590 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
1591
1592 mutex_enter(&of->f_mutex);
1593
1594 if (!smb_ofile_is_open_locked(of)) {
1595 ret = NT_STATUS_INVALID_HANDLE;
1596 goto out;
1597 }
1598
1599 /* if it's just meta data */
1600 if ((of->f_granted_access & FILE_DATA_ALL) == 0) {
1601 ret = NT_STATUS_SUCCESS;
1602 goto out;
1603 }
1604
1605 /*
1606 * Check requested share access against the
1607 * open granted (desired) access
1608 */
1609 if (SMB_DENY_DELETE(share_access) && (of->f_granted_access & DELETE)) {
1610 ret = NT_STATUS_SHARING_VIOLATION;
1611 goto out;
1612 }
1613
1614 if (SMB_DENY_READ(share_access) &&
1615 (of->f_granted_access & (FILE_READ_DATA | FILE_EXECUTE))) {
1616 ret = NT_STATUS_SHARING_VIOLATION;
1617 goto out;
1618 }
1619
1620 if (SMB_DENY_WRITE(share_access) &&
1621 (of->f_granted_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) {
1622 ret = NT_STATUS_SHARING_VIOLATION;
1623 goto out;
1624 }
1625
1626 /* check requested desired access against the open share access */
1627 if (SMB_DENY_DELETE(of->f_share_access) && (desired_access & DELETE)) {
1628 ret = NT_STATUS_SHARING_VIOLATION;
1629 goto out;
1630 }
1631
1632 if (SMB_DENY_READ(of->f_share_access) &&
1633 (desired_access & (FILE_READ_DATA | FILE_EXECUTE))) {
1634 ret = NT_STATUS_SHARING_VIOLATION;
1635 goto out;
1636 }
1637
1638 if (SMB_DENY_WRITE(of->f_share_access) &&
1639 (desired_access & (FILE_WRITE_DATA | FILE_APPEND_DATA))) {
1640 ret = NT_STATUS_SHARING_VIOLATION;
1641 goto out;
1642 }
1643
1644 ret = NT_STATUS_SUCCESS;
1645 out:
1646 mutex_exit(&of->f_mutex);
1647 return (ret);
1648 }
1649
1650 /*
1651 * smb_ofile_rename_check
1652 *
1653 * This does the work described in MS-FSA 2.1.5.1.2.2 (Algorithm
1654 * to Check Sharing Access to an Existing Stream or Directory),
1655 * where the "open in-progress" has DesiredAccess = DELETE and
1656 * SharingMode = SHARE_READ | SHARE_WRITE | SHARE_DELETE.
1657 */
1658
1659 uint32_t
1660 smb_ofile_rename_check(smb_ofile_t *of)
1661 {
1662 uint32_t ret;
1663
1664 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
1665
1666 mutex_enter(&of->f_mutex);
1667
1668 if (!smb_ofile_is_open_locked(of)) {
1669 ret = NT_STATUS_INVALID_HANDLE;
1670 goto out;
1671 }
1672
1673 if ((of->f_granted_access & FILE_DATA_ALL) == 0) {
1674 ret = NT_STATUS_SUCCESS;
1675 goto out;
1676 }
1677
1678 if ((of->f_share_access & FILE_SHARE_DELETE) == 0) {
1679 ret = NT_STATUS_SHARING_VIOLATION;
1680 goto out;
1681 }
1682
1683 ret = NT_STATUS_SUCCESS;
1684 out:
1685 mutex_exit(&of->f_mutex);
1686 return (ret);
1687 }
1688
1689 /*
1690 * smb_ofile_delete_check
1691 *
1692 * An open file can be deleted only if opened for
1693 * accessing meta data. Share modes aren't important
1694 * in this case.
1695 *
1696 * NOTE: there is another mechanism for deleting an
1697 * open file that NT clients usually use.
1698 * That's setting "Delete on close" flag for an open
1699 * file. In this way the file will be deleted after
1700 * last close. This flag can be set by SmbTrans2SetFileInfo
1701 * with FILE_DISPOSITION_INFO information level.
1702 * For setting this flag, the file should be opened by
1703 * DELETE access in the FID that is passed in the Trans2
1704 * request.
1705 */
1706
1707 uint32_t
1708 smb_ofile_delete_check(smb_ofile_t *of)
1709 {
1710 uint32_t ret;
1711
1712 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
1713
1714 mutex_enter(&of->f_mutex);
1715
1716 if (!smb_ofile_is_open_locked(of)) {
1717 ret = NT_STATUS_INVALID_HANDLE;
1718 goto out;
1719 }
1720
1721 if (of->f_granted_access &
1722 (FILE_READ_DATA | FILE_WRITE_DATA |
1723 FILE_APPEND_DATA | FILE_EXECUTE | DELETE)) {
1724 ret = NT_STATUS_SHARING_VIOLATION;
1725 goto out;
1726 }
1727
1728 ret = NT_STATUS_SUCCESS;
1729 out:
1730 mutex_exit(&of->f_mutex);
1731 return (ret);
1732 }
1733
1734 cred_t *
1735 smb_ofile_getcred(smb_ofile_t *of)
1736 {
1737 return (of->f_cr);
1738 }
1739
1740 /*
1741 * smb_ofile_set_delete_on_close
1742 *
1743 * Set the DeleteOnClose flag on the smb file. When the file is closed,
1744 * the flag will be transferred to the smb node, which will commit the
1745 * delete operation and inhibit subsequent open requests.
1746 *
1747 * When DeleteOnClose is set on an smb_node, the common open code will
1748 * reject subsequent open requests for the file. Observation of Windows
1749 * 2000 indicates that subsequent opens should be allowed (assuming
1750 * there would be no sharing violation) until the file is closed using
1751 * the fid on which the DeleteOnClose was requested.
1752 */
1753 void
1754 smb_ofile_set_delete_on_close(smb_request_t *sr, smb_ofile_t *of)
1755 {
1756 uint32_t status;
1757
1758 /*
1759 * Break any oplock handle caching.
1760 */
1761 status = smb_oplock_break_SETINFO(of->f_node, of,
1762 FileDispositionInformation);
1763 if (status == NT_STATUS_OPLOCK_BREAK_IN_PROGRESS) {
1764 if (sr->session->dialect >= SMB_VERS_2_BASE)
1765 (void) smb2sr_go_async(sr);
1766 (void) smb_oplock_wait_break(of->f_node, 0);
1767 }
1768
1769 mutex_enter(&of->f_mutex);
1770 of->f_flags |= SMB_OFLAGS_SET_DELETE_ON_CLOSE;
1771 mutex_exit(&of->f_mutex);
1772 }
1773
1774 /*
1775 * Encode open file information into a buffer; needed in user space to
1776 * support RPC requests.
1777 */
1778 static int
1779 smb_ofile_netinfo_encode(smb_ofile_t *of, uint8_t *buf, size_t buflen,
1780 uint32_t *nbytes)
1781 {
1782 smb_netfileinfo_t fi;
1783 int rc;
1784
1785 rc = smb_ofile_netinfo_init(of, &fi);
1786 if (rc == 0) {
1787 rc = smb_netfileinfo_encode(&fi, buf, buflen, nbytes);
1788 smb_ofile_netinfo_fini(&fi);
|