xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_ofile.c (revision 8c69cc8fbe729fa7b091e901c4b50508ccc6bb33)
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 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  *   |          |
46  *   |          v
47  *   |  +-------------------+     +-------------------+   +-------------------+
48  *   |  |       USER        |<--->|       USER        |...|       USER        |
49  *   |  +-------------------+     +-------------------+   +-------------------+
50  *   |
51  *   |
52  *   v
53  * +-------------------+       +-------------------+      +-------------------+
54  * |       TREE        |<----->|       TREE        |......|       TREE        |
55  * +-------------------+       +-------------------+      +-------------------+
56  *      |         |
57  *      |         |
58  *      |         v
59  *      |     +-------+       +-------+      +-------+
60  *      |     | OFILE |<----->| OFILE |......| OFILE |
61  *      |     +-------+       +-------+      +-------+
62  *      |
63  *      |
64  *      v
65  *  +-------+       +------+      +------+
66  *  | ODIR  |<----->| ODIR |......| ODIR |
67  *  +-------+       +------+      +------+
68  *
69  *
70  * Ofile State Machine
71  * ------------------
72  *
73  *    +-------------------------+	 T0
74  *    |  SMB_OFILE_STATE_OPEN   |<----------- Creation/Allocation
75  *    +-------------------------+
76  *		    |
77  *		    | T1
78  *		    |
79  *		    v
80  *    +-------------------------+
81  *    | SMB_OFILE_STATE_CLOSING |
82  *    +-------------------------+
83  *		    |
84  *		    | T2
85  *		    |
86  *		    v
87  *    +-------------------------+    T3
88  *    | SMB_OFILE_STATE_CLOSED  |----------> Deletion/Free
89  *    +-------------------------+
90  *
91  * SMB_OFILE_STATE_OPEN
92  *
93  *    While in this state:
94  *      - The ofile is queued in the list of ofiles of its tree.
95  *      - References will be given out if the ofile is looked up.
96  *
97  * SMB_OFILE_STATE_CLOSING
98  *
99  *    While in this state:
100  *      - The ofile is queued in the list of ofiles of its tree.
101  *      - References will not be given out if the ofile is looked up.
102  *      - The file is closed and the locks held are being released.
103  *      - The resources associated with the ofile remain.
104  *
105  * SMB_OFILE_STATE_CLOSED
106  *
107  *    While in this state:
108  *      - The ofile is queued in the list of ofiles of its tree.
109  *      - References will not be given out if the ofile is looked up.
110  *      - The resources associated with the ofile remain.
111  *
112  * Transition T0
113  *
114  *    This transition occurs in smb_ofile_open(). A new ofile is created and
115  *    added to the list of ofiles of a tree.
116  *
117  * Transition T1
118  *
119  *    This transition occurs in smb_ofile_close().
120  *
121  * Transition T2
122  *
123  *    This transition occurs in smb_ofile_release(). The resources associated
124  *    with the ofile are freed as well as the ofile structure. For the
125  *    transition to occur, the ofile must be in the SMB_OFILE_STATE_CLOSED
126  *    state and the reference count be zero.
127  *
128  * Comments
129  * --------
130  *
131  *    The state machine of the ofile structures is controlled by 3 elements:
132  *      - The list of ofiles of the tree it belongs to.
133  *      - The mutex embedded in the structure itself.
134  *      - The reference count.
135  *
136  *    There's a mutex embedded in the ofile structure used to protect its fields
137  *    and there's a lock embedded in the list of ofiles of a tree. To
138  *    increment or to decrement the reference count the mutex must be entered.
139  *    To insert the ofile into the list of ofiles of the tree and to remove
140  *    the ofile from it, the lock must be entered in RW_WRITER mode.
141  *
142  *    Rules of access to a ofile structure:
143  *
144  *    1) In order to avoid deadlocks, when both (mutex and lock of the ofile
145  *       list) have to be entered, the lock must be entered first.
146  *
147  *    2) All actions applied to an ofile require a reference count.
148  *
149  *    3) There are 2 ways of getting a reference count. One is when the ofile
150  *       is opened. The other one when the ofile is looked up. This translates
151  *       into 2 functions: smb_ofile_open() and smb_ofile_lookup_by_fid().
152  *
153  *    It should be noted that the reference count of an ofile registers the
154  *    number of references to the ofile in other structures (such as an smb
155  *    request). The reference count is not incremented in these 2 instances:
156  *
157  *    1) The ofile is open. An ofile is anchored by its state. If there's
158  *       no activity involving an ofile currently open, the reference count
159  *       of that ofile is zero.
160  *
161  *    2) The ofile is queued in the list of ofiles of its tree. The fact of
162  *       being queued in that list is NOT registered by incrementing the
163  *       reference count.
164  */
165 #include <smbsrv/smb_kproto.h>
166 #include <smbsrv/smb_fsops.h>
167 
168 static boolean_t smb_ofile_is_open_locked(smb_ofile_t *);
169 static smb_ofile_t *smb_ofile_close_and_next(smb_ofile_t *);
170 static int smb_ofile_netinfo_encode(smb_ofile_t *, uint8_t *, size_t,
171     uint32_t *);
172 static int smb_ofile_netinfo_init(smb_ofile_t *, smb_netfileinfo_t *);
173 static void smb_ofile_netinfo_fini(smb_netfileinfo_t *);
174 
175 /*
176  * smb_ofile_open
177  */
178 smb_ofile_t *
179 smb_ofile_open(
180     smb_request_t	*sr,
181     smb_node_t		*node,
182     struct open_param	*op,
183     uint16_t		ftype,
184     uint32_t		uniqid,
185     smb_error_t		*err)
186 {
187 	smb_tree_t	*tree = sr->tid_tree;
188 	smb_ofile_t	*of;
189 	uint16_t	fid;
190 	smb_attr_t	attr;
191 	int		rc;
192 	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)
518 		return (0);
519 
520 	if (svcenum->se_nskip > 0) {
521 		svcenum->se_nskip--;
522 		return (0);
523 	}
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);
641 
642 	of_list = &tree->t_ofile_list;
643 
644 	smb_llist_enter(of_list, RW_READER);
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 *
685 smb_ofile_lookup_by_uniqid(smb_tree_t *tree, uint32_t uniqid)
686 {
687 	smb_llist_t	*of_list;
688 	smb_ofile_t	*of;
689 
690 	ASSERT(tree->t_magic == SMB_TREE_MAGIC);
691 
692 	of_list = &tree->t_ofile_list;
693 	smb_llist_enter(of_list, RW_READER);
694 	of = smb_llist_head(of_list);
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)
735 			return (B_TRUE);
736 		break;
737 	default:
738 		break;
739 	}
740 
741 	return (B_FALSE);
742 }
743 
744 /*
745  * smb_ofile_set_flags
746  *
747  * Return value:
748  *
749  *	Current flags value
750  *
751  */
752 void
753 smb_ofile_set_flags(
754     smb_ofile_t		*of,
755     uint32_t		flags)
756 {
757 	ASSERT(of);
758 	ASSERT(of->f_magic == SMB_OFILE_MAGIC);
759 	ASSERT(of->f_refcnt);
760 
761 	mutex_enter(&of->f_mutex);
762 	of->f_flags |= flags;
763 	mutex_exit(&of->f_mutex);
764 }
765 
766 /*
767  * smb_ofile_seek
768  *
769  * Return value:
770  *
771  *	0		Success
772  *	EINVAL		Unknown mode
773  *	EOVERFLOW	offset too big
774  *
775  */
776 int
777 smb_ofile_seek(
778     smb_ofile_t		*of,
779     ushort_t		mode,
780     int32_t		off,
781     uint32_t		*retoff)
782 {
783 	u_offset_t	newoff = 0;
784 	int		rc = 0;
785 	smb_attr_t	attr;
786 
787 	ASSERT(of);
788 	ASSERT(of->f_magic == SMB_OFILE_MAGIC);
789 	ASSERT(of->f_refcnt);
790 
791 	mutex_enter(&of->f_mutex);
792 	switch (mode) {
793 	case SMB_SEEK_SET:
794 		if (off < 0)
795 			newoff = 0;
796 		else
797 			newoff = (u_offset_t)off;
798 		break;
799 
800 	case SMB_SEEK_CUR:
801 		if (off < 0 && (-off) > of->f_seek_pos)
802 			newoff = 0;
803 		else
804 			newoff = of->f_seek_pos + (u_offset_t)off;
805 		break;
806 
807 	case SMB_SEEK_END:
808 		bzero(&attr, sizeof (smb_attr_t));
809 		attr.sa_mask |= SMB_AT_SIZE;
810 		rc = smb_fsop_getattr(NULL, zone_kcred(), of->f_node, &attr);
811 		if (rc != 0) {
812 			mutex_exit(&of->f_mutex);
813 			return (rc);
814 		}
815 		if (off < 0 && (-off) > attr.sa_vattr.va_size)
816 			newoff = 0;
817 		else
818 			newoff = attr.sa_vattr.va_size + (u_offset_t)off;
819 		break;
820 
821 	default:
822 		mutex_exit(&of->f_mutex);
823 		return (EINVAL);
824 	}
825 
826 	/*
827 	 * See comments at the beginning of smb_seek.c.
828 	 * If the offset is greater than UINT_MAX, we will return an error.
829 	 */
830 
831 	if (newoff > UINT_MAX) {
832 		rc = EOVERFLOW;
833 	} else {
834 		of->f_seek_pos = newoff;
835 		*retoff = (uint32_t)newoff;
836 	}
837 	mutex_exit(&of->f_mutex);
838 	return (rc);
839 }
840 
841 /*
842  * smb_ofile_flush
843  *
844  * If writes on this file are not synchronous, flush it using the NFSv3
845  * commit interface.
846  *
847  * XXX - todo: Flush named pipe should drain writes.
848  */
849 void
850 smb_ofile_flush(struct smb_request *sr, struct smb_ofile *of)
851 {
852 	switch (of->f_ftype) {
853 	case SMB_FTYPE_DISK:
854 		if ((of->f_node->flags & NODE_FLAGS_WRITE_THROUGH) == 0)
855 			(void) smb_fsop_commit(sr, of->f_cr, of->f_node);
856 		break;
857 	default:
858 		break;
859 	}
860 }
861 
862 /*
863  * smb_ofile_is_open
864  */
865 boolean_t
866 smb_ofile_is_open(smb_ofile_t *of)
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 	 */
1016 	if (~(of->f_granted_access) & access) {
1017 		if (!(of->f_granted_access & ACCESS_SYSTEM_SECURITY) &&
1018 		    (access & ACCESS_SYSTEM_SECURITY)) {
1019 			return (NT_STATUS_PRIVILEGE_NOT_HELD);
1020 		}
1021 		return (NT_STATUS_ACCESS_DENIED);
1022 	}
1023 
1024 	return (NT_STATUS_SUCCESS);
1025 }
1026 
1027 /*
1028  * smb_ofile_share_check
1029  *
1030  * Check if ofile was opened with share access NONE (0).
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);
1234 	}
1235 
1236 	return (rc);
1237 }
1238 
1239 static int
1240 smb_ofile_netinfo_init(smb_ofile_t *of, smb_netfileinfo_t *fi)
1241 {
1242 	smb_user_t	*user;
1243 	smb_tree_t	*tree;
1244 	smb_node_t	*node;
1245 	char		*path;
1246 	char		*buf;
1247 	int		rc;
1248 
1249 	ASSERT(of);
1250 	user = of->f_user;
1251 	tree = of->f_tree;
1252 	ASSERT(user);
1253 	ASSERT(tree);
1254 
1255 	buf = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
1256 
1257 	switch (of->f_ftype) {
1258 	case SMB_FTYPE_DISK:
1259 		node = of->f_node;
1260 		ASSERT(node);
1261 
1262 		fi->fi_permissions = of->f_granted_access;
1263 		fi->fi_numlocks = smb_lock_get_lock_count(node, of);
1264 
1265 		path = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
1266 
1267 		if (node != tree->t_snode) {
1268 			rc = smb_node_getshrpath(node, tree, path, MAXPATHLEN);
1269 			if (rc != 0)
1270 				(void) strlcpy(path, node->od_name, MAXPATHLEN);
1271 		}
1272 
1273 		(void) snprintf(buf, MAXPATHLEN, "%s:%s", tree->t_sharename,
1274 		    path);
1275 		kmem_free(path, MAXPATHLEN);
1276 		break;
1277 
1278 	case SMB_FTYPE_MESG_PIPE:
1279 		ASSERT(of->f_pipe);
1280 
1281 		fi->fi_permissions = FILE_READ_DATA | FILE_WRITE_DATA |
1282 		    FILE_EXECUTE;
1283 		fi->fi_numlocks = 0;
1284 		(void) snprintf(buf, MAXPATHLEN, "\\PIPE\\%s",
1285 		    of->f_pipe->p_name);
1286 		break;
1287 
1288 	default:
1289 		kmem_free(buf, MAXPATHLEN);
1290 		return (-1);
1291 	}
1292 
1293 	fi->fi_fid = of->f_fid;
1294 	fi->fi_uniqid = of->f_uniqid;
1295 	fi->fi_pathlen = strlen(buf) + 1;
1296 	fi->fi_path = smb_mem_strdup(buf);
1297 	kmem_free(buf, MAXPATHLEN);
1298 
1299 	fi->fi_namelen = user->u_domain_len + user->u_name_len + 2;
1300 	fi->fi_username = kmem_alloc(fi->fi_namelen, KM_SLEEP);
1301 	(void) snprintf(fi->fi_username, fi->fi_namelen, "%s\\%s",
1302 	    user->u_domain, user->u_name);
1303 	return (0);
1304 }
1305 
1306 static void
1307 smb_ofile_netinfo_fini(smb_netfileinfo_t *fi)
1308 {
1309 	if (fi == NULL)
1310 		return;
1311 
1312 	if (fi->fi_path)
1313 		smb_mem_free(fi->fi_path);
1314 	if (fi->fi_username)
1315 		kmem_free(fi->fi_username, fi->fi_namelen);
1316 
1317 	bzero(fi, sizeof (smb_netfileinfo_t));
1318 }
1319 
1320 /*
1321  * A query of user and group quotas may span multiple requests.
1322  * f_quota_resume is used to determine where the query should
1323  * be resumed, in a subsequent request. f_quota_resume contains
1324  * the SID of the last quota entry returned to the client.
1325  */
1326 void
1327 smb_ofile_set_quota_resume(smb_ofile_t *ofile, char *resume)
1328 {
1329 	ASSERT(ofile);
1330 	mutex_enter(&ofile->f_mutex);
1331 	if (resume == NULL)
1332 		bzero(ofile->f_quota_resume, SMB_SID_STRSZ);
1333 	else
1334 		(void) strlcpy(ofile->f_quota_resume, resume, SMB_SID_STRSZ);
1335 	mutex_exit(&ofile->f_mutex);
1336 }
1337 
1338 void
1339 smb_ofile_get_quota_resume(smb_ofile_t *ofile, char *buf, int bufsize)
1340 {
1341 	ASSERT(ofile);
1342 	mutex_enter(&ofile->f_mutex);
1343 	(void) strlcpy(buf, ofile->f_quota_resume, bufsize);
1344 	mutex_exit(&ofile->f_mutex);
1345 }
1346