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