1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2016 Syneto S.R.L. All rights reserved.
24 * Copyright (c) 2016 by Delphix. All rights reserved.
25 * Copyright 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 * | |
46 * | v
47 * | +-------------------+ +-------------------+ +-------------------+
48 * | | USER |<--->| USER |...| USER |
49 * | +-------------------+ +-------------------+ +-------------------+
50 * |
51 * |
52 * v
53 * +-------------------+ +-------------------+ +-------------------+
54 * | TREE |<----->| TREE |......| TREE |
55 * +-------------------+ +-------------------+ +-------------------+
56 * | |
57 * | |
58 * | v
59 * | +-------+ +-------+ +-------+
60 * | | OFILE |<----->| OFILE |......| OFILE |
61 * | +-------+ +-------+ +-------+
62 * |
63 * |
64 * v
65 * +-------+ +------+ +------+
66 * | ODIR |<----->| ODIR |......| ODIR |
67 * +-------+ +------+ +------+
68 *
69 *
70 * Ofile State Machine
71 * ------------------
72 *
73 * +-------------------------+ T0
74 * | SMB_OFILE_STATE_OPEN |<--+-------- Creation/Allocation
75 * +-------------------------+ |
76 * | | | 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)
704 return (0);
705
706 if (svcenum->se_nskip > 0) {
707 svcenum->se_nskip--;
708 return (0);
709 }
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);
881
882 of_list = &tree->t_ofile_list;
883
884 smb_llist_enter(of_list, RW_READER);
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 *
926 smb_ofile_lookup_by_uniqid(smb_tree_t *tree, uint32_t uniqid)
927 {
928 smb_llist_t *of_list;
929 smb_ofile_t *of;
930
931 ASSERT(tree->t_magic == SMB_TREE_MAGIC);
932
933 of_list = &tree->t_ofile_list;
934 smb_llist_enter(of_list, RW_READER);
935 of = smb_llist_head(of_list);
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)
1177 return (B_TRUE);
1178 break;
1179 default:
1180 break;
1181 }
1182
1183 return (B_FALSE);
1184 }
1185
1186 /*
1187 * smb_ofile_set_flags
1188 *
1189 * Return value:
1190 *
1191 * Current flags value
1192 *
1193 */
1194 void
1195 smb_ofile_set_flags(
1196 smb_ofile_t *of,
1197 uint32_t flags)
1198 {
1199 ASSERT(of);
1200 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
1201 ASSERT(of->f_refcnt);
1202
1203 mutex_enter(&of->f_mutex);
1204 of->f_flags |= flags;
1205 mutex_exit(&of->f_mutex);
1206 }
1207
1208 /*
1209 * smb_ofile_seek
1210 *
1211 * Return value:
1212 *
1213 * 0 Success
1214 * EINVAL Unknown mode
1215 * EOVERFLOW offset too big
1216 *
1217 */
1218 int
1219 smb_ofile_seek(
1220 smb_ofile_t *of,
1221 ushort_t mode,
1222 int32_t off,
1223 uint32_t *retoff)
1224 {
1225 u_offset_t newoff = 0;
1226 int rc = 0;
1227 smb_attr_t attr;
1228
1229 ASSERT(of);
1230 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
1231 ASSERT(of->f_refcnt);
1232
1233 mutex_enter(&of->f_mutex);
1234 switch (mode) {
1235 case SMB_SEEK_SET:
1236 if (off < 0)
1237 newoff = 0;
1238 else
1239 newoff = (u_offset_t)off;
1240 break;
1241
1242 case SMB_SEEK_CUR:
1243 if (off < 0 && (-off) > of->f_seek_pos)
1244 newoff = 0;
1245 else
1246 newoff = of->f_seek_pos + (u_offset_t)off;
1247 break;
1248
1249 case SMB_SEEK_END:
1250 bzero(&attr, sizeof (smb_attr_t));
1251 attr.sa_mask |= SMB_AT_SIZE;
1252 rc = smb_fsop_getattr(NULL, zone_kcred(), of->f_node, &attr);
1253 if (rc != 0) {
1254 mutex_exit(&of->f_mutex);
1255 return (rc);
1256 }
1257 if (off < 0 && (-off) > attr.sa_vattr.va_size)
1258 newoff = 0;
1259 else
1260 newoff = attr.sa_vattr.va_size + (u_offset_t)off;
1261 break;
1262
1263 default:
1264 mutex_exit(&of->f_mutex);
1265 return (EINVAL);
1266 }
1267
1268 /*
1269 * See comments at the beginning of smb_seek.c.
1270 * If the offset is greater than UINT_MAX, we will return an error.
1271 */
1272
1273 if (newoff > UINT_MAX) {
1274 rc = EOVERFLOW;
1275 } else {
1276 of->f_seek_pos = newoff;
1277 *retoff = (uint32_t)newoff;
1278 }
1279 mutex_exit(&of->f_mutex);
1280 return (rc);
1281 }
1282
1283 /*
1284 * smb_ofile_flush
1285 *
1286 * If writes on this file are not synchronous, flush it using the NFSv3
1287 * commit interface.
1288 *
1289 * XXX - todo: Flush named pipe should drain writes.
1290 */
1291 void
1292 smb_ofile_flush(struct smb_request *sr, struct smb_ofile *of)
1293 {
1294 switch (of->f_ftype) {
1295 case SMB_FTYPE_DISK:
1296 if ((of->f_node->flags & NODE_FLAGS_WRITE_THROUGH) == 0)
1297 (void) smb_fsop_commit(sr, of->f_cr, of->f_node);
1298 break;
1299 default:
1300 break;
1301 }
1302 }
1303
1304 /*
1305 * smb_ofile_is_open
1306 */
1307 boolean_t
1308 smb_ofile_is_open(smb_ofile_t *of)
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 */
1553 if (~(of->f_granted_access) & access) {
1554 if (!(of->f_granted_access & ACCESS_SYSTEM_SECURITY) &&
1555 (access & ACCESS_SYSTEM_SECURITY)) {
1556 return (NT_STATUS_PRIVILEGE_NOT_HELD);
1557 }
1558 return (NT_STATUS_ACCESS_DENIED);
1559 }
1560
1561 return (NT_STATUS_SUCCESS);
1562 }
1563
1564 /*
1565 * smb_ofile_share_check
1566 *
1567 * Check if ofile was opened with share access NONE (0).
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);
1789 }
1790
1791 return (rc);
1792 }
1793
1794 static int
1795 smb_ofile_netinfo_init(smb_ofile_t *of, smb_netfileinfo_t *fi)
1796 {
1797 smb_user_t *user;
1798 smb_tree_t *tree;
1799 smb_node_t *node;
1800 char *path;
1801 char *buf;
1802 int rc;
1803
1804 ASSERT(of);
1805 user = of->f_user;
1806 tree = of->f_tree;
1807 ASSERT(user);
1808 ASSERT(tree);
1809
1810 buf = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
1811
1812 switch (of->f_ftype) {
1813 case SMB_FTYPE_DISK:
1814 node = of->f_node;
1815 ASSERT(node);
1816
1817 fi->fi_permissions = of->f_granted_access;
1818 fi->fi_numlocks = smb_lock_get_lock_count(node, of);
1819
1820 path = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
1821
1822 if (node != tree->t_snode) {
1823 rc = smb_node_getshrpath(node, tree, path, MAXPATHLEN);
1824 if (rc != 0)
1825 (void) strlcpy(path, node->od_name, MAXPATHLEN);
1826 }
1827
1828 (void) snprintf(buf, MAXPATHLEN, "%s:%s", tree->t_sharename,
1829 path);
1830 kmem_free(path, MAXPATHLEN);
1831 break;
1832
1833 case SMB_FTYPE_MESG_PIPE:
1834 ASSERT(of->f_pipe);
1835
1836 fi->fi_permissions = FILE_READ_DATA | FILE_WRITE_DATA |
1837 FILE_EXECUTE;
1838 fi->fi_numlocks = 0;
1839 (void) snprintf(buf, MAXPATHLEN, "\\PIPE\\%s",
1840 of->f_pipe->p_name);
1841 break;
1842
1843 default:
1844 kmem_free(buf, MAXPATHLEN);
1845 return (-1);
1846 }
1847
1848 fi->fi_fid = of->f_fid;
1849 fi->fi_uniqid = of->f_uniqid;
1850 fi->fi_pathlen = strlen(buf) + 1;
1851 fi->fi_path = smb_mem_strdup(buf);
1852 kmem_free(buf, MAXPATHLEN);
1853
1854 fi->fi_namelen = user->u_domain_len + user->u_name_len + 2;
1855 fi->fi_username = kmem_alloc(fi->fi_namelen, KM_SLEEP);
1856 (void) snprintf(fi->fi_username, fi->fi_namelen, "%s\\%s",
1857 user->u_domain, user->u_name);
1858 return (0);
1859 }
1860
1861 static void
1862 smb_ofile_netinfo_fini(smb_netfileinfo_t *fi)
1863 {
1864 if (fi == NULL)
1865 return;
1866
1867 if (fi->fi_path)
1868 smb_mem_free(fi->fi_path);
1869 if (fi->fi_username)
1870 kmem_free(fi->fi_username, fi->fi_namelen);
1871
1872 bzero(fi, sizeof (smb_netfileinfo_t));
1873 }
1874
1875 /*
1876 * A query of user and group quotas may span multiple requests.
1877 * f_quota_resume is used to determine where the query should
1878 * be resumed, in a subsequent request. f_quota_resume contains
1879 * the SID of the last quota entry returned to the client.
1880 */
1881 void
1882 smb_ofile_set_quota_resume(smb_ofile_t *ofile, char *resume)
1883 {
1884 ASSERT(ofile);
1885 mutex_enter(&ofile->f_mutex);
1886 if (resume == NULL)
1887 bzero(ofile->f_quota_resume, SMB_SID_STRSZ);
1888 else
1889 (void) strlcpy(ofile->f_quota_resume, resume, SMB_SID_STRSZ);
1890 mutex_exit(&ofile->f_mutex);
1891 }
1892
1893 void
1894 smb_ofile_get_quota_resume(smb_ofile_t *ofile, char *buf, int bufsize)
1895 {
1896 ASSERT(ofile);
1897 mutex_enter(&ofile->f_mutex);
1898 (void) strlcpy(buf, ofile->f_quota_resume, bufsize);
1899 mutex_exit(&ofile->f_mutex);
1900 }