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