xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_server.c (revision 61dfa5098dc8576d9a5e277deba6df647bb70c06)
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) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
23  * Copyright (c) 2017 by Delphix. All rights reserved.
24  * Copyright 2019 Nexenta by DDN, Inc. All rights reserved.
25  */
26 
27 /*
28  * General Structures Layout
29  * -------------------------
30  *
31  * This is a simplified diagram showing the relationship between most of the
32  * main structures.
33  *
34  * +-------------------+
35  * |     SMB_SERVER    |
36  * +-------------------+
37  *          |
38  *          |
39  *          v
40  * +-------------------+       +-------------------+      +-------------------+
41  * |     SESSION       |<----->|     SESSION       |......|      SESSION      |
42  * +-------------------+       +-------------------+      +-------------------+
43  *          |
44  *          |
45  *          v
46  * +-------------------+       +-------------------+      +-------------------+
47  * |       USER        |<----->|       USER        |......|       USER        |
48  * +-------------------+       +-------------------+      +-------------------+
49  *          |
50  *          |
51  *          v
52  * +-------------------+       +-------------------+      +-------------------+
53  * |       TREE        |<----->|       TREE        |......|       TREE        |
54  * +-------------------+       +-------------------+      +-------------------+
55  *      |         |
56  *      |         |
57  *      |         v
58  *      |     +-------+       +-------+      +-------+
59  *      |     | OFILE |<----->| OFILE |......| OFILE |
60  *      |     +-------+       +-------+      +-------+
61  *      |
62  *      |
63  *      v
64  *  +-------+       +------+      +------+
65  *  | ODIR  |<----->| ODIR |......| ODIR |
66  *  +-------+       +------+      +------+
67  *
68  *
69  * Module Interface Overview
70  * -------------------------
71  *
72  *
73  *	    +===================================+
74  *	    |		 smbd daemon		|
75  *	    +===================================+
76  *	      |		     |		      ^
77  *	      |		     |		      |
78  * User	      |		     |		      |
79  * -----------|--------------|----------------|--------------------------------
80  * Kernel     |		     |		      |
81  *            |		     |		      |
82  *	      |		     |		      |
83  *  +=========|==============|================|=================+
84  *  |	      v		     v		      |			|
85  *  | +-----------+ +--------------------+ +------------------+ |
86  *  | |     IO    | | Kernel Door Server | | User Door Servers|	|
87  *  | | Interface | |     Interface      | |   Interface      | |
88  *  | +-----------+ +--------------------+ +------------------+ |
89  *  |		|	     |		      ^		^	|
90  *  |		v	     v		      |		|	|    +=========+
91  *  |	     +-----------------------------------+	|	|    |	       |
92  *  |	     + SMB Server Management (this file) |<------------------|	 ZFS   |
93  *  |	     +-----------------------------------+	|	|    |	       |
94  *  |							|	|    |  Module |
95  *  |	     +-----------------------------------+	|	|    |	       |
96  *  |	     +     SMB Server Internal Layers    |------+	|    +=========+
97  *  |	     +-----------------------------------+		|
98  *  |								|
99  *  |								|
100  *  +===========================================================+
101  *
102  *
103  * Server State Machine
104  * --------------------
105  *                                  |
106  *                                  | T0
107  *                                  |
108  *                                  v
109  *                    +-----------------------------+
110  *		      |   SMB_SERVER_STATE_CREATED  |
111  *		      +-----------------------------+
112  *				    |
113  *				    | T1
114  *				    |
115  *				    v
116  *		      +-----------------------------+
117  *		      | SMB_SERVER_STATE_CONFIGURED |
118  *		      +-----------------------------+
119  *				    |
120  *				    | T2
121  *				    |
122  *				    v
123  *		      +-----------------------------+
124  *		      |  SMB_SERVER_STATE_RUNNING / |
125  *		      |  SMB_SERVER_STATE_STOPPING  |
126  *		      +-----------------------------+
127  *				    |
128  *				    | T3
129  *				    |
130  *				    v
131  *		      +-----------------------------+
132  *		      |  SMB_SERVER_STATE_DELETING  |
133  *                    +-----------------------------+
134  *				    |
135  *				    |
136  *				    |
137  *				    v
138  *
139  * States
140  * ------
141  *
142  * SMB_SERVER_STATE_CREATED
143  *
144  *    This is the state of the server just after creation.
145  *
146  * SMB_SERVER_STATE_CONFIGURED
147  *
148  *    The server has been configured.
149  *
150  * SMB_SERVER_STATE_RUNNING
151  *
152  *    The server has been started. While in this state the threads listening on
153  *    the sockets are started.
154  *
155  *    When a client establishes a connection the thread listening dispatches
156  *    a task with the new session as an argument. If the dispatch fails the new
157  *    session context is destroyed.
158  *
159  * SMB_SERVER_STATE_STOPPING
160  *
161  *    The threads listening on the NBT and TCP sockets are being terminated.
162  *
163  *
164  * Transitions
165  * -----------
166  *
167  * Transition T0
168  *
169  *    The daemon smbd triggers its creation by opening the smbsrv device. If
170  *    the zone where the daemon lives doesn't have an smb server yet it is
171  *    created.
172  *
173  *		smb_drv_open() --> smb_server_create()
174  *
175  * Transition T1
176  *
177  *    This transition occurs in smb_server_configure(). It is triggered by the
178  *    daemon through an Ioctl.
179  *
180  *	smb_drv_ioctl(SMB_IOC_CONFIG) --> smb_server_configure()
181  *
182  * Transition T2
183  *
184  *    This transition occurs in smb_server_start(). It is triggered by the
185  *    daemon through an Ioctl.
186  *
187  *	smb_drv_ioctl(SMB_IOC_START) --> smb_server_start()
188  *
189  * Transition T3
190  *
191  *    This transition occurs in smb_server_delete(). It is triggered by the
192  *    daemon when closing the smbsrv device
193  *
194  *		smb_drv_close() --> smb_server_delete()
195  *
196  * Comments
197  * --------
198  *
199  * This files assumes that there will one SMB server per zone. For now the
200  * smb server works only in global zone. There's nothing in this file preventing
201  * an smb server from being created in a non global zone. That limitation is
202  * enforced in user space.
203  */
204 
205 #include <sys/cmn_err.h>
206 #include <sys/priv.h>
207 #include <sys/zone.h>
208 #include <netinet/in.h>
209 #include <netinet/in_systm.h>
210 #include <netinet/ip.h>
211 #include <netinet/ip_icmp.h>
212 #include <netinet/ip_var.h>
213 #include <netinet/tcp.h>
214 #include <smbsrv/smb2_kproto.h>
215 #include <smbsrv/string.h>
216 #include <smbsrv/netbios.h>
217 #include <smbsrv/smb_fsops.h>
218 #include <smbsrv/smb_share.h>
219 #include <smbsrv/smb_door.h>
220 #include <smbsrv/smb_kstat.h>
221 
222 static void smb_server_kstat_init(smb_server_t *);
223 static void smb_server_kstat_fini(smb_server_t *);
224 static void smb_server_timers(smb_thread_t *, void *);
225 static void smb_server_store_cfg(smb_server_t *, smb_ioc_cfg_t *);
226 static void smb_server_shutdown(smb_server_t *);
227 static int smb_server_fsop_start(smb_server_t *);
228 static void smb_server_fsop_stop(smb_server_t *);
229 static void smb_event_cancel(smb_server_t *, uint32_t);
230 static uint32_t smb_event_alloc_txid(void);
231 
232 static void smb_server_disconnect_share(smb_server_t *, const char *);
233 static void smb_server_enum_users(smb_server_t *, smb_svcenum_t *);
234 static void smb_server_enum_trees(smb_server_t *, smb_svcenum_t *);
235 static int smb_server_session_disconnect(smb_server_t *, const char *,
236     const char *);
237 static int smb_server_fclose(smb_server_t *, uint32_t);
238 static int smb_server_kstat_update(kstat_t *, int);
239 static int smb_server_legacy_kstat_update(kstat_t *, int);
240 static void smb_server_listener_init(smb_server_t *, smb_listener_daemon_t *,
241     char *, in_port_t, int);
242 static void smb_server_listener_destroy(smb_listener_daemon_t *);
243 static int smb_server_listener_start(smb_listener_daemon_t *);
244 static void smb_server_listener_stop(smb_listener_daemon_t *);
245 static void smb_server_listener(smb_thread_t *, void *);
246 static void smb_server_receiver(void *);
247 static void smb_server_create_session(smb_listener_daemon_t *, ksocket_t);
248 static void smb_server_destroy_session(smb_session_t *);
249 static uint16_t smb_spool_get_fid(smb_server_t *);
250 static boolean_t smb_spool_lookup_doc_byfid(smb_server_t *, uint16_t,
251     smb_kspooldoc_t *);
252 
253 /*
254  * How many "buckets" should our hash tables use?  On a "real" server,
255  * make them much larger than the number of CPUs we're likely to have.
256  * On "fksmbd" make it smaller so dtrace logs are shorter.
257  * These must be powers of two.
258  */
259 #ifdef	_KERNEL
260 #define	DEFAULT_HASH_NBUCKETS	256	/* real server */
261 #else
262 #define	DEFAULT_HASH_NBUCKETS	16	/* for "fksmbd" */
263 #endif
264 uint32_t SMB_OFILE_HASH_NBUCKETS = DEFAULT_HASH_NBUCKETS;
265 uint32_t SMB_LEASE_HASH_NBUCKETS = DEFAULT_HASH_NBUCKETS;
266 
267 int smb_event_debug = 0;
268 
269 static smb_llist_t	smb_servers;
270 
271 kmem_cache_t		*smb_cache_request;
272 kmem_cache_t		*smb_cache_session;
273 kmem_cache_t		*smb_cache_user;
274 kmem_cache_t		*smb_cache_tree;
275 kmem_cache_t		*smb_cache_ofile;
276 kmem_cache_t		*smb_cache_odir;
277 kmem_cache_t		*smb_cache_opipe;
278 kmem_cache_t		*smb_cache_event;
279 kmem_cache_t		*smb_cache_lock;
280 
281 /*
282  * *****************************************************************************
283  * **************** Functions called from the device interface *****************
284  * *****************************************************************************
285  *
286  * These functions typically have to determine the relevant smb server
287  * to which the call applies.
288  */
289 
290 /*
291  * How many zones have an SMB server active?
292  */
293 int
294 smb_server_get_count(void)
295 {
296 	return (smb_llist_get_count(&smb_servers));
297 }
298 
299 /*
300  * smb_server_g_init
301  *
302  * This function must be called from smb_drv_attach().
303  */
304 int
305 smb_server_g_init(void)
306 {
307 	int rc;
308 
309 	if ((rc = smb_vop_init()) != 0)
310 		goto errout;
311 	if ((rc = smb_fem_init()) != 0)
312 		goto errout;
313 
314 	smb_kshare_g_init();
315 	smb_codepage_init();
316 	smb_mbc_init();		/* smb_mbc_cache */
317 	smb_node_init();	/* smb_node_cache, lists */
318 	smb2_lease_init();
319 
320 	smb_cache_request = kmem_cache_create("smb_request_cache",
321 	    sizeof (smb_request_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
322 	smb_cache_session = kmem_cache_create("smb_session_cache",
323 	    sizeof (smb_session_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
324 	smb_cache_user = kmem_cache_create("smb_user_cache",
325 	    sizeof (smb_user_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
326 	smb_cache_tree = kmem_cache_create("smb_tree_cache",
327 	    sizeof (smb_tree_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
328 	smb_cache_ofile = kmem_cache_create("smb_ofile_cache",
329 	    sizeof (smb_ofile_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
330 	smb_cache_odir = kmem_cache_create("smb_odir_cache",
331 	    sizeof (smb_odir_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
332 	smb_cache_opipe = kmem_cache_create("smb_opipe_cache",
333 	    sizeof (smb_opipe_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
334 	smb_cache_event = kmem_cache_create("smb_event_cache",
335 	    sizeof (smb_event_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
336 	smb_cache_lock = kmem_cache_create("smb_lock_cache",
337 	    sizeof (smb_lock_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
338 
339 	smb_llist_init();
340 	smb_llist_constructor(&smb_servers, sizeof (smb_server_t),
341 	    offsetof(smb_server_t, sv_lnd));
342 
343 	return (0);
344 
345 errout:
346 	smb_fem_fini();
347 	smb_vop_fini();
348 	return (rc);
349 }
350 
351 /*
352  * smb_server_g_fini
353  *
354  * This function must called from smb_drv_detach(). It will fail if servers
355  * still exist.
356  */
357 void
358 smb_server_g_fini(void)
359 {
360 
361 	ASSERT(smb_llist_get_count(&smb_servers) == 0);
362 
363 	smb_llist_fini();
364 
365 	kmem_cache_destroy(smb_cache_request);
366 	kmem_cache_destroy(smb_cache_session);
367 	kmem_cache_destroy(smb_cache_user);
368 	kmem_cache_destroy(smb_cache_tree);
369 	kmem_cache_destroy(smb_cache_ofile);
370 	kmem_cache_destroy(smb_cache_odir);
371 	kmem_cache_destroy(smb_cache_opipe);
372 	kmem_cache_destroy(smb_cache_event);
373 	kmem_cache_destroy(smb_cache_lock);
374 
375 	smb2_lease_fini();
376 	smb_node_fini();
377 	smb_mbc_fini();
378 	smb_codepage_fini();
379 	smb_kshare_g_fini();
380 
381 	smb_fem_fini();
382 	smb_vop_fini();
383 
384 	smb_llist_destructor(&smb_servers);
385 }
386 
387 /*
388  * smb_server_create
389  *
390  * This function will fail if there's already a server associated with the
391  * caller's zone.
392  */
393 int
394 smb_server_create(void)
395 {
396 	zoneid_t	zid;
397 	smb_server_t	*sv;
398 
399 	zid = getzoneid();
400 
401 	smb_llist_enter(&smb_servers, RW_WRITER);
402 	sv = smb_llist_head(&smb_servers);
403 	while (sv) {
404 		SMB_SERVER_VALID(sv);
405 		if (sv->sv_zid == zid) {
406 			smb_llist_exit(&smb_servers);
407 			return (EPERM);
408 		}
409 		sv = smb_llist_next(&smb_servers, sv);
410 	}
411 
412 	sv = kmem_zalloc(sizeof (smb_server_t), KM_SLEEP);
413 
414 	sv->sv_magic = SMB_SERVER_MAGIC;
415 	sv->sv_state = SMB_SERVER_STATE_CREATED;
416 	sv->sv_zid = zid;
417 	sv->sv_pid = ddi_get_pid();
418 
419 	mutex_init(&sv->sv_mutex, NULL, MUTEX_DEFAULT, NULL);
420 	cv_init(&sv->sv_cv, NULL, CV_DEFAULT, NULL);
421 	cv_init(&sv->sp_info.sp_cv, NULL, CV_DEFAULT, NULL);
422 
423 	sv->sv_persistid_ht = smb_hash_create(sizeof (smb_ofile_t),
424 	    offsetof(smb_ofile_t, f_dh_lnd), SMB_OFILE_HASH_NBUCKETS);
425 
426 	sv->sv_lease_ht = smb_hash_create(sizeof (smb_lease_t),
427 	    offsetof(smb_lease_t, ls_lnd), SMB_LEASE_HASH_NBUCKETS);
428 
429 	smb_llist_constructor(&sv->sv_session_list, sizeof (smb_session_t),
430 	    offsetof(smb_session_t, s_lnd));
431 
432 	smb_llist_constructor(&sv->sv_event_list, sizeof (smb_event_t),
433 	    offsetof(smb_event_t, se_lnd));
434 
435 	smb_llist_constructor(&sv->sp_info.sp_list, sizeof (smb_kspooldoc_t),
436 	    offsetof(smb_kspooldoc_t, sd_lnd));
437 
438 	smb_llist_constructor(&sv->sp_info.sp_fidlist,
439 	    sizeof (smb_spoolfid_t), offsetof(smb_spoolfid_t, sf_lnd));
440 
441 	sv->sv_disp_stats1 = kmem_zalloc(SMB_COM_NUM *
442 	    sizeof (smb_disp_stats_t), KM_SLEEP);
443 
444 	sv->sv_disp_stats2 = kmem_zalloc(SMB2__NCMDS *
445 	    sizeof (smb_disp_stats_t), KM_SLEEP);
446 
447 	smb_thread_init(&sv->si_thread_timers, "smb_timers",
448 	    smb_server_timers, sv, smbsrv_timer_pri);
449 
450 	smb_srqueue_init(&sv->sv_srqueue);
451 
452 	smb_kdoor_init(sv);
453 	smb_kshare_init(sv);
454 	smb_server_kstat_init(sv);
455 
456 	smb_threshold_init(&sv->sv_ssetup_ct, SMB_SSETUP_CMD,
457 	    smb_ssetup_threshold, smb_ssetup_timeout);
458 	smb_threshold_init(&sv->sv_tcon_ct, SMB_TCON_CMD,
459 	    smb_tcon_threshold, smb_tcon_timeout);
460 	smb_threshold_init(&sv->sv_opipe_ct, SMB_OPIPE_CMD,
461 	    smb_opipe_threshold, smb_opipe_timeout);
462 
463 	smb_llist_insert_tail(&smb_servers, sv);
464 	smb_llist_exit(&smb_servers);
465 
466 	return (0);
467 }
468 
469 /*
470  * smb_server_delete
471  *
472  * This function will delete the server passed in. It will make sure that all
473  * activity associated that server has ceased before destroying it.
474  */
475 int
476 smb_server_delete(smb_server_t	*sv)
477 {
478 
479 	mutex_enter(&sv->sv_mutex);
480 	switch (sv->sv_state) {
481 	case SMB_SERVER_STATE_RUNNING:
482 		sv->sv_state = SMB_SERVER_STATE_STOPPING;
483 		mutex_exit(&sv->sv_mutex);
484 		smb_server_shutdown(sv);
485 		mutex_enter(&sv->sv_mutex);
486 		cv_broadcast(&sv->sp_info.sp_cv);
487 		sv->sv_state = SMB_SERVER_STATE_DELETING;
488 		break;
489 	case SMB_SERVER_STATE_STOPPING:
490 		sv->sv_state = SMB_SERVER_STATE_DELETING;
491 		break;
492 	case SMB_SERVER_STATE_CONFIGURED:
493 	case SMB_SERVER_STATE_CREATED:
494 		sv->sv_state = SMB_SERVER_STATE_DELETING;
495 		break;
496 	default:
497 		SMB_SERVER_STATE_VALID(sv->sv_state);
498 		mutex_exit(&sv->sv_mutex);
499 		smb_server_release(sv);
500 		return (ENOTTY);
501 	}
502 
503 	ASSERT(sv->sv_state == SMB_SERVER_STATE_DELETING);
504 
505 	sv->sv_refcnt--;
506 	while (sv->sv_refcnt)
507 		cv_wait(&sv->sv_cv, &sv->sv_mutex);
508 
509 	mutex_exit(&sv->sv_mutex);
510 
511 	smb_llist_enter(&smb_servers, RW_WRITER);
512 	smb_llist_remove(&smb_servers, sv);
513 	smb_llist_exit(&smb_servers);
514 
515 	smb_threshold_fini(&sv->sv_ssetup_ct);
516 	smb_threshold_fini(&sv->sv_tcon_ct);
517 	smb_threshold_fini(&sv->sv_opipe_ct);
518 
519 	smb_server_listener_destroy(&sv->sv_nbt_daemon);
520 	smb_server_listener_destroy(&sv->sv_tcp_daemon);
521 	rw_destroy(&sv->sv_cfg_lock);
522 	smb_server_kstat_fini(sv);
523 	smb_kshare_fini(sv);
524 	smb_kdoor_fini(sv);
525 	smb_llist_destructor(&sv->sv_event_list);
526 	smb_llist_destructor(&sv->sv_session_list);
527 
528 	kmem_free(sv->sv_disp_stats1,
529 	    SMB_COM_NUM * sizeof (smb_disp_stats_t));
530 
531 	kmem_free(sv->sv_disp_stats2,
532 	    SMB2__NCMDS * sizeof (smb_disp_stats_t));
533 
534 	smb_srqueue_destroy(&sv->sv_srqueue);
535 	smb_thread_destroy(&sv->si_thread_timers);
536 
537 	mutex_destroy(&sv->sv_mutex);
538 	smb_hash_destroy(sv->sv_lease_ht);
539 	smb_hash_destroy(sv->sv_persistid_ht);
540 	cv_destroy(&sv->sv_cv);
541 	sv->sv_magic = 0;
542 	kmem_free(sv, sizeof (smb_server_t));
543 
544 	return (0);
545 }
546 
547 /*
548  * smb_server_configure
549  */
550 int
551 smb_server_configure(smb_ioc_cfg_t *ioc)
552 {
553 	int		rc = 0;
554 	smb_server_t	*sv;
555 
556 	/*
557 	 * Reality check negotiation token length vs. #define'd maximum.
558 	 */
559 	if (ioc->negtok_len > SMB_PI_MAX_NEGTOK)
560 		return (EINVAL);
561 
562 	rc = smb_server_lookup(&sv);
563 	if (rc)
564 		return (rc);
565 
566 	mutex_enter(&sv->sv_mutex);
567 	switch (sv->sv_state) {
568 	case SMB_SERVER_STATE_CREATED:
569 		smb_server_store_cfg(sv, ioc);
570 		sv->sv_state = SMB_SERVER_STATE_CONFIGURED;
571 		break;
572 
573 	case SMB_SERVER_STATE_CONFIGURED:
574 		smb_server_store_cfg(sv, ioc);
575 		break;
576 
577 	case SMB_SERVER_STATE_RUNNING:
578 	case SMB_SERVER_STATE_STOPPING:
579 		rw_enter(&sv->sv_cfg_lock, RW_WRITER);
580 		smb_server_store_cfg(sv, ioc);
581 		rw_exit(&sv->sv_cfg_lock);
582 		break;
583 
584 	default:
585 		SMB_SERVER_STATE_VALID(sv->sv_state);
586 		rc = EFAULT;
587 		break;
588 	}
589 	mutex_exit(&sv->sv_mutex);
590 
591 	smb_server_release(sv);
592 
593 	return (rc);
594 }
595 
596 /*
597  * smb_server_start
598  */
599 int
600 smb_server_start(smb_ioc_start_t *ioc)
601 {
602 	int		rc = 0;
603 	int		family;
604 	smb_server_t	*sv;
605 	cred_t		*ucr;
606 
607 	rc = smb_server_lookup(&sv);
608 	if (rc)
609 		return (rc);
610 
611 	mutex_enter(&sv->sv_mutex);
612 	switch (sv->sv_state) {
613 	case SMB_SERVER_STATE_CONFIGURED:
614 
615 		if ((rc = smb_server_fsop_start(sv)) != 0)
616 			break;
617 
618 		/*
619 		 * Note: smb_kshare_start needs sv_session.
620 		 */
621 		sv->sv_session = smb_session_create(NULL, 0, sv, 0);
622 		if (sv->sv_session == NULL) {
623 			rc = ENOMEM;
624 			break;
625 		}
626 
627 		/*
628 		 * Create a logon on the server session,
629 		 * used when importing CA shares.
630 		 */
631 		sv->sv_rootuser = smb_user_new(sv->sv_session);
632 		ucr = smb_kcred_create();
633 		rc = smb_user_logon(sv->sv_rootuser, ucr, "", "root",
634 		    SMB_USER_FLAG_ADMIN, 0, 0);
635 		crfree(ucr);
636 		ucr = NULL;
637 		if (rc != 0) {
638 			cmn_err(CE_NOTE, "smb_server_start: "
639 			    "failed to create root user");
640 			break;
641 		}
642 
643 		if ((rc = smb_kshare_start(sv)) != 0)
644 			break;
645 
646 		/*
647 		 * NB: the proc passed here has to be a "system" one.
648 		 * Normally that's p0, or the NGZ eqivalent.
649 		 */
650 		sv->sv_worker_pool = taskq_create_proc("smb_workers",
651 		    sv->sv_cfg.skc_maxworkers, smbsrv_worker_pri,
652 		    sv->sv_cfg.skc_maxworkers, INT_MAX,
653 		    curzone->zone_zsched, TASKQ_DYNAMIC);
654 
655 		sv->sv_receiver_pool = taskq_create_proc("smb_receivers",
656 		    sv->sv_cfg.skc_maxconnections, smbsrv_receive_pri,
657 		    sv->sv_cfg.skc_maxconnections, INT_MAX,
658 		    curzone->zone_zsched, TASKQ_DYNAMIC);
659 
660 		if (sv->sv_worker_pool == NULL ||
661 		    sv->sv_receiver_pool == NULL) {
662 			rc = ENOMEM;
663 			break;
664 		}
665 
666 #ifdef	_KERNEL
667 		ASSERT(sv->sv_lmshrd == NULL);
668 		sv->sv_lmshrd = smb_kshare_door_init(ioc->lmshrd);
669 		if (sv->sv_lmshrd == NULL)
670 			break;
671 		if ((rc = smb_kdoor_open(sv, ioc->udoor)) != 0) {
672 			cmn_err(CE_WARN, "Cannot open smbd door");
673 			break;
674 		}
675 #else	/* _KERNEL */
676 		/* Fake kernel does not use the kshare_door */
677 		fksmb_kdoor_open(sv, ioc->udoor_func);
678 #endif	/* _KERNEL */
679 
680 		if ((rc = smb_thread_start(&sv->si_thread_timers)) != 0)
681 			break;
682 
683 		family = AF_INET;
684 		smb_server_listener_init(sv, &sv->sv_nbt_daemon,
685 		    "smb_nbt_listener", IPPORT_NETBIOS_SSN, family);
686 		if (sv->sv_cfg.skc_ipv6_enable)
687 			family = AF_INET6;
688 		smb_server_listener_init(sv, &sv->sv_tcp_daemon,
689 		    "smb_tcp_listener", IPPORT_SMB, family);
690 		rc = smb_server_listener_start(&sv->sv_tcp_daemon);
691 		if (rc != 0)
692 			break;
693 		if (sv->sv_cfg.skc_netbios_enable)
694 			(void) smb_server_listener_start(&sv->sv_nbt_daemon);
695 
696 		sv->sv_state = SMB_SERVER_STATE_RUNNING;
697 		sv->sv_start_time = gethrtime();
698 		mutex_exit(&sv->sv_mutex);
699 		smb_server_release(sv);
700 		smb_export_start(sv);
701 		return (0);
702 	default:
703 		SMB_SERVER_STATE_VALID(sv->sv_state);
704 		mutex_exit(&sv->sv_mutex);
705 		smb_server_release(sv);
706 		return (ENOTTY);
707 	}
708 
709 	mutex_exit(&sv->sv_mutex);
710 	smb_server_shutdown(sv);
711 	smb_server_release(sv);
712 	return (rc);
713 }
714 
715 /*
716  * An smbd is shutting down.
717  */
718 int
719 smb_server_stop(void)
720 {
721 	smb_server_t	*sv;
722 	int		rc;
723 
724 	if ((rc = smb_server_lookup(&sv)) != 0)
725 		return (rc);
726 
727 	mutex_enter(&sv->sv_mutex);
728 	switch (sv->sv_state) {
729 	case SMB_SERVER_STATE_RUNNING:
730 		sv->sv_state = SMB_SERVER_STATE_STOPPING;
731 		mutex_exit(&sv->sv_mutex);
732 		smb_server_shutdown(sv);
733 		mutex_enter(&sv->sv_mutex);
734 		cv_broadcast(&sv->sp_info.sp_cv);
735 		break;
736 	default:
737 		SMB_SERVER_STATE_VALID(sv->sv_state);
738 		break;
739 	}
740 	mutex_exit(&sv->sv_mutex);
741 
742 	smb_server_release(sv);
743 	return (0);
744 }
745 
746 boolean_t
747 smb_server_is_stopping(smb_server_t *sv)
748 {
749 	boolean_t	status;
750 
751 	SMB_SERVER_VALID(sv);
752 
753 	mutex_enter(&sv->sv_mutex);
754 
755 	switch (sv->sv_state) {
756 	case SMB_SERVER_STATE_STOPPING:
757 	case SMB_SERVER_STATE_DELETING:
758 		status = B_TRUE;
759 		break;
760 	default:
761 		status = B_FALSE;
762 		break;
763 	}
764 
765 	mutex_exit(&sv->sv_mutex);
766 	return (status);
767 }
768 
769 void
770 smb_server_cancel_event(smb_server_t *sv, uint32_t txid)
771 {
772 	smb_event_cancel(sv, txid);
773 }
774 
775 int
776 smb_server_notify_event(smb_ioc_event_t *ioc)
777 {
778 	smb_server_t	*sv;
779 	int		rc;
780 
781 	if ((rc = smb_server_lookup(&sv)) == 0) {
782 		smb_event_notify(sv, ioc->txid);
783 		smb_server_release(sv);
784 	}
785 
786 	return (rc);
787 }
788 
789 /*
790  * smb_server_spooldoc
791  *
792  * Waits for print file close broadcast.
793  * Gets the head of the fid list,
794  * then searches the spooldoc list and returns
795  * this info via the ioctl to user land.
796  *
797  * rc - 0 success
798  */
799 
800 int
801 smb_server_spooldoc(smb_ioc_spooldoc_t *ioc)
802 {
803 	smb_server_t	*sv;
804 	int		rc;
805 	smb_kspooldoc_t *spdoc;
806 	uint16_t	fid;
807 
808 	if ((rc = smb_server_lookup(&sv)) != 0)
809 		return (rc);
810 
811 	if (sv->sv_cfg.skc_print_enable == 0) {
812 		rc = ENOTTY;
813 		goto out;
814 	}
815 
816 	mutex_enter(&sv->sv_mutex);
817 	for (;;) {
818 		if (sv->sv_state != SMB_SERVER_STATE_RUNNING) {
819 			rc = ECANCELED;
820 			break;
821 		}
822 		if ((fid = smb_spool_get_fid(sv)) != 0) {
823 			rc = 0;
824 			break;
825 		}
826 		if (cv_wait_sig(&sv->sp_info.sp_cv, &sv->sv_mutex) == 0) {
827 			rc = EINTR;
828 			break;
829 		}
830 	}
831 	mutex_exit(&sv->sv_mutex);
832 	if (rc != 0)
833 		goto out;
834 
835 	spdoc = kmem_zalloc(sizeof (*spdoc), KM_SLEEP);
836 	if (smb_spool_lookup_doc_byfid(sv, fid, spdoc)) {
837 		ioc->spool_num = spdoc->sd_spool_num;
838 		ioc->ipaddr = spdoc->sd_ipaddr;
839 		(void) strlcpy(ioc->path, spdoc->sd_path,
840 		    MAXPATHLEN);
841 		(void) strlcpy(ioc->username,
842 		    spdoc->sd_username, MAXNAMELEN);
843 	} else {
844 		/* Did not find that print job. */
845 		rc = EAGAIN;
846 	}
847 	kmem_free(spdoc, sizeof (*spdoc));
848 
849 out:
850 	smb_server_release(sv);
851 	return (rc);
852 }
853 
854 int
855 smb_server_set_gmtoff(smb_ioc_gmt_t *ioc)
856 {
857 	int		rc;
858 	smb_server_t	*sv;
859 
860 	if ((rc = smb_server_lookup(&sv)) == 0) {
861 		sv->si_gmtoff = ioc->offset;
862 		smb_server_release(sv);
863 	}
864 
865 	return (rc);
866 }
867 
868 int
869 smb_server_numopen(smb_ioc_opennum_t *ioc)
870 {
871 	smb_server_t	*sv;
872 	int		rc;
873 
874 	if ((rc = smb_server_lookup(&sv)) == 0) {
875 		ioc->open_users = sv->sv_users;
876 		ioc->open_trees = sv->sv_trees;
877 		ioc->open_files = sv->sv_files + sv->sv_pipes;
878 		smb_server_release(sv);
879 	}
880 	return (rc);
881 }
882 
883 /*
884  * Enumerate objects within the server.  The svcenum provides the
885  * enumeration context, i.e. what the caller want to get back.
886  */
887 int
888 smb_server_enum(smb_ioc_svcenum_t *ioc)
889 {
890 	smb_svcenum_t	*svcenum = &ioc->svcenum;
891 	smb_server_t	*sv;
892 	int		rc;
893 
894 	/*
895 	 * Reality check that the buffer-length insize the enum doesn't
896 	 * overrun the ioctl's total length.
897 	 */
898 	if (svcenum->se_buflen + sizeof (*ioc) > ioc->hdr.len)
899 		return (EINVAL);
900 
901 	if ((rc = smb_server_lookup(&sv)) != 0)
902 		return (rc);
903 
904 	svcenum->se_bavail = svcenum->se_buflen;
905 	svcenum->se_bused = 0;
906 	svcenum->se_nitems = 0;
907 
908 	switch (svcenum->se_type) {
909 	case SMB_SVCENUM_TYPE_USER:
910 		smb_server_enum_users(sv, svcenum);
911 		break;
912 	case SMB_SVCENUM_TYPE_TREE:
913 	case SMB_SVCENUM_TYPE_FILE:
914 		smb_server_enum_trees(sv, svcenum);
915 		break;
916 	default:
917 		rc = EINVAL;
918 	}
919 
920 	smb_server_release(sv);
921 	return (rc);
922 }
923 
924 /*
925  * Look for sessions to disconnect by client and user name.
926  */
927 int
928 smb_server_session_close(smb_ioc_session_t *ioc)
929 {
930 	smb_server_t	*sv;
931 	int		cnt;
932 	int		rc;
933 
934 	if ((rc = smb_server_lookup(&sv)) != 0)
935 		return (rc);
936 
937 	cnt = smb_server_session_disconnect(sv, ioc->client, ioc->username);
938 
939 	smb_server_release(sv);
940 
941 	if (cnt == 0)
942 		return (ENOENT);
943 	return (0);
944 }
945 
946 /*
947  * Close a file by uniqid.
948  */
949 int
950 smb_server_file_close(smb_ioc_fileid_t *ioc)
951 {
952 	uint32_t	uniqid = ioc->uniqid;
953 	smb_server_t	*sv;
954 	int		rc;
955 
956 	if ((rc = smb_server_lookup(&sv)) != 0)
957 		return (rc);
958 
959 	rc = smb_server_fclose(sv, uniqid);
960 
961 	smb_server_release(sv);
962 	return (rc);
963 }
964 
965 /*
966  * These functions determine the relevant smb server to which the call apply.
967  */
968 
969 uint32_t
970 smb_server_get_session_count(smb_server_t *sv)
971 {
972 	uint32_t	counter = 0;
973 
974 	counter = smb_llist_get_count(&sv->sv_session_list);
975 
976 	return (counter);
977 }
978 
979 /*
980  * Gets the smb_node of the specified share path.
981  * Node is returned held (caller must rele.)
982  */
983 int
984 smb_server_share_lookup(smb_server_t *sv, const char *shr_path,
985     smb_node_t **nodepp)
986 {
987 	smb_request_t	*sr;
988 	smb_node_t	*fnode = NULL;
989 	smb_node_t	*dnode = NULL;
990 	char		last_comp[MAXNAMELEN];
991 	int		rc = 0;
992 
993 	ASSERT(shr_path);
994 
995 	mutex_enter(&sv->sv_mutex);
996 	switch (sv->sv_state) {
997 	case SMB_SERVER_STATE_RUNNING:
998 		break;
999 	default:
1000 		mutex_exit(&sv->sv_mutex);
1001 		return (ENOTACTIVE);
1002 	}
1003 	mutex_exit(&sv->sv_mutex);
1004 
1005 	if ((sr = smb_request_alloc(sv->sv_session, 0)) == NULL) {
1006 		return (ENOTCONN);
1007 	}
1008 	sr->user_cr = zone_kcred();
1009 
1010 	rc = smb_pathname_reduce(sr, sr->user_cr, shr_path,
1011 	    NULL, NULL, &dnode, last_comp);
1012 
1013 	if (rc == 0) {
1014 		rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
1015 		    sv->si_root_smb_node, dnode, last_comp, &fnode);
1016 		smb_node_release(dnode);
1017 	}
1018 
1019 	smb_request_free(sr);
1020 
1021 	if (rc != 0)
1022 		return (rc);
1023 
1024 	ASSERT(fnode->vp && fnode->vp->v_vfsp);
1025 
1026 	*nodepp = fnode;
1027 
1028 	return (0);
1029 }
1030 
1031 #ifdef	_KERNEL
1032 /*
1033  * This is a special interface that will be utilized by ZFS to cause a share to
1034  * be added/removed.
1035  *
1036  * arg is either a lmshare_info_t or share_name from userspace.
1037  * It will need to be copied into the kernel.   It is lmshare_info_t
1038  * for add operations and share_name for delete operations.
1039  */
1040 int
1041 smb_server_share(void *arg, boolean_t add_share)
1042 {
1043 	smb_server_t	*sv;
1044 	int		rc;
1045 
1046 	if ((rc = smb_server_lookup(&sv)) == 0) {
1047 		mutex_enter(&sv->sv_mutex);
1048 		switch (sv->sv_state) {
1049 		case SMB_SERVER_STATE_RUNNING:
1050 			mutex_exit(&sv->sv_mutex);
1051 			(void) smb_kshare_upcall(sv->sv_lmshrd, arg, add_share);
1052 			break;
1053 		default:
1054 			mutex_exit(&sv->sv_mutex);
1055 			break;
1056 		}
1057 		smb_server_release(sv);
1058 	}
1059 
1060 	return (rc);
1061 }
1062 #endif	/* _KERNEL */
1063 
1064 int
1065 smb_server_unshare(const char *sharename)
1066 {
1067 	smb_server_t	*sv;
1068 	int		rc;
1069 
1070 	if ((rc = smb_server_lookup(&sv)))
1071 		return (rc);
1072 
1073 	mutex_enter(&sv->sv_mutex);
1074 	switch (sv->sv_state) {
1075 	case SMB_SERVER_STATE_RUNNING:
1076 	case SMB_SERVER_STATE_STOPPING:
1077 		break;
1078 	default:
1079 		mutex_exit(&sv->sv_mutex);
1080 		smb_server_release(sv);
1081 		return (ENOTACTIVE);
1082 	}
1083 	mutex_exit(&sv->sv_mutex);
1084 
1085 	smb_server_disconnect_share(sv, sharename);
1086 
1087 	smb_server_release(sv);
1088 	return (0);
1089 }
1090 
1091 /*
1092  * Disconnect the specified share.
1093  * Typically called when a share has been removed.
1094  */
1095 static void
1096 smb_server_disconnect_share(smb_server_t *sv, const char *sharename)
1097 {
1098 	smb_llist_t	*ll;
1099 	smb_session_t	*session;
1100 
1101 	ll = &sv->sv_session_list;
1102 	smb_llist_enter(ll, RW_READER);
1103 
1104 	session = smb_llist_head(ll);
1105 	while (session) {
1106 		SMB_SESSION_VALID(session);
1107 		smb_rwx_rwenter(&session->s_lock, RW_READER);
1108 		switch (session->s_state) {
1109 		case SMB_SESSION_STATE_NEGOTIATED:
1110 			smb_rwx_rwexit(&session->s_lock);
1111 			smb_session_disconnect_share(session, sharename);
1112 			break;
1113 		default:
1114 			smb_rwx_rwexit(&session->s_lock);
1115 			break;
1116 		}
1117 		session = smb_llist_next(ll, session);
1118 	}
1119 
1120 	smb_llist_exit(ll);
1121 }
1122 
1123 /*
1124  * *****************************************************************************
1125  * **************** Functions called from the internal layers ******************
1126  * *****************************************************************************
1127  *
1128  * These functions are provided the relevant smb server by the caller.
1129  */
1130 
1131 void
1132 smb_server_get_cfg(smb_server_t *sv, smb_kmod_cfg_t *cfg)
1133 {
1134 	rw_enter(&sv->sv_cfg_lock, RW_READER);
1135 	bcopy(&sv->sv_cfg, cfg, sizeof (*cfg));
1136 	rw_exit(&sv->sv_cfg_lock);
1137 }
1138 
1139 /*
1140  *
1141  */
1142 void
1143 smb_server_inc_nbt_sess(smb_server_t *sv)
1144 {
1145 	SMB_SERVER_VALID(sv);
1146 	atomic_inc_32(&sv->sv_nbt_sess);
1147 }
1148 
1149 void
1150 smb_server_dec_nbt_sess(smb_server_t *sv)
1151 {
1152 	SMB_SERVER_VALID(sv);
1153 	atomic_dec_32(&sv->sv_nbt_sess);
1154 }
1155 
1156 void
1157 smb_server_inc_tcp_sess(smb_server_t *sv)
1158 {
1159 	SMB_SERVER_VALID(sv);
1160 	atomic_inc_32(&sv->sv_tcp_sess);
1161 }
1162 
1163 void
1164 smb_server_dec_tcp_sess(smb_server_t *sv)
1165 {
1166 	SMB_SERVER_VALID(sv);
1167 	atomic_dec_32(&sv->sv_tcp_sess);
1168 }
1169 
1170 void
1171 smb_server_inc_users(smb_server_t *sv)
1172 {
1173 	SMB_SERVER_VALID(sv);
1174 	atomic_inc_32(&sv->sv_users);
1175 }
1176 
1177 void
1178 smb_server_dec_users(smb_server_t *sv)
1179 {
1180 	SMB_SERVER_VALID(sv);
1181 	atomic_dec_32(&sv->sv_users);
1182 }
1183 
1184 void
1185 smb_server_inc_trees(smb_server_t *sv)
1186 {
1187 	SMB_SERVER_VALID(sv);
1188 	atomic_inc_32(&sv->sv_trees);
1189 }
1190 
1191 void
1192 smb_server_dec_trees(smb_server_t *sv)
1193 {
1194 	SMB_SERVER_VALID(sv);
1195 	atomic_dec_32(&sv->sv_trees);
1196 }
1197 
1198 void
1199 smb_server_inc_files(smb_server_t *sv)
1200 {
1201 	SMB_SERVER_VALID(sv);
1202 	atomic_inc_32(&sv->sv_files);
1203 }
1204 
1205 void
1206 smb_server_dec_files(smb_server_t *sv)
1207 {
1208 	SMB_SERVER_VALID(sv);
1209 	atomic_dec_32(&sv->sv_files);
1210 }
1211 
1212 void
1213 smb_server_inc_pipes(smb_server_t *sv)
1214 {
1215 	SMB_SERVER_VALID(sv);
1216 	atomic_inc_32(&sv->sv_pipes);
1217 }
1218 
1219 void
1220 smb_server_dec_pipes(smb_server_t *sv)
1221 {
1222 	SMB_SERVER_VALID(sv);
1223 	atomic_dec_32(&sv->sv_pipes);
1224 }
1225 
1226 void
1227 smb_server_add_rxb(smb_server_t *sv, int64_t value)
1228 {
1229 	SMB_SERVER_VALID(sv);
1230 	atomic_add_64(&sv->sv_rxb, value);
1231 }
1232 
1233 void
1234 smb_server_add_txb(smb_server_t *sv, int64_t value)
1235 {
1236 	SMB_SERVER_VALID(sv);
1237 	atomic_add_64(&sv->sv_txb, value);
1238 }
1239 
1240 void
1241 smb_server_inc_req(smb_server_t *sv)
1242 {
1243 	SMB_SERVER_VALID(sv);
1244 	atomic_inc_64(&sv->sv_nreq);
1245 }
1246 
1247 /*
1248  * *****************************************************************************
1249  * *************************** Static Functions ********************************
1250  * *****************************************************************************
1251  */
1252 
1253 static void
1254 smb_server_timers(smb_thread_t *thread, void *arg)
1255 {
1256 	smb_server_t	*sv = (smb_server_t *)arg;
1257 
1258 	ASSERT(sv != NULL);
1259 
1260 	/*
1261 	 * This kills old inactive sessions and expired durable
1262 	 * handles. The session code expects one call per minute.
1263 	 */
1264 	while (smb_thread_continue_timedwait(thread, 60 /* Seconds */)) {
1265 		if (sv->sv_cfg.skc_keepalive != 0)
1266 			smb_session_timers(sv);
1267 		smb2_durable_timers(sv);
1268 	}
1269 }
1270 
1271 /*
1272  * smb_server_kstat_init
1273  */
1274 static void
1275 smb_server_kstat_init(smb_server_t *sv)
1276 {
1277 
1278 	sv->sv_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, 0,
1279 	    SMBSRV_KSTAT_STATISTICS, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_RAW,
1280 	    sizeof (smbsrv_kstats_t), 0, sv->sv_zid);
1281 
1282 	if (sv->sv_ksp != NULL) {
1283 		sv->sv_ksp->ks_update = smb_server_kstat_update;
1284 		sv->sv_ksp->ks_private = sv;
1285 		((smbsrv_kstats_t *)sv->sv_ksp->ks_data)->ks_start_time =
1286 		    sv->sv_start_time;
1287 		smb_dispatch_stats_init(sv);
1288 		smb2_dispatch_stats_init(sv);
1289 		kstat_install(sv->sv_ksp);
1290 	} else {
1291 		cmn_err(CE_WARN, "SMB Server: Statistics unavailable");
1292 	}
1293 
1294 	sv->sv_legacy_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, 0,
1295 	    SMBSRV_KSTAT_NAME, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_NAMED,
1296 	    sizeof (smb_server_legacy_kstat_t) / sizeof (kstat_named_t),
1297 	    0, sv->sv_zid);
1298 
1299 	if (sv->sv_legacy_ksp != NULL) {
1300 		smb_server_legacy_kstat_t *ksd;
1301 
1302 		ksd = sv->sv_legacy_ksp->ks_data;
1303 
1304 		(void) strlcpy(ksd->ls_files.name, "open_files",
1305 		    sizeof (ksd->ls_files.name));
1306 		ksd->ls_files.data_type = KSTAT_DATA_UINT32;
1307 
1308 		(void) strlcpy(ksd->ls_trees.name, "connections",
1309 		    sizeof (ksd->ls_trees.name));
1310 		ksd->ls_trees.data_type = KSTAT_DATA_UINT32;
1311 
1312 		(void) strlcpy(ksd->ls_users.name, "connections",
1313 		    sizeof (ksd->ls_users.name));
1314 		ksd->ls_users.data_type = KSTAT_DATA_UINT32;
1315 
1316 		mutex_init(&sv->sv_legacy_ksmtx, NULL, MUTEX_DEFAULT, NULL);
1317 		sv->sv_legacy_ksp->ks_lock = &sv->sv_legacy_ksmtx;
1318 		sv->sv_legacy_ksp->ks_update = smb_server_legacy_kstat_update;
1319 		kstat_install(sv->sv_legacy_ksp);
1320 	}
1321 }
1322 
1323 /*
1324  * smb_server_kstat_fini
1325  */
1326 static void
1327 smb_server_kstat_fini(smb_server_t *sv)
1328 {
1329 	if (sv->sv_legacy_ksp != NULL) {
1330 		kstat_delete(sv->sv_legacy_ksp);
1331 		mutex_destroy(&sv->sv_legacy_ksmtx);
1332 		sv->sv_legacy_ksp = NULL;
1333 	}
1334 
1335 	if (sv->sv_ksp != NULL) {
1336 		kstat_delete(sv->sv_ksp);
1337 		sv->sv_ksp = NULL;
1338 		smb_dispatch_stats_fini(sv);
1339 		smb2_dispatch_stats_fini(sv);
1340 	}
1341 }
1342 
1343 /*
1344  * smb_server_kstat_update
1345  */
1346 static int
1347 smb_server_kstat_update(kstat_t *ksp, int rw)
1348 {
1349 	smb_server_t	*sv;
1350 	smbsrv_kstats_t	*ksd;
1351 
1352 	if (rw == KSTAT_READ) {
1353 		sv = ksp->ks_private;
1354 		SMB_SERVER_VALID(sv);
1355 		ksd = (smbsrv_kstats_t *)ksp->ks_data;
1356 		/*
1357 		 * Counters
1358 		 */
1359 		ksd->ks_nbt_sess = sv->sv_nbt_sess;
1360 		ksd->ks_tcp_sess = sv->sv_tcp_sess;
1361 		ksd->ks_users = sv->sv_users;
1362 		ksd->ks_trees = sv->sv_trees;
1363 		ksd->ks_files = sv->sv_files;
1364 		ksd->ks_pipes = sv->sv_pipes;
1365 		/*
1366 		 * Throughput
1367 		 */
1368 		ksd->ks_txb = sv->sv_txb;
1369 		ksd->ks_rxb = sv->sv_rxb;
1370 		ksd->ks_nreq = sv->sv_nreq;
1371 		/*
1372 		 * Busyness
1373 		 */
1374 		ksd->ks_maxreqs = sv->sv_cfg.skc_maxworkers;
1375 		smb_srqueue_update(&sv->sv_srqueue,
1376 		    &ksd->ks_utilization);
1377 		/*
1378 		 * Latency & Throughput of the requests
1379 		 */
1380 		smb_dispatch_stats_update(sv, ksd->ks_reqs1, 0, SMB_COM_NUM);
1381 		smb2_dispatch_stats_update(sv, ksd->ks_reqs2, 0, SMB2__NCMDS);
1382 		return (0);
1383 	}
1384 	if (rw == KSTAT_WRITE)
1385 		return (EACCES);
1386 
1387 	return (EIO);
1388 }
1389 
1390 static int
1391 smb_server_legacy_kstat_update(kstat_t *ksp, int rw)
1392 {
1393 	smb_server_t			*sv;
1394 	smb_server_legacy_kstat_t	*ksd;
1395 	int				rc;
1396 
1397 	switch (rw) {
1398 	case KSTAT_WRITE:
1399 		rc = EACCES;
1400 		break;
1401 	case KSTAT_READ:
1402 		if (!smb_server_lookup(&sv)) {
1403 			ASSERT(MUTEX_HELD(ksp->ks_lock));
1404 			ASSERT(sv->sv_legacy_ksp == ksp);
1405 			ksd = (smb_server_legacy_kstat_t *)ksp->ks_data;
1406 			ksd->ls_files.value.ui32 = sv->sv_files + sv->sv_pipes;
1407 			ksd->ls_trees.value.ui32 = sv->sv_trees;
1408 			ksd->ls_users.value.ui32 = sv->sv_users;
1409 			smb_server_release(sv);
1410 			rc = 0;
1411 			break;
1412 		}
1413 		/* FALLTHROUGH */
1414 	default:
1415 		rc = EIO;
1416 		break;
1417 	}
1418 	return (rc);
1419 
1420 }
1421 
1422 /*
1423  * smb_server_shutdown
1424  */
1425 static void
1426 smb_server_shutdown(smb_server_t *sv)
1427 {
1428 	smb_llist_t *sl = &sv->sv_session_list;
1429 	smb_session_t *session;
1430 	clock_t	time;
1431 
1432 	SMB_SERVER_VALID(sv);
1433 
1434 	/*
1435 	 * Stop the listeners first, so we don't get any more
1436 	 * new work while we're trying to shut down.
1437 	 */
1438 	smb_server_listener_stop(&sv->sv_nbt_daemon);
1439 	smb_server_listener_stop(&sv->sv_tcp_daemon);
1440 	smb_thread_stop(&sv->si_thread_timers);
1441 
1442 	/* Disconnect all of the sessions */
1443 	smb_llist_enter(sl, RW_READER);
1444 	session = smb_llist_head(sl);
1445 	while (session != NULL) {
1446 		smb_session_disconnect(session);
1447 		session = smb_llist_next(sl, session);
1448 	}
1449 	smb_llist_exit(sl);
1450 
1451 	/*
1452 	 * Wake up any threads we might have blocked.
1453 	 * Must precede kdoor_close etc. because those will
1454 	 * wait for such threads to get out.
1455 	 */
1456 	smb_event_cancel(sv, 0);
1457 	smb_threshold_wake_all(&sv->sv_ssetup_ct);
1458 	smb_threshold_wake_all(&sv->sv_tcon_ct);
1459 	smb_threshold_wake_all(&sv->sv_opipe_ct);
1460 
1461 	/*
1462 	 * Wait for the session list to empty.
1463 	 * (cv_signal in smb_server_destroy_session)
1464 	 *
1465 	 * This should not take long, but if there are any leaked
1466 	 * references to ofiles, trees, or users, there could be a
1467 	 * session hanging around.  If that happens, the ll_count
1468 	 * never gets to zero and we'll never get the sv_signal.
1469 	 * Defend against that problem using timed wait, then
1470 	 * complain if we find sessions left over and continue
1471 	 * with shutdown in spite of any leaked sessions.
1472 	 * That's better than a server that won't reboot.
1473 	 */
1474 	time = SEC_TO_TICK(10) + ddi_get_lbolt();
1475 	mutex_enter(&sv->sv_mutex);
1476 	while (sv->sv_session_list.ll_count != 0) {
1477 		if (cv_timedwait(&sv->sv_cv, &sv->sv_mutex, time) < 0)
1478 			break;
1479 	}
1480 	mutex_exit(&sv->sv_mutex);
1481 #ifdef	DEBUG
1482 	if (sv->sv_session_list.ll_count != 0) {
1483 		cmn_err(CE_NOTE, "shutdown leaked sessions");
1484 		debug_enter("shutdown leaked sessions");
1485 	}
1486 #endif
1487 
1488 	/*
1489 	 * Clean out any durable handles.  After this we should
1490 	 * have no ofiles remaining (and no more oplock breaks).
1491 	 */
1492 	smb2_dh_shutdown(sv);
1493 
1494 	smb_kdoor_close(sv);
1495 #ifdef	_KERNEL
1496 	smb_kshare_door_fini(sv->sv_lmshrd);
1497 #endif	/* _KERNEL */
1498 	sv->sv_lmshrd = NULL;
1499 
1500 	smb_export_stop(sv);
1501 	smb_kshare_stop(sv);
1502 
1503 	/*
1504 	 * Both kshare and the oplock break sub-systems may have
1505 	 * taskq jobs on the spcial "server" session, until we've
1506 	 * closed all ofiles and stopped the kshare exporter.
1507 	 * Now it's safe to destroy the server session, but first
1508 	 * wait for any requests on it to finish.  Note that for
1509 	 * normal sessions, this happens in smb_session_cancel,
1510 	 * but that's not called for the server session.
1511 	 */
1512 	if (sv->sv_rootuser != NULL) {
1513 		smb_user_logoff(sv->sv_rootuser);
1514 		smb_user_release(sv->sv_rootuser);
1515 		sv->sv_rootuser = NULL;
1516 	}
1517 	if (sv->sv_session != NULL) {
1518 		smb_slist_wait_for_empty(&sv->sv_session->s_req_list);
1519 
1520 		/* Just in case import left users and trees */
1521 		smb_session_logoff(sv->sv_session);
1522 
1523 		smb_session_delete(sv->sv_session);
1524 		sv->sv_session = NULL;
1525 	}
1526 
1527 	if (sv->sv_receiver_pool != NULL) {
1528 		taskq_destroy(sv->sv_receiver_pool);
1529 		sv->sv_receiver_pool = NULL;
1530 	}
1531 
1532 	if (sv->sv_worker_pool != NULL) {
1533 		taskq_destroy(sv->sv_worker_pool);
1534 		sv->sv_worker_pool = NULL;
1535 	}
1536 
1537 	smb_server_fsop_stop(sv);
1538 }
1539 
1540 /*
1541  * smb_server_listener_init
1542  *
1543  * Initializes listener contexts.
1544  */
1545 static void
1546 smb_server_listener_init(
1547     smb_server_t		*sv,
1548     smb_listener_daemon_t	*ld,
1549     char			*name,
1550     in_port_t			port,
1551     int				family)
1552 {
1553 	ASSERT(ld->ld_magic != SMB_LISTENER_MAGIC);
1554 
1555 	bzero(ld, sizeof (*ld));
1556 
1557 	ld->ld_sv = sv;
1558 	ld->ld_family = family;
1559 	ld->ld_port = port;
1560 
1561 	if (family == AF_INET) {
1562 		ld->ld_sin.sin_family = (uint32_t)family;
1563 		ld->ld_sin.sin_port = htons(port);
1564 		ld->ld_sin.sin_addr.s_addr = htonl(INADDR_ANY);
1565 	} else {
1566 		ld->ld_sin6.sin6_family = (uint32_t)family;
1567 		ld->ld_sin6.sin6_port = htons(port);
1568 		(void) memset(&ld->ld_sin6.sin6_addr.s6_addr, 0,
1569 		    sizeof (ld->ld_sin6.sin6_addr.s6_addr));
1570 	}
1571 
1572 	smb_thread_init(&ld->ld_thread, name, smb_server_listener, ld,
1573 	    smbsrv_listen_pri);
1574 	ld->ld_magic = SMB_LISTENER_MAGIC;
1575 }
1576 
1577 /*
1578  * smb_server_listener_destroy
1579  *
1580  * Destroyes listener contexts.
1581  */
1582 static void
1583 smb_server_listener_destroy(smb_listener_daemon_t *ld)
1584 {
1585 	/*
1586 	 * Note that if startup fails early, we can legitimately
1587 	 * get here with an all-zeros object.
1588 	 */
1589 	if (ld->ld_magic == 0)
1590 		return;
1591 
1592 	SMB_LISTENER_VALID(ld);
1593 	ASSERT(ld->ld_so == NULL);
1594 	smb_thread_destroy(&ld->ld_thread);
1595 	ld->ld_magic = 0;
1596 }
1597 
1598 /*
1599  * smb_server_listener_start
1600  *
1601  * Starts the listener associated with the context passed in.
1602  *
1603  * Return:	0	Success
1604  *		not 0	Failure
1605  */
1606 static int
1607 smb_server_listener_start(smb_listener_daemon_t *ld)
1608 {
1609 	int		rc;
1610 	uint32_t	on;
1611 	uint32_t	off;
1612 
1613 	SMB_LISTENER_VALID(ld);
1614 
1615 	if (ld->ld_so != NULL)
1616 		return (EINVAL);
1617 
1618 	ld->ld_so = smb_socreate(ld->ld_family, SOCK_STREAM, 0);
1619 	if (ld->ld_so == NULL) {
1620 		cmn_err(CE_WARN, "port %d: socket create failed", ld->ld_port);
1621 		return (ENOMEM);
1622 	}
1623 
1624 	off = 0;
1625 	(void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET,
1626 	    SO_MAC_EXEMPT, &off, sizeof (off), CRED());
1627 
1628 	on = 1;
1629 	(void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET,
1630 	    SO_REUSEADDR, &on, sizeof (on), CRED());
1631 
1632 	if (ld->ld_family == AF_INET) {
1633 		rc = ksocket_bind(ld->ld_so,
1634 		    (struct sockaddr *)&ld->ld_sin,
1635 		    sizeof (ld->ld_sin), CRED());
1636 	} else {
1637 		rc = ksocket_bind(ld->ld_so,
1638 		    (struct sockaddr *)&ld->ld_sin6,
1639 		    sizeof (ld->ld_sin6), CRED());
1640 	}
1641 
1642 	if (rc != 0) {
1643 		cmn_err(CE_WARN, "port %d: bind failed", ld->ld_port);
1644 		return (rc);
1645 	}
1646 
1647 	rc =  ksocket_listen(ld->ld_so, 20, CRED());
1648 	if (rc < 0) {
1649 		cmn_err(CE_WARN, "port %d: listen failed", ld->ld_port);
1650 		return (rc);
1651 	}
1652 
1653 	ksocket_hold(ld->ld_so);
1654 	rc = smb_thread_start(&ld->ld_thread);
1655 	if (rc != 0) {
1656 		ksocket_rele(ld->ld_so);
1657 		cmn_err(CE_WARN, "port %d: listener failed to start",
1658 		    ld->ld_port);
1659 		return (rc);
1660 	}
1661 	return (0);
1662 }
1663 
1664 /*
1665  * smb_server_listener_stop
1666  *
1667  * Stops the listener associated with the context passed in.
1668  */
1669 static void
1670 smb_server_listener_stop(smb_listener_daemon_t *ld)
1671 {
1672 	SMB_LISTENER_VALID(ld);
1673 
1674 	if (ld->ld_so != NULL) {
1675 		smb_soshutdown(ld->ld_so);
1676 		smb_sodestroy(ld->ld_so);
1677 		smb_thread_stop(&ld->ld_thread);
1678 		ld->ld_so = NULL;
1679 	}
1680 }
1681 
1682 /*
1683  * smb_server_listener
1684  *
1685  * Entry point of the listeners.
1686  */
1687 static void
1688 smb_server_listener(smb_thread_t *thread, void *arg)
1689 {
1690 	_NOTE(ARGUNUSED(thread))
1691 	smb_listener_daemon_t	*ld;
1692 	ksocket_t		s_so;
1693 	int			on;
1694 	int			txbuf_size;
1695 
1696 	ld = (smb_listener_daemon_t *)arg;
1697 
1698 	SMB_LISTENER_VALID(ld);
1699 
1700 	DTRACE_PROBE1(so__wait__accept, struct sonode *, ld->ld_so);
1701 
1702 	for (;;) {
1703 		int ret = ksocket_accept(ld->ld_so, NULL, NULL, &s_so, CRED());
1704 
1705 		switch (ret) {
1706 		case 0:
1707 			break;
1708 		case ECONNABORTED:
1709 			continue;
1710 		case EINTR:
1711 		case EBADF:	/* libfakekernel */
1712 			goto out;
1713 		default:
1714 			cmn_err(CE_WARN,
1715 			    "smb_server_listener: ksocket_accept(%d)",
1716 			    ret);
1717 			goto out;
1718 		}
1719 
1720 		DTRACE_PROBE1(so__accept, struct sonode *, s_so);
1721 
1722 		on = 1;
1723 		(void) ksocket_setsockopt(s_so, IPPROTO_TCP, TCP_NODELAY,
1724 		    &on, sizeof (on), CRED());
1725 
1726 		on = 1;
1727 		(void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_KEEPALIVE,
1728 		    &on, sizeof (on), CRED());
1729 
1730 		txbuf_size = 128*1024;
1731 		(void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_SNDBUF,
1732 		    (const void *)&txbuf_size, sizeof (txbuf_size), CRED());
1733 
1734 		/*
1735 		 * Create a session for this connection.
1736 		 */
1737 		smb_server_create_session(ld, s_so);
1738 	}
1739 out:
1740 	ksocket_rele(ld->ld_so);
1741 }
1742 
1743 /*
1744  * smb_server_receiver
1745  *
1746  * Entry point of the receiver threads.
1747  * Also does cleanup when socket disconnected.
1748  */
1749 static void
1750 smb_server_receiver(void *arg)
1751 {
1752 	smb_session_t	*session;
1753 
1754 	session = (smb_session_t *)arg;
1755 
1756 	/* We stay in here until socket disconnect. */
1757 	smb_session_receiver(session);
1758 
1759 	ASSERT(session->s_state == SMB_SESSION_STATE_SHUTDOWN);
1760 	smb_server_destroy_session(session);
1761 }
1762 
1763 /*
1764  * smb_server_lookup
1765  *
1766  * This function finds the server associated with the zone of the
1767  * caller.  Note: requires a fix in the dynamic taskq code:
1768  * 1501 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0
1769  */
1770 int
1771 smb_server_lookup(smb_server_t **psv)
1772 {
1773 	zoneid_t	zid;
1774 	smb_server_t	*sv;
1775 
1776 	zid = getzoneid();
1777 
1778 	smb_llist_enter(&smb_servers, RW_READER);
1779 	sv = smb_llist_head(&smb_servers);
1780 	while (sv) {
1781 		SMB_SERVER_VALID(sv);
1782 		if (sv->sv_zid == zid) {
1783 			mutex_enter(&sv->sv_mutex);
1784 			if (sv->sv_state != SMB_SERVER_STATE_DELETING) {
1785 				sv->sv_refcnt++;
1786 				mutex_exit(&sv->sv_mutex);
1787 				smb_llist_exit(&smb_servers);
1788 				*psv = sv;
1789 				return (0);
1790 			}
1791 			mutex_exit(&sv->sv_mutex);
1792 			break;
1793 		}
1794 		sv = smb_llist_next(&smb_servers, sv);
1795 	}
1796 	smb_llist_exit(&smb_servers);
1797 	return (EPERM);
1798 }
1799 
1800 /*
1801  * smb_server_release
1802  *
1803  * This function decrements the reference count of the server and signals its
1804  * condition variable if the state of the server is SMB_SERVER_STATE_DELETING.
1805  */
1806 void
1807 smb_server_release(smb_server_t *sv)
1808 {
1809 	SMB_SERVER_VALID(sv);
1810 
1811 	mutex_enter(&sv->sv_mutex);
1812 	ASSERT(sv->sv_refcnt);
1813 	sv->sv_refcnt--;
1814 	if ((sv->sv_refcnt == 0) && (sv->sv_state == SMB_SERVER_STATE_DELETING))
1815 		cv_signal(&sv->sv_cv);
1816 	mutex_exit(&sv->sv_mutex);
1817 }
1818 
1819 /*
1820  * Enumerate the users associated with a session list.
1821  */
1822 static void
1823 smb_server_enum_users(smb_server_t *sv, smb_svcenum_t *svcenum)
1824 {
1825 	smb_llist_t	*ll = &sv->sv_session_list;
1826 	smb_session_t	*sn;
1827 	smb_llist_t	*ulist;
1828 	smb_user_t	*user;
1829 	int		rc = 0;
1830 
1831 	smb_llist_enter(ll, RW_READER);
1832 	sn = smb_llist_head(ll);
1833 
1834 	while (sn != NULL) {
1835 		SMB_SESSION_VALID(sn);
1836 		ulist = &sn->s_user_list;
1837 		smb_llist_enter(ulist, RW_READER);
1838 		user = smb_llist_head(ulist);
1839 
1840 		while (user != NULL) {
1841 			if (smb_user_hold(user)) {
1842 				rc = smb_user_enum(user, svcenum);
1843 				smb_user_release(user);
1844 				if (rc != 0)
1845 					break;
1846 			}
1847 
1848 			user = smb_llist_next(ulist, user);
1849 		}
1850 
1851 		smb_llist_exit(ulist);
1852 
1853 		if (rc != 0)
1854 			break;
1855 
1856 		sn = smb_llist_next(ll, sn);
1857 	}
1858 
1859 	smb_llist_exit(ll);
1860 }
1861 
1862 /*
1863  * Enumerate the trees/files associated with a session list.
1864  */
1865 static void
1866 smb_server_enum_trees(smb_server_t *sv, smb_svcenum_t *svcenum)
1867 {
1868 	smb_llist_t	*ll = &sv->sv_session_list;
1869 	smb_session_t	*sn;
1870 	smb_llist_t	*tlist;
1871 	smb_tree_t	*tree;
1872 	int		rc = 0;
1873 
1874 	smb_llist_enter(ll, RW_READER);
1875 	sn = smb_llist_head(ll);
1876 
1877 	while (sn != NULL) {
1878 		SMB_SESSION_VALID(sn);
1879 		tlist = &sn->s_tree_list;
1880 		smb_llist_enter(tlist, RW_READER);
1881 		tree = smb_llist_head(tlist);
1882 
1883 		while (tree != NULL) {
1884 			if (smb_tree_hold(tree)) {
1885 				rc = smb_tree_enum(tree, svcenum);
1886 				smb_tree_release(tree);
1887 				if (rc != 0)
1888 					break;
1889 			}
1890 
1891 			tree = smb_llist_next(tlist, tree);
1892 		}
1893 
1894 		smb_llist_exit(tlist);
1895 
1896 		if (rc != 0)
1897 			break;
1898 
1899 		sn = smb_llist_next(ll, sn);
1900 	}
1901 
1902 	smb_llist_exit(ll);
1903 }
1904 
1905 /*
1906  * Disconnect sessions associated with the specified client and username.
1907  * Empty strings are treated as wildcards.
1908  */
1909 static int
1910 smb_server_session_disconnect(smb_server_t *sv,
1911     const char *client, const char *name)
1912 {
1913 	smb_llist_t	*ll = &sv->sv_session_list;
1914 	smb_session_t	*sn;
1915 	smb_llist_t	*ulist;
1916 	smb_user_t	*user;
1917 	int		count = 0;
1918 
1919 	smb_llist_enter(ll, RW_READER);
1920 
1921 	for (sn = smb_llist_head(ll);
1922 	    sn != NULL;
1923 	    sn = smb_llist_next(ll, sn)) {
1924 		SMB_SESSION_VALID(sn);
1925 
1926 		if (*client != '\0' && !smb_session_isclient(sn, client))
1927 			continue;
1928 
1929 		ulist = &sn->s_user_list;
1930 		smb_llist_enter(ulist, RW_READER);
1931 
1932 		for (user = smb_llist_head(ulist);
1933 		    user != NULL;
1934 		    user = smb_llist_next(ulist, user)) {
1935 
1936 			if (smb_user_hold(user)) {
1937 
1938 				if (*name == '\0' ||
1939 				    smb_user_namecmp(user, name)) {
1940 					smb_user_logoff(user);
1941 					count++;
1942 				}
1943 
1944 				smb_user_release(user);
1945 			}
1946 		}
1947 
1948 		smb_llist_exit(ulist);
1949 	}
1950 
1951 	smb_llist_exit(ll);
1952 	return (count);
1953 }
1954 
1955 /*
1956  * Close a file by its unique id.
1957  */
1958 static int
1959 smb_server_fclose(smb_server_t *sv, uint32_t uniqid)
1960 {
1961 	smb_llist_t	*ll;
1962 	smb_session_t	*sn;
1963 	smb_llist_t	*tlist;
1964 	smb_tree_t	*tree;
1965 	int		rc = ENOENT;
1966 
1967 	ll = &sv->sv_session_list;
1968 	smb_llist_enter(ll, RW_READER);
1969 	sn = smb_llist_head(ll);
1970 
1971 	while ((sn != NULL) && (rc == ENOENT)) {
1972 		SMB_SESSION_VALID(sn);
1973 		tlist = &sn->s_tree_list;
1974 		smb_llist_enter(tlist, RW_READER);
1975 		tree = smb_llist_head(tlist);
1976 
1977 		while ((tree != NULL) && (rc == ENOENT)) {
1978 			if (smb_tree_hold(tree)) {
1979 				rc = smb_tree_fclose(tree, uniqid);
1980 				smb_tree_release(tree);
1981 			}
1982 
1983 			tree = smb_llist_next(tlist, tree);
1984 		}
1985 
1986 		smb_llist_exit(tlist);
1987 		sn = smb_llist_next(ll, sn);
1988 	}
1989 
1990 	smb_llist_exit(ll);
1991 	return (rc);
1992 }
1993 
1994 /*
1995  * This is used by SMB2 session setup to logoff a previous session,
1996  * so it can force a logoff that we haven't noticed yet.
1997  * This is not called frequently, so we just walk the list of
1998  * connections searching for the user.
1999  */
2000 void
2001 smb_server_logoff_ssnid(smb_request_t *sr, uint64_t ssnid)
2002 {
2003 	smb_server_t	*sv = sr->sr_server;
2004 	smb_llist_t	*sess_list;
2005 	smb_session_t	*sess;
2006 
2007 	if (sv->sv_state != SMB_SERVER_STATE_RUNNING)
2008 		return;
2009 
2010 	sess_list = &sv->sv_session_list;
2011 	smb_llist_enter(sess_list, RW_READER);
2012 
2013 	for (sess = smb_llist_head(sess_list);
2014 	    sess != NULL;
2015 	    sess = smb_llist_next(sess_list, sess)) {
2016 
2017 		smb_user_t	*user;
2018 
2019 		SMB_SESSION_VALID(sess);
2020 
2021 		if (sess->dialect < SMB_VERS_2_BASE)
2022 			continue;
2023 
2024 		if (sess->s_state != SMB_SESSION_STATE_NEGOTIATED)
2025 			continue;
2026 
2027 		user = smb_session_lookup_ssnid(sess, ssnid);
2028 		if (user == NULL)
2029 			continue;
2030 
2031 		if (!smb_is_same_user(user->u_cred, sr->user_cr)) {
2032 			smb_user_release(user);
2033 			continue;
2034 		}
2035 
2036 		/* Treat this as if we lost the connection */
2037 		user->preserve_opens = SMB2_DH_PRESERVE_SOME;
2038 		smb_user_logoff(user);
2039 		smb_user_release(user);
2040 
2041 		/*
2042 		 * The above may have left work on the delete queues
2043 		 */
2044 		smb_llist_flush(&sess->s_tree_list);
2045 		smb_llist_flush(&sess->s_user_list);
2046 	}
2047 
2048 	smb_llist_exit(sess_list);
2049 }
2050 
2051 /* See also: libsmb smb_kmod_setcfg */
2052 static void
2053 smb_server_store_cfg(smb_server_t *sv, smb_ioc_cfg_t *ioc)
2054 {
2055 	if (ioc->maxconnections == 0)
2056 		ioc->maxconnections = 0xFFFFFFFF;
2057 
2058 	if (ioc->encrypt == SMB_CONFIG_REQUIRED &&
2059 	    ioc->max_protocol < SMB_VERS_3_0) {
2060 		cmn_err(CE_WARN, "Server set to require encryption; "
2061 		    "forcing max_protocol to 3.0");
2062 		ioc->max_protocol = SMB_VERS_3_0;
2063 	}
2064 
2065 	sv->sv_cfg.skc_maxworkers = ioc->maxworkers;
2066 	sv->sv_cfg.skc_maxconnections = ioc->maxconnections;
2067 	sv->sv_cfg.skc_keepalive = ioc->keepalive;
2068 	sv->sv_cfg.skc_restrict_anon = ioc->restrict_anon;
2069 	sv->sv_cfg.skc_signing_enable = ioc->signing_enable;
2070 	sv->sv_cfg.skc_signing_required = ioc->signing_required;
2071 	sv->sv_cfg.skc_oplock_enable = ioc->oplock_enable;
2072 	sv->sv_cfg.skc_sync_enable = ioc->sync_enable;
2073 	sv->sv_cfg.skc_secmode = ioc->secmode;
2074 	sv->sv_cfg.skc_netbios_enable = ioc->netbios_enable;
2075 	sv->sv_cfg.skc_ipv6_enable = ioc->ipv6_enable;
2076 	sv->sv_cfg.skc_print_enable = ioc->print_enable;
2077 	sv->sv_cfg.skc_traverse_mounts = ioc->traverse_mounts;
2078 	sv->sv_cfg.skc_max_protocol = ioc->max_protocol;
2079 	sv->sv_cfg.skc_min_protocol = ioc->min_protocol;
2080 	sv->sv_cfg.skc_encrypt = ioc->encrypt;
2081 	sv->sv_cfg.skc_execflags = ioc->exec_flags;
2082 	sv->sv_cfg.skc_negtok_len = ioc->negtok_len;
2083 	sv->sv_cfg.skc_version = ioc->version;
2084 	sv->sv_cfg.skc_initial_credits = ioc->initial_credits;
2085 	sv->sv_cfg.skc_maximum_credits = ioc->maximum_credits;
2086 
2087 	(void) memcpy(sv->sv_cfg.skc_machine_uuid, ioc->machine_uuid,
2088 	    sizeof (uuid_t));
2089 	(void) memcpy(sv->sv_cfg.skc_negtok, ioc->negtok,
2090 	    sizeof (sv->sv_cfg.skc_negtok));
2091 	(void) memcpy(sv->sv_cfg.skc_native_os, ioc->native_os,
2092 	    sizeof (sv->sv_cfg.skc_native_os));
2093 	(void) memcpy(sv->sv_cfg.skc_native_lm, ioc->native_lm,
2094 	    sizeof (sv->sv_cfg.skc_native_lm));
2095 
2096 	(void) strlcpy(sv->sv_cfg.skc_nbdomain, ioc->nbdomain,
2097 	    sizeof (sv->sv_cfg.skc_nbdomain));
2098 	(void) strlcpy(sv->sv_cfg.skc_fqdn, ioc->fqdn,
2099 	    sizeof (sv->sv_cfg.skc_fqdn));
2100 	(void) strlcpy(sv->sv_cfg.skc_hostname, ioc->hostname,
2101 	    sizeof (sv->sv_cfg.skc_hostname));
2102 	(void) strlcpy(sv->sv_cfg.skc_system_comment, ioc->system_comment,
2103 	    sizeof (sv->sv_cfg.skc_system_comment));
2104 }
2105 
2106 static int
2107 smb_server_fsop_start(smb_server_t *sv)
2108 {
2109 	int	error;
2110 
2111 	error = smb_node_root_init(sv, &sv->si_root_smb_node);
2112 	if (error != 0)
2113 		sv->si_root_smb_node = NULL;
2114 
2115 	return (error);
2116 }
2117 
2118 static void
2119 smb_server_fsop_stop(smb_server_t *sv)
2120 {
2121 	if (sv->si_root_smb_node != NULL) {
2122 		smb_node_release(sv->si_root_smb_node);
2123 		sv->si_root_smb_node = NULL;
2124 	}
2125 }
2126 
2127 smb_event_t *
2128 smb_event_create(smb_server_t *sv, int timeout)
2129 {
2130 	smb_event_t	*event;
2131 
2132 	if (smb_server_is_stopping(sv))
2133 		return (NULL);
2134 
2135 	event = kmem_cache_alloc(smb_cache_event, KM_SLEEP);
2136 
2137 	bzero(event, sizeof (smb_event_t));
2138 	mutex_init(&event->se_mutex, NULL, MUTEX_DEFAULT, NULL);
2139 	cv_init(&event->se_cv, NULL, CV_DEFAULT, NULL);
2140 	event->se_magic = SMB_EVENT_MAGIC;
2141 	event->se_txid = smb_event_alloc_txid();
2142 	event->se_server = sv;
2143 	event->se_timeout = timeout;
2144 
2145 	smb_llist_enter(&sv->sv_event_list, RW_WRITER);
2146 	smb_llist_insert_tail(&sv->sv_event_list, event);
2147 	smb_llist_exit(&sv->sv_event_list);
2148 
2149 	return (event);
2150 }
2151 
2152 void
2153 smb_event_destroy(smb_event_t *event)
2154 {
2155 	smb_server_t	*sv;
2156 
2157 	if (event == NULL)
2158 		return;
2159 
2160 	SMB_EVENT_VALID(event);
2161 	ASSERT(event->se_waittime == 0);
2162 	sv = event->se_server;
2163 	SMB_SERVER_VALID(sv);
2164 
2165 	smb_llist_enter(&sv->sv_event_list, RW_WRITER);
2166 	smb_llist_remove(&sv->sv_event_list, event);
2167 	smb_llist_exit(&sv->sv_event_list);
2168 
2169 	event->se_magic = (uint32_t)~SMB_EVENT_MAGIC;
2170 	cv_destroy(&event->se_cv);
2171 	mutex_destroy(&event->se_mutex);
2172 
2173 	kmem_cache_free(smb_cache_event, event);
2174 }
2175 
2176 /*
2177  * Get the txid for the specified event.
2178  */
2179 uint32_t
2180 smb_event_txid(smb_event_t *event)
2181 {
2182 	if (event != NULL) {
2183 		SMB_EVENT_VALID(event);
2184 		return (event->se_txid);
2185 	}
2186 
2187 	cmn_err(CE_NOTE, "smb_event_txid failed");
2188 	return ((uint32_t)-1);
2189 }
2190 
2191 /*
2192  * Wait for event notification.
2193  */
2194 int
2195 smb_event_wait(smb_event_t *event)
2196 {
2197 	int	seconds = 1;
2198 	int	ticks;
2199 	int	err;
2200 
2201 	if (event == NULL)
2202 		return (EINVAL);
2203 
2204 	SMB_EVENT_VALID(event);
2205 
2206 	mutex_enter(&event->se_mutex);
2207 	event->se_waittime = 1;
2208 	event->se_errno = 0;
2209 
2210 	while (!(event->se_notified)) {
2211 		if (smb_event_debug && ((event->se_waittime % 30) == 0))
2212 			cmn_err(CE_NOTE, "smb_event_wait[%d] (%d sec)",
2213 			    event->se_txid, event->se_waittime);
2214 
2215 		if (event->se_errno != 0)
2216 			break;
2217 
2218 		if (event->se_waittime > event->se_timeout) {
2219 			event->se_errno = ETIME;
2220 			break;
2221 		}
2222 
2223 		ticks = SEC_TO_TICK(seconds);
2224 		(void) cv_reltimedwait(&event->se_cv,
2225 		    &event->se_mutex, (clock_t)ticks, TR_CLOCK_TICK);
2226 		++event->se_waittime;
2227 	}
2228 
2229 	err = event->se_errno;
2230 	event->se_waittime = 0;
2231 	event->se_notified = B_FALSE;
2232 	cv_signal(&event->se_cv);
2233 	mutex_exit(&event->se_mutex);
2234 	return (err);
2235 }
2236 
2237 /*
2238  * If txid is non-zero, cancel the specified event.
2239  * Otherwise, cancel all events.
2240  */
2241 static void
2242 smb_event_cancel(smb_server_t *sv, uint32_t txid)
2243 {
2244 	smb_event_t	*event;
2245 	smb_llist_t	*event_list;
2246 
2247 	SMB_SERVER_VALID(sv);
2248 
2249 	event_list = &sv->sv_event_list;
2250 	smb_llist_enter(event_list, RW_WRITER);
2251 
2252 	event = smb_llist_head(event_list);
2253 	while (event) {
2254 		SMB_EVENT_VALID(event);
2255 
2256 		if (txid == 0 || event->se_txid == txid) {
2257 			mutex_enter(&event->se_mutex);
2258 			event->se_errno = ECANCELED;
2259 			event->se_notified = B_TRUE;
2260 			cv_signal(&event->se_cv);
2261 			mutex_exit(&event->se_mutex);
2262 
2263 			if (txid != 0)
2264 				break;
2265 		}
2266 
2267 		event = smb_llist_next(event_list, event);
2268 	}
2269 
2270 	smb_llist_exit(event_list);
2271 }
2272 
2273 /*
2274  * If txid is non-zero, notify the specified event.
2275  * Otherwise, notify all events.
2276  */
2277 void
2278 smb_event_notify(smb_server_t *sv, uint32_t txid)
2279 {
2280 	smb_event_t	*event;
2281 	smb_llist_t	*event_list;
2282 
2283 	SMB_SERVER_VALID(sv);
2284 
2285 	event_list = &sv->sv_event_list;
2286 	smb_llist_enter(event_list, RW_READER);
2287 
2288 	event = smb_llist_head(event_list);
2289 	while (event) {
2290 		SMB_EVENT_VALID(event);
2291 
2292 		if (txid == 0 || event->se_txid == txid) {
2293 			mutex_enter(&event->se_mutex);
2294 			event->se_notified = B_TRUE;
2295 			cv_signal(&event->se_cv);
2296 			mutex_exit(&event->se_mutex);
2297 
2298 			if (txid != 0)
2299 				break;
2300 		}
2301 
2302 		event = smb_llist_next(event_list, event);
2303 	}
2304 
2305 	smb_llist_exit(event_list);
2306 }
2307 
2308 /*
2309  * Allocate a new transaction id (txid).
2310  *
2311  * 0 or -1 are not assigned because they are used to detect invalid
2312  * conditions or to indicate all open id's.
2313  */
2314 static uint32_t
2315 smb_event_alloc_txid(void)
2316 {
2317 	static kmutex_t	txmutex;
2318 	static uint32_t	txid;
2319 	uint32_t	txid_ret;
2320 
2321 	mutex_enter(&txmutex);
2322 
2323 	if (txid == 0)
2324 		txid = ddi_get_lbolt() << 11;
2325 
2326 	do {
2327 		++txid;
2328 	} while (txid == 0 || txid == (uint32_t)-1);
2329 
2330 	txid_ret = txid;
2331 	mutex_exit(&txmutex);
2332 
2333 	return (txid_ret);
2334 }
2335 
2336 /*
2337  * Called by the ioctl to find the corresponding
2338  * spooldoc node.  removes node on success
2339  *
2340  * Return values
2341  * rc
2342  * B_FALSE - not found
2343  * B_TRUE  - found
2344  *
2345  */
2346 
2347 static boolean_t
2348 smb_spool_lookup_doc_byfid(smb_server_t *sv, uint16_t fid,
2349     smb_kspooldoc_t *spdoc)
2350 {
2351 	smb_kspooldoc_t *sp;
2352 	smb_llist_t	*splist;
2353 
2354 	splist = &sv->sp_info.sp_list;
2355 	smb_llist_enter(splist, RW_WRITER);
2356 	sp = smb_llist_head(splist);
2357 	while (sp != NULL) {
2358 		/*
2359 		 * check for a matching fid
2360 		 */
2361 		if (sp->sd_fid == fid) {
2362 			*spdoc = *sp;
2363 			smb_llist_remove(splist, sp);
2364 			smb_llist_exit(splist);
2365 			kmem_free(sp, sizeof (smb_kspooldoc_t));
2366 			return (B_TRUE);
2367 		}
2368 		sp = smb_llist_next(splist, sp);
2369 	}
2370 	cmn_err(CE_WARN, "smb_spool_lookup_user_byfid: no fid:%d", fid);
2371 	smb_llist_exit(splist);
2372 	return (B_FALSE);
2373 }
2374 
2375 /*
2376  * Adds the spool fid to a linked list to be used
2377  * as a search key in the spooldoc queue
2378  *
2379  * Return values
2380  *      rc non-zero error
2381  *	rc zero success
2382  *
2383  */
2384 
2385 void
2386 smb_spool_add_fid(smb_server_t *sv, uint16_t fid)
2387 {
2388 	smb_llist_t	*fidlist;
2389 	smb_spoolfid_t  *sf;
2390 
2391 	if (sv->sv_cfg.skc_print_enable == 0)
2392 		return;
2393 
2394 	sf = kmem_zalloc(sizeof (smb_spoolfid_t), KM_SLEEP);
2395 	fidlist = &sv->sp_info.sp_fidlist;
2396 	smb_llist_enter(fidlist, RW_WRITER);
2397 	sf->sf_fid = fid;
2398 	smb_llist_insert_tail(fidlist, sf);
2399 	smb_llist_exit(fidlist);
2400 	cv_broadcast(&sv->sp_info.sp_cv);
2401 }
2402 
2403 /*
2404  * Called by the ioctl to get and remove the head of the fid list
2405  *
2406  * Return values
2407  * int fd
2408  * greater than 0 success
2409  * 0 - error
2410  *
2411  */
2412 
2413 static uint16_t
2414 smb_spool_get_fid(smb_server_t *sv)
2415 {
2416 	smb_spoolfid_t	*spfid;
2417 	smb_llist_t	*splist;
2418 	uint16_t	fid;
2419 
2420 	splist = &sv->sp_info.sp_fidlist;
2421 	smb_llist_enter(splist, RW_WRITER);
2422 	spfid = smb_llist_head(splist);
2423 	if (spfid != NULL) {
2424 		fid = spfid->sf_fid;
2425 		smb_llist_remove(&sv->sp_info.sp_fidlist, spfid);
2426 		kmem_free(spfid, sizeof (smb_spoolfid_t));
2427 	} else {
2428 		fid = 0;
2429 	}
2430 	smb_llist_exit(splist);
2431 	return (fid);
2432 }
2433 
2434 /*
2435  * Adds the spooldoc to the tail of the spooldoc list
2436  *
2437  * Return values
2438  *      rc non-zero error
2439  *	rc zero success
2440  */
2441 int
2442 smb_spool_add_doc(smb_tree_t *tree, smb_kspooldoc_t *sp)
2443 {
2444 	smb_llist_t	*splist;
2445 	smb_server_t	*sv = tree->t_server;
2446 	int rc = 0;
2447 
2448 	splist = &sv->sp_info.sp_list;
2449 	smb_llist_enter(splist, RW_WRITER);
2450 	sp->sd_spool_num = atomic_inc_32_nv(&sv->sp_info.sp_cnt);
2451 	smb_llist_insert_tail(splist, sp);
2452 	smb_llist_exit(splist);
2453 
2454 	return (rc);
2455 }
2456 
2457 /*
2458  * smb_server_create_session
2459  */
2460 static void
2461 smb_server_create_session(smb_listener_daemon_t *ld, ksocket_t s_so)
2462 {
2463 	smb_session_t		*session;
2464 	taskqid_t		tqid;
2465 	smb_llist_t		*sl;
2466 	smb_server_t		*sv = ld->ld_sv;
2467 
2468 	session = smb_session_create(s_so, ld->ld_port, sv,
2469 	    ld->ld_family);
2470 
2471 	if (session == NULL) {
2472 		smb_soshutdown(s_so);
2473 		smb_sodestroy(s_so);
2474 		cmn_err(CE_WARN, "SMB Session: alloc failed");
2475 		return;
2476 	}
2477 
2478 	sl = &sv->sv_session_list;
2479 	smb_llist_enter(sl, RW_WRITER);
2480 	smb_llist_insert_tail(sl, session);
2481 	smb_llist_exit(sl);
2482 
2483 	/*
2484 	 * These taskq entries must run independently of one another,
2485 	 * so TQ_NOQUEUE.  TQ_SLEEP (==0) just for clarity.
2486 	 */
2487 	tqid = taskq_dispatch(sv->sv_receiver_pool,
2488 	    smb_server_receiver, session, TQ_NOQUEUE | TQ_SLEEP);
2489 	if (tqid == TASKQID_INVALID) {
2490 		smb_session_disconnect(session);
2491 		smb_server_destroy_session(session);
2492 		cmn_err(CE_WARN, "SMB Session: taskq_dispatch failed");
2493 		return;
2494 	}
2495 	/* handy for debugging */
2496 	session->s_receiver_tqid = tqid;
2497 }
2498 
2499 static void
2500 smb_server_destroy_session(smb_session_t *session)
2501 {
2502 	smb_server_t *sv;
2503 	smb_llist_t *ll;
2504 	uint32_t count;
2505 
2506 	ASSERT(session->s_server != NULL);
2507 	sv = session->s_server;
2508 	ll = &sv->sv_session_list;
2509 
2510 	smb_llist_flush(&session->s_tree_list);
2511 	smb_llist_flush(&session->s_user_list);
2512 
2513 	/*
2514 	 * The user and tree lists should be empty now.
2515 	 */
2516 #ifdef DEBUG
2517 	if (session->s_user_list.ll_count != 0) {
2518 		cmn_err(CE_WARN, "user list not empty?");
2519 		debug_enter("s_user_list");
2520 	}
2521 	if (session->s_tree_list.ll_count != 0) {
2522 		cmn_err(CE_WARN, "tree list not empty?");
2523 		debug_enter("s_tree_list");
2524 	}
2525 #endif
2526 
2527 	smb_llist_enter(ll, RW_WRITER);
2528 	smb_llist_remove(ll, session);
2529 	count = ll->ll_count;
2530 	smb_llist_exit(ll);
2531 
2532 	smb_session_delete(session);
2533 	if (count == 0) {
2534 		/* See smb_server_shutdown */
2535 		cv_signal(&sv->sv_cv);
2536 	}
2537 }
2538