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 }