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
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
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
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
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
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
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
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
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
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
771 smb_server_cancel_event(smb_server_t *sv, uint32_t txid)
772 {
773 smb_event_cancel(sv, txid);
774 }
775
776 int
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 *
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
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
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
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
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
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
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
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
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
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
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
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
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 }