1faa1795aSjb /*
2faa1795aSjb * CDDL HEADER START
3faa1795aSjb *
4faa1795aSjb * The contents of this file are subject to the terms of the
5faa1795aSjb * Common Development and Distribution License (the "License").
6faa1795aSjb * You may not use this file except in compliance with the License.
7faa1795aSjb *
8faa1795aSjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9faa1795aSjb * or http://www.opensolaris.org/os/licensing.
10faa1795aSjb * See the License for the specific language governing permissions
11faa1795aSjb * and limitations under the License.
12faa1795aSjb *
13faa1795aSjb * When distributing Covered Code, include this CDDL HEADER in each
14faa1795aSjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15faa1795aSjb * If applicable, add the following below this CDDL HEADER, with the
16faa1795aSjb * fields enclosed by brackets "[]" replaced with your own identifying
17faa1795aSjb * information: Portions Copyright [yyyy] [name of copyright owner]
18faa1795aSjb *
19faa1795aSjb * CDDL HEADER END
20faa1795aSjb */
21faa1795aSjb /*
22c5866007SKeyur Desai * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
23adc68ba9SPavel Zakharov * Copyright (c) 2017 by Delphix. All rights reserved.
24896d9552SGordon Ross * Copyright 2019 Nexenta by DDN, Inc. All rights reserved.
255d8538b6SGordon Ross * Copyright 2021-2023 RackTop Systems, Inc.
26faa1795aSjb */
27faa1795aSjb
28faa1795aSjb /*
29faa1795aSjb * General Structures Layout
30faa1795aSjb * -------------------------
31faa1795aSjb *
32faa1795aSjb * This is a simplified diagram showing the relationship between most of the
33faa1795aSjb * main structures.
34faa1795aSjb *
35faa1795aSjb * +-------------------+
36faa1795aSjb * | SMB_SERVER |
37faa1795aSjb * +-------------------+
38faa1795aSjb * |
39faa1795aSjb * |
40faa1795aSjb * v
41faa1795aSjb * +-------------------+ +-------------------+ +-------------------+
42faa1795aSjb * | SESSION |<----->| SESSION |......| SESSION |
43faa1795aSjb * +-------------------+ +-------------------+ +-------------------+
44faa1795aSjb * |
45faa1795aSjb * |
46faa1795aSjb * v
47faa1795aSjb * +-------------------+ +-------------------+ +-------------------+
48faa1795aSjb * | USER |<----->| USER |......| USER |
49faa1795aSjb * +-------------------+ +-------------------+ +-------------------+
50faa1795aSjb * |
51faa1795aSjb * |
52faa1795aSjb * v
53faa1795aSjb * +-------------------+ +-------------------+ +-------------------+
54faa1795aSjb * | TREE |<----->| TREE |......| TREE |
55faa1795aSjb * +-------------------+ +-------------------+ +-------------------+
56faa1795aSjb * | |
57faa1795aSjb * | |
58faa1795aSjb * | v
59faa1795aSjb * | +-------+ +-------+ +-------+
60faa1795aSjb * | | OFILE |<----->| OFILE |......| OFILE |
61faa1795aSjb * | +-------+ +-------+ +-------+
62faa1795aSjb * |
63faa1795aSjb * |
64faa1795aSjb * v
65faa1795aSjb * +-------+ +------+ +------+
66faa1795aSjb * | ODIR |<----->| ODIR |......| ODIR |
67faa1795aSjb * +-------+ +------+ +------+
68faa1795aSjb *
69faa1795aSjb *
70faa1795aSjb * Module Interface Overview
71faa1795aSjb * -------------------------
72faa1795aSjb *
73faa1795aSjb *
74faa1795aSjb * +===================================+
75faa1795aSjb * | smbd daemon |
76faa1795aSjb * +===================================+
77faa1795aSjb * | | ^
78faa1795aSjb * | | |
79faa1795aSjb * User | | |
80faa1795aSjb * -----------|--------------|----------------|--------------------------------
81faa1795aSjb * Kernel | | |
82faa1795aSjb * | | |
83faa1795aSjb * | | |
84faa1795aSjb * +=========|==============|================|=================+
85faa1795aSjb * | v v | |
86faa1795aSjb * | +-----------+ +--------------------+ +------------------+ |
87faa1795aSjb * | | IO | | Kernel Door Server | | User Door Servers| |
88faa1795aSjb * | | Interface | | Interface | | Interface | |
89faa1795aSjb * | +-----------+ +--------------------+ +------------------+ |
90faa1795aSjb * | | | ^ ^ |
91faa1795aSjb * | v v | | | +=========+
92faa1795aSjb * | +-----------------------------------+ | | | |
93faa1795aSjb * | + SMB Server Management (this file) |<------------------| ZFS |
94faa1795aSjb * | +-----------------------------------+ | | | |
95faa1795aSjb * | | | | Module |
96faa1795aSjb * | +-----------------------------------+ | | | |
97faa1795aSjb * | + SMB Server Internal Layers |------+ | +=========+
98faa1795aSjb * | +-----------------------------------+ |
99faa1795aSjb * | |
100faa1795aSjb * | |
101faa1795aSjb * +===========================================================+
102faa1795aSjb *
103faa1795aSjb *
104faa1795aSjb * Server State Machine
105faa1795aSjb * --------------------
106faa1795aSjb * |
107faa1795aSjb * | T0
108faa1795aSjb * |
109faa1795aSjb * v
110faa1795aSjb * +-----------------------------+
111faa1795aSjb * | SMB_SERVER_STATE_CREATED |
112faa1795aSjb * +-----------------------------+
113faa1795aSjb * |
114faa1795aSjb * | T1
115faa1795aSjb * |
116faa1795aSjb * v
117faa1795aSjb * +-----------------------------+
118faa1795aSjb * | SMB_SERVER_STATE_CONFIGURED |
119faa1795aSjb * +-----------------------------+
120faa1795aSjb * |
121faa1795aSjb * | T2
122faa1795aSjb * |
123faa1795aSjb * v
124faa1795aSjb * +-----------------------------+
1259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * | SMB_SERVER_STATE_RUNNING / |
1269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * | SMB_SERVER_STATE_STOPPING |
127faa1795aSjb * +-----------------------------+
128faa1795aSjb * |
129faa1795aSjb * | T3
130faa1795aSjb * |
131faa1795aSjb * v
132faa1795aSjb * +-----------------------------+
133faa1795aSjb * | SMB_SERVER_STATE_DELETING |
134faa1795aSjb * +-----------------------------+
135faa1795aSjb * |
136faa1795aSjb * |
137faa1795aSjb * |
138faa1795aSjb * v
139faa1795aSjb *
140faa1795aSjb * States
141faa1795aSjb * ------
142faa1795aSjb *
143faa1795aSjb * SMB_SERVER_STATE_CREATED
144faa1795aSjb *
145faa1795aSjb * This is the state of the server just after creation.
146faa1795aSjb *
147faa1795aSjb * SMB_SERVER_STATE_CONFIGURED
148faa1795aSjb *
149faa1795aSjb * The server has been configured.
150faa1795aSjb *
151faa1795aSjb * SMB_SERVER_STATE_RUNNING
152faa1795aSjb *
153faa1795aSjb * The server has been started. While in this state the threads listening on
1544163af6aSjose borrego * the sockets are started.
155faa1795aSjb *
1564163af6aSjose borrego * When a client establishes a connection the thread listening dispatches
1574163af6aSjose borrego * a task with the new session as an argument. If the dispatch fails the new
1584163af6aSjose borrego * session context is destroyed.
159faa1795aSjb *
160faa1795aSjb * SMB_SERVER_STATE_STOPPING
161faa1795aSjb *
162faa1795aSjb * The threads listening on the NBT and TCP sockets are being terminated.
163faa1795aSjb *
164faa1795aSjb *
165faa1795aSjb * Transitions
166faa1795aSjb * -----------
167faa1795aSjb *
168faa1795aSjb * Transition T0
169faa1795aSjb *
170faa1795aSjb * The daemon smbd triggers its creation by opening the smbsrv device. If
171faa1795aSjb * the zone where the daemon lives doesn't have an smb server yet it is
172faa1795aSjb * created.
173faa1795aSjb *
174faa1795aSjb * smb_drv_open() --> smb_server_create()
175faa1795aSjb *
176faa1795aSjb * Transition T1
177faa1795aSjb *
178faa1795aSjb * This transition occurs in smb_server_configure(). It is triggered by the
179faa1795aSjb * daemon through an Ioctl.
180faa1795aSjb *
181faa1795aSjb * smb_drv_ioctl(SMB_IOC_CONFIG) --> smb_server_configure()
182faa1795aSjb *
183faa1795aSjb * Transition T2
184faa1795aSjb *
185faa1795aSjb * This transition occurs in smb_server_start(). It is triggered by the
186faa1795aSjb * daemon through an Ioctl.
187faa1795aSjb *
188faa1795aSjb * smb_drv_ioctl(SMB_IOC_START) --> smb_server_start()
189faa1795aSjb *
190faa1795aSjb * Transition T3
191faa1795aSjb *
192faa1795aSjb * This transition occurs in smb_server_delete(). It is triggered by the
193faa1795aSjb * daemon when closing the smbsrv device
194faa1795aSjb *
195faa1795aSjb * smb_drv_close() --> smb_server_delete()
196faa1795aSjb *
197faa1795aSjb * Comments
198faa1795aSjb * --------
199faa1795aSjb *
200faa1795aSjb * This files assumes that there will one SMB server per zone. For now the
201faa1795aSjb * smb server works only in global zone. There's nothing in this file preventing
202faa1795aSjb * an smb server from being created in a non global zone. That limitation is
203faa1795aSjb * enforced in user space.
204faa1795aSjb */
205faa1795aSjb
206faa1795aSjb #include <sys/cmn_err.h>
207faa1795aSjb #include <sys/priv.h>
208faa1795aSjb #include <sys/zone.h>
2095d8538b6SGordon Ross #include <sys/sysmacros.h>
2105d8538b6SGordon Ross #include <sys/callb.h>
2115d8538b6SGordon Ross #include <sys/class.h>
2125d8538b6SGordon Ross #include <sys/disp.h>
213bbf6f00cSJordan Brown #include <netinet/in.h>
214bbf6f00cSJordan Brown #include <netinet/in_systm.h>
215bbf6f00cSJordan Brown #include <netinet/ip.h>
216bbf6f00cSJordan Brown #include <netinet/ip_icmp.h>
217bbf6f00cSJordan Brown #include <netinet/ip_var.h>
218bbf6f00cSJordan Brown #include <netinet/tcp.h>
219a90cf9f2SGordon Ross #include <smbsrv/smb2_kproto.h>
220bbf6f00cSJordan Brown #include <smbsrv/string.h>
221faa1795aSjb #include <smbsrv/netbios.h>
222faa1795aSjb #include <smbsrv/smb_fsops.h>
2233db3f65cSamw #include <smbsrv/smb_share.h>
2249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smb_door.h>
2256537f381Sas #include <smbsrv/smb_kstat.h>
226faa1795aSjb
227148c5f43SAlan Wright static void smb_server_kstat_init(smb_server_t *);
228faa1795aSjb static void smb_server_kstat_fini(smb_server_t *);
229faa1795aSjb static void smb_server_timers(smb_thread_t *, void *);
23029bd2886SAlan Wright static void smb_server_store_cfg(smb_server_t *, smb_ioc_cfg_t *);
2319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_server_shutdown(smb_server_t *);
232faa1795aSjb static int smb_server_fsop_start(smb_server_t *);
233faa1795aSjb static void smb_server_fsop_stop(smb_server_t *);
2349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_event_cancel(smb_server_t *, uint32_t);
2359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static uint32_t smb_event_alloc_txid(void);
236faa1795aSjb
2378d94f651SGordon Ross static void smb_server_disconnect_share(smb_server_t *, const char *);
2388d94f651SGordon Ross static void smb_server_enum_users(smb_server_t *, smb_svcenum_t *);
2398d94f651SGordon Ross static void smb_server_enum_trees(smb_server_t *, smb_svcenum_t *);
2408d94f651SGordon Ross static int smb_server_session_disconnect(smb_server_t *, const char *,
2411fcced4cSJordan Brown const char *);
2428d94f651SGordon Ross static int smb_server_fclose(smb_server_t *, uint32_t);
243148c5f43SAlan Wright static int smb_server_kstat_update(kstat_t *, int);
244cb174861Sjoyce mcintosh static int smb_server_legacy_kstat_update(kstat_t *, int);
2454163af6aSjose borrego static void smb_server_listener_init(smb_server_t *, smb_listener_daemon_t *,
2464163af6aSjose borrego char *, in_port_t, int);
2474163af6aSjose borrego static void smb_server_listener_destroy(smb_listener_daemon_t *);
2484163af6aSjose borrego static int smb_server_listener_start(smb_listener_daemon_t *);
2494163af6aSjose borrego static void smb_server_listener_stop(smb_listener_daemon_t *);
2504163af6aSjose borrego static void smb_server_listener(smb_thread_t *, void *);
2514163af6aSjose borrego static void smb_server_receiver(void *);
2524163af6aSjose borrego static void smb_server_create_session(smb_listener_daemon_t *, ksocket_t);
253811599a4SMatt Barden static void smb_server_destroy_session(smb_session_t *);
25423a9c295SGordon Ross static uint16_t smb_spool_get_fid(smb_server_t *);
25523a9c295SGordon Ross static boolean_t smb_spool_lookup_doc_byfid(smb_server_t *, uint16_t,
25623a9c295SGordon Ross smb_kspooldoc_t *);
2571fcced4cSJordan Brown
2585d8538b6SGordon Ross #ifdef _KERNEL
2595d8538b6SGordon Ross int smb_create_process = 1;
2605d8538b6SGordon Ross static void smb_server_delproc(smb_server_t *);
2615d8538b6SGordon Ross static int smb_server_newproc(smb_server_t *);
2625d8538b6SGordon Ross static void smb_server_proc_main(void *);
2635d8538b6SGordon Ross #endif
2645d8538b6SGordon Ross
265811599a4SMatt Barden /*
266811599a4SMatt Barden * How many "buckets" should our hash tables use? On a "real" server,
267811599a4SMatt Barden * make them much larger than the number of CPUs we're likely to have.
268811599a4SMatt Barden * On "fksmbd" make it smaller so dtrace logs are shorter.
269811599a4SMatt Barden * These must be powers of two.
270811599a4SMatt Barden */
271811599a4SMatt Barden #ifdef _KERNEL
272811599a4SMatt Barden #define DEFAULT_HASH_NBUCKETS 256 /* real server */
273811599a4SMatt Barden #else
274811599a4SMatt Barden #define DEFAULT_HASH_NBUCKETS 16 /* for "fksmbd" */
275811599a4SMatt Barden #endif
276811599a4SMatt Barden uint32_t SMB_OFILE_HASH_NBUCKETS = DEFAULT_HASH_NBUCKETS;
277811599a4SMatt Barden uint32_t SMB_LEASE_HASH_NBUCKETS = DEFAULT_HASH_NBUCKETS;
278811599a4SMatt Barden
2799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int smb_event_debug = 0;
2809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
281faa1795aSjb static smb_llist_t smb_servers;
282faa1795aSjb
2837f5d80fdSGordon Ross /* for smb_server_destroy_session() */
2847f5d80fdSGordon Ross static smb_llist_t smb_server_session_zombies;
2857f5d80fdSGordon Ross
2868622ec45SGordon Ross kmem_cache_t *smb_cache_request;
2878622ec45SGordon Ross kmem_cache_t *smb_cache_session;
2888622ec45SGordon Ross kmem_cache_t *smb_cache_user;
2898622ec45SGordon Ross kmem_cache_t *smb_cache_tree;
2908622ec45SGordon Ross kmem_cache_t *smb_cache_ofile;
2918622ec45SGordon Ross kmem_cache_t *smb_cache_odir;
2928622ec45SGordon Ross kmem_cache_t *smb_cache_opipe;
2938622ec45SGordon Ross kmem_cache_t *smb_cache_event;
2940897f7fbSGordon Ross kmem_cache_t *smb_cache_lock;
2958622ec45SGordon Ross
296faa1795aSjb /*
297faa1795aSjb * *****************************************************************************
298faa1795aSjb * **************** Functions called from the device interface *****************
299faa1795aSjb * *****************************************************************************
300faa1795aSjb *
3011fcced4cSJordan Brown * These functions typically have to determine the relevant smb server
3021fcced4cSJordan Brown * to which the call applies.
303faa1795aSjb */
304faa1795aSjb
305a90cf9f2SGordon Ross /*
306a90cf9f2SGordon Ross * How many zones have an SMB server active?
307a90cf9f2SGordon Ross */
308a90cf9f2SGordon Ross int
smb_server_get_count(void)309a90cf9f2SGordon Ross smb_server_get_count(void)
310a90cf9f2SGordon Ross {
311a90cf9f2SGordon Ross return (smb_llist_get_count(&smb_servers));
312a90cf9f2SGordon Ross }
313a90cf9f2SGordon Ross
314faa1795aSjb /*
3158622ec45SGordon Ross * smb_server_g_init
316faa1795aSjb *
317c8ec8eeaSjose borrego * This function must be called from smb_drv_attach().
318faa1795aSjb */
319faa1795aSjb int
smb_server_g_init(void)3208622ec45SGordon Ross smb_server_g_init(void)
321faa1795aSjb {
3228622ec45SGordon Ross int rc;
323faa1795aSjb
3248622ec45SGordon Ross if ((rc = smb_vop_init()) != 0)
3258622ec45SGordon Ross goto errout;
3268622ec45SGordon Ross if ((rc = smb_fem_init()) != 0)
3278622ec45SGordon Ross goto errout;
3289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
3298622ec45SGordon Ross smb_kshare_g_init();
3308622ec45SGordon Ross smb_codepage_init();
3318622ec45SGordon Ross smb_mbc_init(); /* smb_mbc_cache */
3328622ec45SGordon Ross smb_node_init(); /* smb_node_cache, lists */
33394047d49SGordon Ross smb2_lease_init();
3348622ec45SGordon Ross
3358622ec45SGordon Ross smb_cache_request = kmem_cache_create("smb_request_cache",
3368622ec45SGordon Ross sizeof (smb_request_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
3378622ec45SGordon Ross smb_cache_session = kmem_cache_create("smb_session_cache",
3388622ec45SGordon Ross sizeof (smb_session_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
3398622ec45SGordon Ross smb_cache_user = kmem_cache_create("smb_user_cache",
3408622ec45SGordon Ross sizeof (smb_user_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
3418622ec45SGordon Ross smb_cache_tree = kmem_cache_create("smb_tree_cache",
3428622ec45SGordon Ross sizeof (smb_tree_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
3438622ec45SGordon Ross smb_cache_ofile = kmem_cache_create("smb_ofile_cache",
3448622ec45SGordon Ross sizeof (smb_ofile_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
3458622ec45SGordon Ross smb_cache_odir = kmem_cache_create("smb_odir_cache",
3468622ec45SGordon Ross sizeof (smb_odir_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
3478622ec45SGordon Ross smb_cache_opipe = kmem_cache_create("smb_opipe_cache",
3488622ec45SGordon Ross sizeof (smb_opipe_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
3498622ec45SGordon Ross smb_cache_event = kmem_cache_create("smb_event_cache",
3508622ec45SGordon Ross sizeof (smb_event_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
3510897f7fbSGordon Ross smb_cache_lock = kmem_cache_create("smb_lock_cache",
3520897f7fbSGordon Ross sizeof (smb_lock_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
3538622ec45SGordon Ross
3548622ec45SGordon Ross smb_llist_init();
3558622ec45SGordon Ross smb_llist_constructor(&smb_servers, sizeof (smb_server_t),
3568622ec45SGordon Ross offsetof(smb_server_t, sv_lnd));
3578622ec45SGordon Ross
3587f5d80fdSGordon Ross smb_llist_constructor(&smb_server_session_zombies,
3597f5d80fdSGordon Ross sizeof (smb_session_t), offsetof(smb_session_t, s_lnd));
3607f5d80fdSGordon Ross
3618622ec45SGordon Ross return (0);
3628622ec45SGordon Ross
3638622ec45SGordon Ross errout:
364faa1795aSjb smb_fem_fini();
365faa1795aSjb smb_vop_fini();
366faa1795aSjb return (rc);
367faa1795aSjb }
368faa1795aSjb
369faa1795aSjb /*
3708622ec45SGordon Ross * smb_server_g_fini
371faa1795aSjb *
372faa1795aSjb * This function must called from smb_drv_detach(). It will fail if servers
373faa1795aSjb * still exist.
374faa1795aSjb */
375a90cf9f2SGordon Ross void
smb_server_g_fini(void)3768622ec45SGordon Ross smb_server_g_fini(void)
3778622ec45SGordon Ross {
3788622ec45SGordon Ross
379a90cf9f2SGordon Ross ASSERT(smb_llist_get_count(&smb_servers) == 0);
380a90cf9f2SGordon Ross
3818622ec45SGordon Ross smb_llist_fini();
3828622ec45SGordon Ross
3838622ec45SGordon Ross kmem_cache_destroy(smb_cache_request);
3848622ec45SGordon Ross kmem_cache_destroy(smb_cache_session);
3858622ec45SGordon Ross kmem_cache_destroy(smb_cache_user);
3868622ec45SGordon Ross kmem_cache_destroy(smb_cache_tree);
3878622ec45SGordon Ross kmem_cache_destroy(smb_cache_ofile);
3888622ec45SGordon Ross kmem_cache_destroy(smb_cache_odir);
3898622ec45SGordon Ross kmem_cache_destroy(smb_cache_opipe);
3908622ec45SGordon Ross kmem_cache_destroy(smb_cache_event);
3910897f7fbSGordon Ross kmem_cache_destroy(smb_cache_lock);
3928622ec45SGordon Ross
39394047d49SGordon Ross smb2_lease_fini();
3948622ec45SGordon Ross smb_node_fini();
3958622ec45SGordon Ross smb_mbc_fini();
396adc68ba9SPavel Zakharov smb_codepage_fini();
3978622ec45SGordon Ross smb_kshare_g_fini();
3988622ec45SGordon Ross
3998622ec45SGordon Ross smb_fem_fini();
4008622ec45SGordon Ross smb_vop_fini();
4018622ec45SGordon Ross
4028622ec45SGordon Ross smb_llist_destructor(&smb_servers);
403faa1795aSjb }
404faa1795aSjb
405faa1795aSjb /*
406faa1795aSjb * smb_server_create
407faa1795aSjb *
4085d8538b6SGordon Ross * Called by driver open
4095d8538b6SGordon Ross *
410faa1795aSjb * This function will fail if there's already a server associated with the
411faa1795aSjb * caller's zone.
4125d8538b6SGordon Ross *
4135d8538b6SGordon Ross * This object is one-to-one with zones, so we could instead
4145d8538b6SGordon Ross * create/destroy this via zone_key_create callbacks.
4155d8538b6SGordon Ross * See smb_server_delete() for destruction.
416faa1795aSjb */
417faa1795aSjb int
smb_server_create(dev_t dev)418*34bbc83aSGordon Ross smb_server_create(dev_t dev)
419faa1795aSjb {
420faa1795aSjb zoneid_t zid;
421faa1795aSjb smb_server_t *sv;
422faa1795aSjb
423faa1795aSjb zid = getzoneid();
424faa1795aSjb
425faa1795aSjb smb_llist_enter(&smb_servers, RW_WRITER);
426faa1795aSjb sv = smb_llist_head(&smb_servers);
427*34bbc83aSGordon Ross while (sv != NULL) {
4289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv);
429faa1795aSjb if (sv->sv_zid == zid) {
430faa1795aSjb smb_llist_exit(&smb_servers);
431*34bbc83aSGordon Ross return (SET_ERROR(EBUSY));
432faa1795aSjb }
433faa1795aSjb sv = smb_llist_next(&smb_servers, sv);
434faa1795aSjb }
435faa1795aSjb
4368622ec45SGordon Ross sv = kmem_zalloc(sizeof (smb_server_t), KM_SLEEP);
4378622ec45SGordon Ross
4388622ec45SGordon Ross sv->sv_magic = SMB_SERVER_MAGIC;
4398622ec45SGordon Ross sv->sv_state = SMB_SERVER_STATE_CREATED;
4408622ec45SGordon Ross sv->sv_zid = zid;
441b819cea2SGordon Ross sv->sv_pid = ddi_get_pid();
442*34bbc83aSGordon Ross sv->sv_dev = dev;
4435d8538b6SGordon Ross sv->sv_proc_state = SMB_THREAD_STATE_EXITED;
4448622ec45SGordon Ross
4458622ec45SGordon Ross mutex_init(&sv->sv_mutex, NULL, MUTEX_DEFAULT, NULL);
4468622ec45SGordon Ross cv_init(&sv->sv_cv, NULL, CV_DEFAULT, NULL);
4478622ec45SGordon Ross cv_init(&sv->sp_info.sp_cv, NULL, CV_DEFAULT, NULL);
448faa1795aSjb
449811599a4SMatt Barden sv->sv_persistid_ht = smb_hash_create(sizeof (smb_ofile_t),
450811599a4SMatt Barden offsetof(smb_ofile_t, f_dh_lnd), SMB_OFILE_HASH_NBUCKETS);
451811599a4SMatt Barden
45294047d49SGordon Ross sv->sv_lease_ht = smb_hash_create(sizeof (smb_lease_t),
45394047d49SGordon Ross offsetof(smb_lease_t, ls_lnd), SMB_LEASE_HASH_NBUCKETS);
45494047d49SGordon Ross
455811599a4SMatt Barden smb_llist_constructor(&sv->sv_session_list, sizeof (smb_session_t),
456811599a4SMatt Barden offsetof(smb_session_t, s_lnd));
457811599a4SMatt Barden
4589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_constructor(&sv->sv_event_list, sizeof (smb_event_t),
4599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States offsetof(smb_event_t, se_lnd));
4609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
461cb174861Sjoyce mcintosh smb_llist_constructor(&sv->sp_info.sp_list, sizeof (smb_kspooldoc_t),
462cb174861Sjoyce mcintosh offsetof(smb_kspooldoc_t, sd_lnd));
463cb174861Sjoyce mcintosh
464cb174861Sjoyce mcintosh smb_llist_constructor(&sv->sp_info.sp_fidlist,
465cb174861Sjoyce mcintosh sizeof (smb_spoolfid_t), offsetof(smb_spoolfid_t, sf_lnd));
466cb174861Sjoyce mcintosh
467a90cf9f2SGordon Ross sv->sv_disp_stats1 = kmem_zalloc(SMB_COM_NUM *
468a90cf9f2SGordon Ross sizeof (smb_disp_stats_t), KM_SLEEP);
469a90cf9f2SGordon Ross
470a90cf9f2SGordon Ross sv->sv_disp_stats2 = kmem_zalloc(SMB2__NCMDS *
4718622ec45SGordon Ross sizeof (smb_disp_stats_t), KM_SLEEP);
472faa1795aSjb
47308344b29SGordon Ross smb_thread_init(&sv->si_thread_timers, "smb_timers",
4745d8538b6SGordon Ross smb_server_timers, sv, smbsrv_timer_pri, sv);
475faa1795aSjb
476148c5f43SAlan Wright smb_srqueue_init(&sv->sv_srqueue);
477faa1795aSjb
4788622ec45SGordon Ross smb_kdoor_init(sv);
4798622ec45SGordon Ross smb_kshare_init(sv);
480148c5f43SAlan Wright smb_server_kstat_init(sv);
481faa1795aSjb
482856399cfSGordon Ross smb_threshold_init(&sv->sv_ssetup_ct, SMB_SSETUP_CMD,
483cb174861Sjoyce mcintosh smb_ssetup_threshold, smb_ssetup_timeout);
484856399cfSGordon Ross smb_threshold_init(&sv->sv_tcon_ct, SMB_TCON_CMD,
4858622ec45SGordon Ross smb_tcon_threshold, smb_tcon_timeout);
486856399cfSGordon Ross smb_threshold_init(&sv->sv_opipe_ct, SMB_OPIPE_CMD,
4878622ec45SGordon Ross smb_opipe_threshold, smb_opipe_timeout);
488a9609934SGordon Ross smb_threshold_init(&sv->sv_logoff_ct, SMB_LOGOFF_CMD,
489a9609934SGordon Ross smb_logoff_threshold, smb_logoff_timeout);
490cb174861Sjoyce mcintosh
491856399cfSGordon Ross smb_llist_insert_tail(&smb_servers, sv);
492856399cfSGordon Ross smb_llist_exit(&smb_servers);
493856399cfSGordon Ross
494faa1795aSjb return (0);
495faa1795aSjb }
496faa1795aSjb
497faa1795aSjb /*
498faa1795aSjb * smb_server_delete
499faa1795aSjb *
5005d8538b6SGordon Ross * Called by driver close
5015d8538b6SGordon Ross *
502faa1795aSjb * This function will delete the server passed in. It will make sure that all
503faa1795aSjb * activity associated that server has ceased before destroying it.
504faa1795aSjb */
505faa1795aSjb int
smb_server_delete(smb_server_t * sv)5068d94f651SGordon Ross smb_server_delete(smb_server_t *sv)
507faa1795aSjb {
508faa1795aSjb
509faa1795aSjb mutex_enter(&sv->sv_mutex);
510faa1795aSjb switch (sv->sv_state) {
511faa1795aSjb case SMB_SERVER_STATE_RUNNING:
5129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States sv->sv_state = SMB_SERVER_STATE_STOPPING;
513faa1795aSjb mutex_exit(&sv->sv_mutex);
5144163af6aSjose borrego smb_server_shutdown(sv);
515faa1795aSjb mutex_enter(&sv->sv_mutex);
5164163af6aSjose borrego cv_broadcast(&sv->sp_info.sp_cv);
5174163af6aSjose borrego sv->sv_state = SMB_SERVER_STATE_DELETING;
5184163af6aSjose borrego break;
5194163af6aSjose borrego case SMB_SERVER_STATE_STOPPING:
5204163af6aSjose borrego sv->sv_state = SMB_SERVER_STATE_DELETING;
521faa1795aSjb break;
522faa1795aSjb case SMB_SERVER_STATE_CONFIGURED:
523faa1795aSjb case SMB_SERVER_STATE_CREATED:
524faa1795aSjb sv->sv_state = SMB_SERVER_STATE_DELETING;
525faa1795aSjb break;
526faa1795aSjb default:
5279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_STATE_VALID(sv->sv_state);
528faa1795aSjb mutex_exit(&sv->sv_mutex);
529faa1795aSjb smb_server_release(sv);
530faa1795aSjb return (ENOTTY);
531faa1795aSjb }
532faa1795aSjb
533faa1795aSjb ASSERT(sv->sv_state == SMB_SERVER_STATE_DELETING);
534faa1795aSjb
535faa1795aSjb sv->sv_refcnt--;
536faa1795aSjb while (sv->sv_refcnt)
537faa1795aSjb cv_wait(&sv->sv_cv, &sv->sv_mutex);
538faa1795aSjb
539faa1795aSjb mutex_exit(&sv->sv_mutex);
540faa1795aSjb
541faa1795aSjb smb_llist_enter(&smb_servers, RW_WRITER);
542faa1795aSjb smb_llist_remove(&smb_servers, sv);
543faa1795aSjb smb_llist_exit(&smb_servers);
544faa1795aSjb
545856399cfSGordon Ross smb_threshold_fini(&sv->sv_ssetup_ct);
546856399cfSGordon Ross smb_threshold_fini(&sv->sv_tcon_ct);
547856399cfSGordon Ross smb_threshold_fini(&sv->sv_opipe_ct);
548a9609934SGordon Ross smb_threshold_fini(&sv->sv_logoff_ct);
549856399cfSGordon Ross
5504163af6aSjose borrego smb_server_listener_destroy(&sv->sv_nbt_daemon);
5514163af6aSjose borrego smb_server_listener_destroy(&sv->sv_tcp_daemon);
552faa1795aSjb rw_destroy(&sv->sv_cfg_lock);
553faa1795aSjb smb_server_kstat_fini(sv);
5548622ec45SGordon Ross smb_kshare_fini(sv);
5558622ec45SGordon Ross smb_kdoor_fini(sv);
5569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_destructor(&sv->sv_event_list);
557811599a4SMatt Barden smb_llist_destructor(&sv->sv_session_list);
5582c1b14e5Sjose borrego
559a90cf9f2SGordon Ross kmem_free(sv->sv_disp_stats1,
5608622ec45SGordon Ross SMB_COM_NUM * sizeof (smb_disp_stats_t));
561faa1795aSjb
562a90cf9f2SGordon Ross kmem_free(sv->sv_disp_stats2,
563a90cf9f2SGordon Ross SMB2__NCMDS * sizeof (smb_disp_stats_t));
564a90cf9f2SGordon Ross
565148c5f43SAlan Wright smb_srqueue_destroy(&sv->sv_srqueue);
566faa1795aSjb smb_thread_destroy(&sv->si_thread_timers);
5678622ec45SGordon Ross
568faa1795aSjb mutex_destroy(&sv->sv_mutex);
56994047d49SGordon Ross smb_hash_destroy(sv->sv_lease_ht);
570811599a4SMatt Barden smb_hash_destroy(sv->sv_persistid_ht);
571faa1795aSjb cv_destroy(&sv->sv_cv);
572faa1795aSjb sv->sv_magic = 0;
573faa1795aSjb kmem_free(sv, sizeof (smb_server_t));
574faa1795aSjb
575faa1795aSjb return (0);
576faa1795aSjb }
577faa1795aSjb
578faa1795aSjb /*
579faa1795aSjb * smb_server_configure
5805d8538b6SGordon Ross *
5815d8538b6SGordon Ross * Called via SMB_IOC_CONFIG, for smbd startup or refresh.
582faa1795aSjb */
583faa1795aSjb int
smb_server_configure(smb_server_t * sv,smb_ioc_cfg_t * ioc)584*34bbc83aSGordon Ross smb_server_configure(smb_server_t *sv, smb_ioc_cfg_t *ioc)
585faa1795aSjb {
586faa1795aSjb int rc = 0;
587faa1795aSjb
5881d443a93SDan McDonald /*
5891d443a93SDan McDonald * Reality check negotiation token length vs. #define'd maximum.
5901d443a93SDan McDonald */
5911d443a93SDan McDonald if (ioc->negtok_len > SMB_PI_MAX_NEGTOK)
5921d443a93SDan McDonald return (EINVAL);
5931d443a93SDan McDonald
594faa1795aSjb mutex_enter(&sv->sv_mutex);
595faa1795aSjb switch (sv->sv_state) {
596faa1795aSjb case SMB_SERVER_STATE_CREATED:
59729bd2886SAlan Wright smb_server_store_cfg(sv, ioc);
598faa1795aSjb sv->sv_state = SMB_SERVER_STATE_CONFIGURED;
599faa1795aSjb break;
600faa1795aSjb
601faa1795aSjb case SMB_SERVER_STATE_CONFIGURED:
60229bd2886SAlan Wright smb_server_store_cfg(sv, ioc);
603faa1795aSjb break;
604faa1795aSjb
605faa1795aSjb case SMB_SERVER_STATE_RUNNING:
6069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SERVER_STATE_STOPPING:
607faa1795aSjb rw_enter(&sv->sv_cfg_lock, RW_WRITER);
60829bd2886SAlan Wright smb_server_store_cfg(sv, ioc);
609faa1795aSjb rw_exit(&sv->sv_cfg_lock);
610faa1795aSjb break;
611faa1795aSjb
612faa1795aSjb default:
6139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_STATE_VALID(sv->sv_state);
614faa1795aSjb rc = EFAULT;
615faa1795aSjb break;
616faa1795aSjb }
617faa1795aSjb mutex_exit(&sv->sv_mutex);
618faa1795aSjb
619faa1795aSjb return (rc);
620faa1795aSjb }
621faa1795aSjb
622faa1795aSjb /*
623faa1795aSjb * smb_server_start
6245d8538b6SGordon Ross *
6255d8538b6SGordon Ross * Called via SMB_IOC_START during smbd startup.
6265d8538b6SGordon Ross * Bring up the activities requried for SMB service.
627faa1795aSjb */
628faa1795aSjb int
smb_server_start(smb_server_t * sv,smb_ioc_start_t * ioc)629*34bbc83aSGordon Ross smb_server_start(smb_server_t *sv, smb_ioc_start_t *ioc)
630faa1795aSjb {
631faa1795aSjb int rc = 0;
6324163af6aSjose borrego int family;
6338d94f651SGordon Ross cred_t *ucr;
6345d8538b6SGordon Ross struct proc *tqproc;
635faa1795aSjb
636faa1795aSjb mutex_enter(&sv->sv_mutex);
637faa1795aSjb switch (sv->sv_state) {
638faa1795aSjb case SMB_SERVER_STATE_CONFIGURED:
639faa1795aSjb
6405d8538b6SGordon Ross #ifdef _KERNEL
6415d8538b6SGordon Ross if (smb_create_process) {
6425d8538b6SGordon Ross rc = smb_server_newproc(sv);
6435d8538b6SGordon Ross if (rc != 0)
6445d8538b6SGordon Ross break;
6455d8538b6SGordon Ross }
6465d8538b6SGordon Ross #endif /* _KERNEL */
6475d8538b6SGordon Ross
6488622ec45SGordon Ross if ((rc = smb_server_fsop_start(sv)) != 0)
6498622ec45SGordon Ross break;
6508622ec45SGordon Ross
6518d94f651SGordon Ross /*
6528d94f651SGordon Ross * Note: smb_kshare_start needs sv_session.
6538d94f651SGordon Ross */
6548d94f651SGordon Ross sv->sv_session = smb_session_create(NULL, 0, sv, 0);
6558d94f651SGordon Ross if (sv->sv_session == NULL) {
6568d94f651SGordon Ross rc = ENOMEM;
6578d94f651SGordon Ross break;
6588d94f651SGordon Ross }
6598d94f651SGordon Ross
6608d94f651SGordon Ross /*
6618d94f651SGordon Ross * Create a logon on the server session,
6628d94f651SGordon Ross * used when importing CA shares.
6638d94f651SGordon Ross */
6648d94f651SGordon Ross sv->sv_rootuser = smb_user_new(sv->sv_session);
6658d94f651SGordon Ross ucr = smb_kcred_create();
6668d94f651SGordon Ross rc = smb_user_logon(sv->sv_rootuser, ucr, "", "root",
6678d94f651SGordon Ross SMB_USER_FLAG_ADMIN, 0, 0);
6688d94f651SGordon Ross crfree(ucr);
6698d94f651SGordon Ross ucr = NULL;
6708d94f651SGordon Ross if (rc != 0) {
6718d94f651SGordon Ross cmn_err(CE_NOTE, "smb_server_start: "
6728d94f651SGordon Ross "failed to create root user");
6738d94f651SGordon Ross break;
6748d94f651SGordon Ross }
6758d94f651SGordon Ross
6768622ec45SGordon Ross if ((rc = smb_kshare_start(sv)) != 0)
6778622ec45SGordon Ross break;
6788622ec45SGordon Ross
679b819cea2SGordon Ross /*
680e515d096SGordon Ross * Create our taskq's (thread pools)
681e515d096SGordon Ross *
682b819cea2SGordon Ross * NB: the proc passed here has to be a "system" one.
683b819cea2SGordon Ross * Normally that's p0, or the NGZ eqivalent.
684e515d096SGordon Ross *
685e515d096SGordon Ross * The notify pool is sized at a quarter the number of
686e515d096SGordon Ross * worker threads (instead of another config item).
687b819cea2SGordon Ross */
6885d8538b6SGordon Ross tqproc = (sv->sv_proc_p != NULL) ?
6895d8538b6SGordon Ross sv->sv_proc_p : curzone->zone_zsched;
6905d8538b6SGordon Ross
691e515d096SGordon Ross sv->sv_notify_pool = taskq_create_proc("smb_notify",
692e515d096SGordon Ross sv->sv_cfg.skc_maxworkers / 4, smbsrv_notify_pri,
693e515d096SGordon Ross sv->sv_cfg.skc_maxworkers / 4, INT_MAX,
694a02a2451SGordon Ross tqproc, TASKQ_DYNAMIC|TASKQ_THREADS_LWP);
695e515d096SGordon Ross
6968622ec45SGordon Ross sv->sv_worker_pool = taskq_create_proc("smb_workers",
69708344b29SGordon Ross sv->sv_cfg.skc_maxworkers, smbsrv_worker_pri,
698faa1795aSjb sv->sv_cfg.skc_maxworkers, INT_MAX,
699a02a2451SGordon Ross tqproc, TASKQ_DYNAMIC|TASKQ_THREADS_LWP);
700faa1795aSjb
7018622ec45SGordon Ross sv->sv_receiver_pool = taskq_create_proc("smb_receivers",
70208344b29SGordon Ross sv->sv_cfg.skc_maxconnections, smbsrv_receive_pri,
7034163af6aSjose borrego sv->sv_cfg.skc_maxconnections, INT_MAX,
704a02a2451SGordon Ross tqproc, TASKQ_DYNAMIC|TASKQ_THREADS_LWP);
7054163af6aSjose borrego
706e515d096SGordon Ross if (sv->sv_notify_pool == NULL ||
707e515d096SGordon Ross sv->sv_worker_pool == NULL ||
7088d94f651SGordon Ross sv->sv_receiver_pool == NULL) {
709faa1795aSjb rc = ENOMEM;
710faa1795aSjb break;
711faa1795aSjb }
712faa1795aSjb
713b819cea2SGordon Ross #ifdef _KERNEL
714faa1795aSjb ASSERT(sv->sv_lmshrd == NULL);
715148c5f43SAlan Wright sv->sv_lmshrd = smb_kshare_door_init(ioc->lmshrd);
716faa1795aSjb if (sv->sv_lmshrd == NULL)
717faa1795aSjb break;
71854026d5aSGordon Ross if ((rc = smb_kdoor_open(sv, ioc->udoor)) != 0) {
7199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cmn_err(CE_WARN, "Cannot open smbd door");
7202c1b14e5Sjose borrego break;
7219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
722b819cea2SGordon Ross #else /* _KERNEL */
723b819cea2SGordon Ross /* Fake kernel does not use the kshare_door */
724b819cea2SGordon Ross fksmb_kdoor_open(sv, ioc->udoor_func);
725b819cea2SGordon Ross #endif /* _KERNEL */
726b819cea2SGordon Ross
72754026d5aSGordon Ross if ((rc = smb_thread_start(&sv->si_thread_timers)) != 0)
7289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break;
7294163af6aSjose borrego
7304163af6aSjose borrego family = AF_INET;
7314163af6aSjose borrego smb_server_listener_init(sv, &sv->sv_nbt_daemon,
7324163af6aSjose borrego "smb_nbt_listener", IPPORT_NETBIOS_SSN, family);
7334163af6aSjose borrego if (sv->sv_cfg.skc_ipv6_enable)
7344163af6aSjose borrego family = AF_INET6;
7354163af6aSjose borrego smb_server_listener_init(sv, &sv->sv_tcp_daemon,
7364163af6aSjose borrego "smb_tcp_listener", IPPORT_SMB, family);
7374163af6aSjose borrego rc = smb_server_listener_start(&sv->sv_tcp_daemon);
7384163af6aSjose borrego if (rc != 0)
7394163af6aSjose borrego break;
74083d2dfe6SGordon Ross if (sv->sv_cfg.skc_netbios_enable)
74183d2dfe6SGordon Ross (void) smb_server_listener_start(&sv->sv_nbt_daemon);
7424163af6aSjose borrego
743faa1795aSjb sv->sv_state = SMB_SERVER_STATE_RUNNING;
744148c5f43SAlan Wright sv->sv_start_time = gethrtime();
745faa1795aSjb mutex_exit(&sv->sv_mutex);
7468622ec45SGordon Ross smb_export_start(sv);
747faa1795aSjb return (0);
748faa1795aSjb default:
7499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_STATE_VALID(sv->sv_state);
750faa1795aSjb mutex_exit(&sv->sv_mutex);
751faa1795aSjb return (ENOTTY);
752faa1795aSjb }
753faa1795aSjb
7549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&sv->sv_mutex);
7554163af6aSjose borrego smb_server_shutdown(sv);
7569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (rc);
7579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
7589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
7599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
7609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * An smbd is shutting down.
7619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */
7629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
smb_server_stop(smb_server_t * sv)763*34bbc83aSGordon Ross smb_server_stop(smb_server_t *sv)
7649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
7659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
7669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&sv->sv_mutex);
7679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States switch (sv->sv_state) {
7689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SERVER_STATE_RUNNING:
7699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States sv->sv_state = SMB_SERVER_STATE_STOPPING;
7704163af6aSjose borrego mutex_exit(&sv->sv_mutex);
7714163af6aSjose borrego smb_server_shutdown(sv);
7724163af6aSjose borrego mutex_enter(&sv->sv_mutex);
773cb174861Sjoyce mcintosh cv_broadcast(&sv->sp_info.sp_cv);
7749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break;
7759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States default:
7769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_STATE_VALID(sv->sv_state);
7779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break;
7789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
7799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&sv->sv_mutex);
7809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
7819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (0);
7829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
7839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
7849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States boolean_t
smb_server_is_stopping(smb_server_t * sv)7858622ec45SGordon Ross smb_server_is_stopping(smb_server_t *sv)
7869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
7879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States boolean_t status;
7889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
7899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv);
7909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
7919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&sv->sv_mutex);
7929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
7939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States switch (sv->sv_state) {
7949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SERVER_STATE_STOPPING:
7959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SERVER_STATE_DELETING:
7969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States status = B_TRUE;
7979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break;
7989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States default:
7999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States status = B_FALSE;
8009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break;
8019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
8029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
803faa1795aSjb mutex_exit(&sv->sv_mutex);
8049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (status);
8059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
8069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
8078622ec45SGordon Ross void
smb_server_cancel_event(smb_server_t * sv,uint32_t txid)8088622ec45SGordon Ross smb_server_cancel_event(smb_server_t *sv, uint32_t txid)
8099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
8108622ec45SGordon Ross smb_event_cancel(sv, txid);
8119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
8129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
8139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
smb_server_notify_event(smb_server_t * sv,smb_ioc_event_t * ioc)814*34bbc83aSGordon Ross smb_server_notify_event(smb_server_t *sv, smb_ioc_event_t *ioc)
8159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
8169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
817*34bbc83aSGordon Ross smb_event_notify(sv, ioc->txid);
8189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
819*34bbc83aSGordon Ross return (0);
820faa1795aSjb }
821faa1795aSjb
822cb174861Sjoyce mcintosh /*
823cb174861Sjoyce mcintosh * smb_server_spooldoc
824cb174861Sjoyce mcintosh *
825cb174861Sjoyce mcintosh * Waits for print file close broadcast.
826cb174861Sjoyce mcintosh * Gets the head of the fid list,
827cb174861Sjoyce mcintosh * then searches the spooldoc list and returns
828cb174861Sjoyce mcintosh * this info via the ioctl to user land.
829cb174861Sjoyce mcintosh *
830cb174861Sjoyce mcintosh * rc - 0 success
831cb174861Sjoyce mcintosh */
832cb174861Sjoyce mcintosh int
smb_server_spooldoc(smb_server_t * sv,smb_ioc_spooldoc_t * ioc)833*34bbc83aSGordon Ross smb_server_spooldoc(smb_server_t *sv, smb_ioc_spooldoc_t *ioc)
834cb174861Sjoyce mcintosh {
835*34bbc83aSGordon Ross int rc = 0;
836cb174861Sjoyce mcintosh smb_kspooldoc_t *spdoc;
837cb174861Sjoyce mcintosh uint16_t fid;
838cb174861Sjoyce mcintosh
839b7301bf5SGordon Ross if (sv->sv_cfg.skc_print_enable == 0) {
840b7301bf5SGordon Ross rc = ENOTTY;
841b7301bf5SGordon Ross goto out;
842b7301bf5SGordon Ross }
843b7301bf5SGordon Ross
84423a9c295SGordon Ross mutex_enter(&sv->sv_mutex);
84523a9c295SGordon Ross for (;;) {
846cb174861Sjoyce mcintosh if (sv->sv_state != SMB_SERVER_STATE_RUNNING) {
847cb174861Sjoyce mcintosh rc = ECANCELED;
84823a9c295SGordon Ross break;
84923a9c295SGordon Ross }
85023a9c295SGordon Ross if ((fid = smb_spool_get_fid(sv)) != 0) {
85123a9c295SGordon Ross rc = 0;
85223a9c295SGordon Ross break;
85323a9c295SGordon Ross }
85423a9c295SGordon Ross if (cv_wait_sig(&sv->sp_info.sp_cv, &sv->sv_mutex) == 0) {
85523a9c295SGordon Ross rc = EINTR;
85623a9c295SGordon Ross break;
857cb174861Sjoyce mcintosh }
858cb174861Sjoyce mcintosh }
85923a9c295SGordon Ross mutex_exit(&sv->sv_mutex);
860b7301bf5SGordon Ross if (rc != 0)
861b7301bf5SGordon Ross goto out;
862b7301bf5SGordon Ross
863b7301bf5SGordon Ross spdoc = kmem_zalloc(sizeof (*spdoc), KM_SLEEP);
864b7301bf5SGordon Ross if (smb_spool_lookup_doc_byfid(sv, fid, spdoc)) {
865b7301bf5SGordon Ross ioc->spool_num = spdoc->sd_spool_num;
866b7301bf5SGordon Ross ioc->ipaddr = spdoc->sd_ipaddr;
867b7301bf5SGordon Ross (void) strlcpy(ioc->path, spdoc->sd_path,
868b7301bf5SGordon Ross MAXPATHLEN);
869b7301bf5SGordon Ross (void) strlcpy(ioc->username,
870b7301bf5SGordon Ross spdoc->sd_username, MAXNAMELEN);
871b7301bf5SGordon Ross } else {
872b7301bf5SGordon Ross /* Did not find that print job. */
873b7301bf5SGordon Ross rc = EAGAIN;
87423a9c295SGordon Ross }
875b7301bf5SGordon Ross kmem_free(spdoc, sizeof (*spdoc));
87623a9c295SGordon Ross
877b7301bf5SGordon Ross out:
878cb174861Sjoyce mcintosh return (rc);
879cb174861Sjoyce mcintosh }
880cb174861Sjoyce mcintosh
881faa1795aSjb int
smb_server_set_gmtoff(smb_server_t * sv,smb_ioc_gmt_t * ioc)882*34bbc83aSGordon Ross smb_server_set_gmtoff(smb_server_t *sv, smb_ioc_gmt_t *ioc)
883faa1795aSjb {
884faa1795aSjb
885*34bbc83aSGordon Ross sv->si_gmtoff = ioc->offset;
886faa1795aSjb
887*34bbc83aSGordon Ross return (0);
888faa1795aSjb }
889faa1795aSjb
89029bd2886SAlan Wright int
smb_server_numopen(smb_server_t * sv,smb_ioc_opennum_t * ioc)891*34bbc83aSGordon Ross smb_server_numopen(smb_server_t *sv, smb_ioc_opennum_t *ioc)
89229bd2886SAlan Wright {
89329bd2886SAlan Wright
894*34bbc83aSGordon Ross ioc->open_users = sv->sv_users;
895*34bbc83aSGordon Ross ioc->open_trees = sv->sv_trees;
896*34bbc83aSGordon Ross ioc->open_files = sv->sv_files + sv->sv_pipes;
897*34bbc83aSGordon Ross
898*34bbc83aSGordon Ross return (0);
89929bd2886SAlan Wright }
90029bd2886SAlan Wright
9011fcced4cSJordan Brown /*
9021fcced4cSJordan Brown * Enumerate objects within the server. The svcenum provides the
9031fcced4cSJordan Brown * enumeration context, i.e. what the caller want to get back.
9041fcced4cSJordan Brown */
90529bd2886SAlan Wright int
smb_server_enum(smb_server_t * sv,smb_ioc_svcenum_t * ioc)906*34bbc83aSGordon Ross smb_server_enum(smb_server_t *sv, smb_ioc_svcenum_t *ioc)
90729bd2886SAlan Wright {
9084163af6aSjose borrego smb_svcenum_t *svcenum = &ioc->svcenum;
909*34bbc83aSGordon Ross int rc = 0;
91029bd2886SAlan Wright
9111d443a93SDan McDonald /*
9121d443a93SDan McDonald * Reality check that the buffer-length insize the enum doesn't
9131d443a93SDan McDonald * overrun the ioctl's total length.
9141d443a93SDan McDonald */
9151d443a93SDan McDonald if (svcenum->se_buflen + sizeof (*ioc) > ioc->hdr.len)
9161d443a93SDan McDonald return (EINVAL);
9171d443a93SDan McDonald
9181fcced4cSJordan Brown svcenum->se_bavail = svcenum->se_buflen;
9191fcced4cSJordan Brown svcenum->se_bused = 0;
9201fcced4cSJordan Brown svcenum->se_nitems = 0;
92129bd2886SAlan Wright
9223b13a1efSThomas Keiser switch (svcenum->se_type) {
9233b13a1efSThomas Keiser case SMB_SVCENUM_TYPE_USER:
9248d94f651SGordon Ross smb_server_enum_users(sv, svcenum);
9253b13a1efSThomas Keiser break;
9263b13a1efSThomas Keiser case SMB_SVCENUM_TYPE_TREE:
9273b13a1efSThomas Keiser case SMB_SVCENUM_TYPE_FILE:
9288d94f651SGordon Ross smb_server_enum_trees(sv, svcenum);
9293b13a1efSThomas Keiser break;
9303b13a1efSThomas Keiser default:
9313b13a1efSThomas Keiser rc = EINVAL;
9323b13a1efSThomas Keiser }
93329bd2886SAlan Wright
9343b13a1efSThomas Keiser return (rc);
93529bd2886SAlan Wright }
93629bd2886SAlan Wright
937faa1795aSjb /*
9381fcced4cSJordan Brown * Look for sessions to disconnect by client and user name.
939faa1795aSjb */
9401fcced4cSJordan Brown int
smb_server_session_close(smb_server_t * sv,smb_ioc_session_t * ioc)941*34bbc83aSGordon Ross smb_server_session_close(smb_server_t *sv, smb_ioc_session_t *ioc)
9421fcced4cSJordan Brown {
943811599a4SMatt Barden int cnt;
9441fcced4cSJordan Brown
9458d94f651SGordon Ross cnt = smb_server_session_disconnect(sv, ioc->client, ioc->username);
9461fcced4cSJordan Brown
947811599a4SMatt Barden if (cnt == 0)
9481fcced4cSJordan Brown return (ENOENT);
9491fcced4cSJordan Brown return (0);
9501fcced4cSJordan Brown }
9511fcced4cSJordan Brown
9521fcced4cSJordan Brown /*
9531fcced4cSJordan Brown * Close a file by uniqid.
9541fcced4cSJordan Brown */
9551fcced4cSJordan Brown int
smb_server_file_close(smb_server_t * sv,smb_ioc_fileid_t * ioc)956*34bbc83aSGordon Ross smb_server_file_close(smb_server_t *sv, smb_ioc_fileid_t *ioc)
957faa1795aSjb {
9584163af6aSjose borrego uint32_t uniqid = ioc->uniqid;
9594163af6aSjose borrego int rc;
960faa1795aSjb
9618d94f651SGordon Ross rc = smb_server_fclose(sv, uniqid);
9621fcced4cSJordan Brown return (rc);
963faa1795aSjb }
964faa1795aSjb
9651fcced4cSJordan Brown /*
9661fcced4cSJordan Brown * These functions determine the relevant smb server to which the call apply.
9671fcced4cSJordan Brown */
9681fcced4cSJordan Brown
969faa1795aSjb uint32_t
smb_server_get_session_count(smb_server_t * sv)9708622ec45SGordon Ross smb_server_get_session_count(smb_server_t *sv)
971faa1795aSjb {
972faa1795aSjb uint32_t counter = 0;
973faa1795aSjb
974811599a4SMatt Barden counter = smb_llist_get_count(&sv->sv_session_list);
975faa1795aSjb
976faa1795aSjb return (counter);
977faa1795aSjb }
978faa1795aSjb
979faa1795aSjb /*
9808d94f651SGordon Ross * Gets the smb_node of the specified share path.
9818d94f651SGordon Ross * Node is returned held (caller must rele.)
982faa1795aSjb */
983faa1795aSjb int
smb_server_share_lookup(smb_server_t * sv,const char * shr_path,smb_node_t ** nodepp)9848d94f651SGordon Ross smb_server_share_lookup(smb_server_t *sv, const char *shr_path,
9858d94f651SGordon Ross smb_node_t **nodepp)
986faa1795aSjb {
987148c5f43SAlan Wright smb_request_t *sr;
988faa1795aSjb smb_node_t *fnode = NULL;
9898d94f651SGordon Ross smb_node_t *dnode = NULL;
990faa1795aSjb char last_comp[MAXNAMELEN];
991148c5f43SAlan Wright int rc = 0;
992faa1795aSjb
993148c5f43SAlan Wright ASSERT(shr_path);
994148c5f43SAlan Wright
99529bd2886SAlan Wright mutex_enter(&sv->sv_mutex);
99629bd2886SAlan Wright switch (sv->sv_state) {
99729bd2886SAlan Wright case SMB_SERVER_STATE_RUNNING:
99829bd2886SAlan Wright break;
99929bd2886SAlan Wright default:
100029bd2886SAlan Wright mutex_exit(&sv->sv_mutex);
100129bd2886SAlan Wright return (ENOTACTIVE);
100229bd2886SAlan Wright }
100329bd2886SAlan Wright mutex_exit(&sv->sv_mutex);
100429bd2886SAlan Wright
1005148c5f43SAlan Wright if ((sr = smb_request_alloc(sv->sv_session, 0)) == NULL) {
1006811599a4SMatt Barden return (ENOTCONN);
1007faa1795aSjb }
10088622ec45SGordon Ross sr->user_cr = zone_kcred();
1009faa1795aSjb
1010148c5f43SAlan Wright rc = smb_pathname_reduce(sr, sr->user_cr, shr_path,
101129bd2886SAlan Wright NULL, NULL, &dnode, last_comp);
1012faa1795aSjb
1013148c5f43SAlan Wright if (rc == 0) {
1014148c5f43SAlan Wright rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
1015148c5f43SAlan Wright sv->si_root_smb_node, dnode, last_comp, &fnode);
1016148c5f43SAlan Wright smb_node_release(dnode);
1017faa1795aSjb }
1018faa1795aSjb
1019148c5f43SAlan Wright smb_request_free(sr);
1020faa1795aSjb
1021148c5f43SAlan Wright if (rc != 0)
1022148c5f43SAlan Wright return (rc);
1023faa1795aSjb
1024faa1795aSjb ASSERT(fnode->vp && fnode->vp->v_vfsp);
1025faa1795aSjb
10268d94f651SGordon Ross *nodepp = fnode;
1027148c5f43SAlan Wright
1028148c5f43SAlan Wright return (0);
1029faa1795aSjb }
1030faa1795aSjb
1031b819cea2SGordon Ross #ifdef _KERNEL
1032faa1795aSjb /*
1033148c5f43SAlan Wright * This is a special interface that will be utilized by ZFS to cause a share to
1034148c5f43SAlan Wright * be added/removed.
1035faa1795aSjb *
1036148c5f43SAlan Wright * arg is either a lmshare_info_t or share_name from userspace.
1037148c5f43SAlan Wright * It will need to be copied into the kernel. It is lmshare_info_t
1038148c5f43SAlan Wright * for add operations and share_name for delete operations.
1039faa1795aSjb */
1040faa1795aSjb int
smb_server_share(void * arg,boolean_t add_share)1041148c5f43SAlan Wright smb_server_share(void *arg, boolean_t add_share)
1042faa1795aSjb {
1043faa1795aSjb smb_server_t *sv;
10442c1b14e5Sjose borrego int rc;
1045faa1795aSjb
1046148c5f43SAlan Wright if ((rc = smb_server_lookup(&sv)) == 0) {
1047148c5f43SAlan Wright mutex_enter(&sv->sv_mutex);
1048148c5f43SAlan Wright switch (sv->sv_state) {
1049148c5f43SAlan Wright case SMB_SERVER_STATE_RUNNING:
1050148c5f43SAlan Wright mutex_exit(&sv->sv_mutex);
1051148c5f43SAlan Wright (void) smb_kshare_upcall(sv->sv_lmshrd, arg, add_share);
1052148c5f43SAlan Wright break;
1053148c5f43SAlan Wright default:
1054148c5f43SAlan Wright mutex_exit(&sv->sv_mutex);
1055148c5f43SAlan Wright break;
1056148c5f43SAlan Wright }
1057148c5f43SAlan Wright smb_server_release(sv);
1058148c5f43SAlan Wright }
1059148c5f43SAlan Wright
1060148c5f43SAlan Wright return (rc);
1061148c5f43SAlan Wright }
1062b819cea2SGordon Ross #endif /* _KERNEL */
1063148c5f43SAlan Wright
1064148c5f43SAlan Wright int
smb_server_unshare(const char * sharename)1065148c5f43SAlan Wright smb_server_unshare(const char *sharename)
1066148c5f43SAlan Wright {
10674163af6aSjose borrego smb_server_t *sv;
10684163af6aSjose borrego int rc;
1069148c5f43SAlan Wright
10702c1b14e5Sjose borrego if ((rc = smb_server_lookup(&sv)))
10712c1b14e5Sjose borrego return (rc);
1072faa1795aSjb
107329bd2886SAlan Wright mutex_enter(&sv->sv_mutex);
107429bd2886SAlan Wright switch (sv->sv_state) {
107529bd2886SAlan Wright case SMB_SERVER_STATE_RUNNING:
10769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SERVER_STATE_STOPPING:
107729bd2886SAlan Wright break;
107829bd2886SAlan Wright default:
107929bd2886SAlan Wright mutex_exit(&sv->sv_mutex);
1080148c5f43SAlan Wright smb_server_release(sv);
108129bd2886SAlan Wright return (ENOTACTIVE);
108229bd2886SAlan Wright }
108329bd2886SAlan Wright mutex_exit(&sv->sv_mutex);
108429bd2886SAlan Wright
10858d94f651SGordon Ross smb_server_disconnect_share(sv, sharename);
10862c1b14e5Sjose borrego
1087faa1795aSjb smb_server_release(sv);
1088faa1795aSjb return (0);
1089faa1795aSjb }
1090faa1795aSjb
10912c1b14e5Sjose borrego /*
1092148c5f43SAlan Wright * Disconnect the specified share.
1093148c5f43SAlan Wright * Typically called when a share has been removed.
10942c1b14e5Sjose borrego */
10952c1b14e5Sjose borrego static void
smb_server_disconnect_share(smb_server_t * sv,const char * sharename)10968d94f651SGordon Ross smb_server_disconnect_share(smb_server_t *sv, const char *sharename)
10972c1b14e5Sjose borrego {
10988d94f651SGordon Ross smb_llist_t *ll;
10994163af6aSjose borrego smb_session_t *session;
11002c1b14e5Sjose borrego
11018d94f651SGordon Ross ll = &sv->sv_session_list;
11024163af6aSjose borrego smb_llist_enter(ll, RW_READER);
1103faa1795aSjb
11044163af6aSjose borrego session = smb_llist_head(ll);
1105148c5f43SAlan Wright while (session) {
11064163af6aSjose borrego SMB_SESSION_VALID(session);
1107148c5f43SAlan Wright smb_rwx_rwenter(&session->s_lock, RW_READER);
1108148c5f43SAlan Wright switch (session->s_state) {
1109148c5f43SAlan Wright case SMB_SESSION_STATE_NEGOTIATED:
1110811599a4SMatt Barden smb_rwx_rwexit(&session->s_lock);
1111148c5f43SAlan Wright smb_session_disconnect_share(session, sharename);
111229bd2886SAlan Wright break;
111329bd2886SAlan Wright default:
1114811599a4SMatt Barden smb_rwx_rwexit(&session->s_lock);
111529bd2886SAlan Wright break;
1116faa1795aSjb }
11174163af6aSjose borrego session = smb_llist_next(ll, session);
1118faa1795aSjb }
1119148c5f43SAlan Wright
11204163af6aSjose borrego smb_llist_exit(ll);
1121faa1795aSjb }
1122faa1795aSjb
11235d8538b6SGordon Ross #ifdef _KERNEL
11245d8538b6SGordon Ross
11255d8538b6SGordon Ross /*
11267957766eSGordon Ross * Create a process to own SMB server threads (like zfs spa.c)
11277957766eSGordon Ross * so we can see the CPU usage etc. with "prstat -L".
11287957766eSGordon Ross * The new process MUST be in the same zone as the caller.
11295d8538b6SGordon Ross */
11305d8538b6SGordon Ross static int
smb_server_newproc(smb_server_t * sv)11315d8538b6SGordon Ross smb_server_newproc(smb_server_t *sv)
11325d8538b6SGordon Ross {
11335d8538b6SGordon Ross int rc;
11345d8538b6SGordon Ross
11357957766eSGordon Ross /*
11367957766eSGordon Ross * Todo: Fix newproc() for zones.
11377957766eSGordon Ross * At present, it always creates in p0.
11387957766eSGordon Ross * For now, only do this for the global zone.
11397957766eSGordon Ross */
11407957766eSGordon Ross if (getzoneid() != GLOBAL_ZONEID)
11417957766eSGordon Ross return (0);
11427957766eSGordon Ross
11435d8538b6SGordon Ross mutex_enter(&sv->sv_proc_lock);
11445d8538b6SGordon Ross if (sv->sv_proc_p != NULL) {
11455d8538b6SGordon Ross /* restart? re-use proc */
11465d8538b6SGordon Ross rc = 0;
11475d8538b6SGordon Ross goto out;
11485d8538b6SGordon Ross }
11495d8538b6SGordon Ross
11505d8538b6SGordon Ross sv->sv_proc_state = SMB_THREAD_STATE_STARTING;
11515d8538b6SGordon Ross rc = newproc(smb_server_proc_main, (caddr_t)sv,
11525d8538b6SGordon Ross syscid, smbsrv_base_pri, NULL, 0);
11535d8538b6SGordon Ross if (rc != 0) {
11545d8538b6SGordon Ross cmn_err(CE_WARN, "newproc failed, rc=%d", rc);
11555d8538b6SGordon Ross goto out;
11565d8538b6SGordon Ross }
11575d8538b6SGordon Ross
11585d8538b6SGordon Ross /* Rendez-vous with new proc thread. */
11595d8538b6SGordon Ross while (sv->sv_proc_state == SMB_THREAD_STATE_STARTING) {
11605d8538b6SGordon Ross cv_wait(&sv->sv_proc_cv, &sv->sv_proc_lock);
11615d8538b6SGordon Ross
11625d8538b6SGordon Ross }
11635d8538b6SGordon Ross if (sv->sv_proc_state != SMB_THREAD_STATE_RUNNING) {
11645d8538b6SGordon Ross rc = ESRCH;
11655d8538b6SGordon Ross goto out;
11665d8538b6SGordon Ross }
11675d8538b6SGordon Ross ASSERT(sv->sv_proc_p != NULL);
11685d8538b6SGordon Ross
11695d8538b6SGordon Ross out:
11705d8538b6SGordon Ross mutex_exit(&sv->sv_proc_lock);
11715d8538b6SGordon Ross return (rc);
11725d8538b6SGordon Ross }
11735d8538b6SGordon Ross
11745d8538b6SGordon Ross /*
11755d8538b6SGordon Ross * Main thread for the process we create to own SMB server threads.
11765d8538b6SGordon Ross */
11775d8538b6SGordon Ross static void
smb_server_proc_main(void * arg)11785d8538b6SGordon Ross smb_server_proc_main(void *arg)
11795d8538b6SGordon Ross {
11805d8538b6SGordon Ross callb_cpr_t cprinfo;
11815d8538b6SGordon Ross smb_server_t *sv = arg;
11825d8538b6SGordon Ross user_t *pu = PTOU(curproc);
11835d8538b6SGordon Ross zoneid_t zid = getzoneid();
11845d8538b6SGordon Ross
11855d8538b6SGordon Ross ASSERT(curproc != &p0);
11865d8538b6SGordon Ross ASSERT(zid == sv->sv_zid);
11875d8538b6SGordon Ross
11885d8538b6SGordon Ross (void) strlcpy(pu->u_comm, "smbsrv", sizeof (pu->u_comm));
11895d8538b6SGordon Ross (void) snprintf(pu->u_psargs, sizeof (pu->u_psargs),
11905d8538b6SGordon Ross "smbsrv %d", (int)zid);
11915d8538b6SGordon Ross
11925d8538b6SGordon Ross CALLB_CPR_INIT(&cprinfo, &sv->sv_proc_lock, callb_generic_cpr,
11935d8538b6SGordon Ross pu->u_psargs);
11945d8538b6SGordon Ross
11955d8538b6SGordon Ross mutex_enter(&sv->sv_proc_lock);
11965d8538b6SGordon Ross ASSERT(sv->sv_proc_state == SMB_THREAD_STATE_STARTING);
11975d8538b6SGordon Ross
11985d8538b6SGordon Ross sv->sv_proc_p = curproc;
11995d8538b6SGordon Ross sv->sv_proc_did = curthread->t_did;
12005d8538b6SGordon Ross
12015d8538b6SGordon Ross sv->sv_proc_state = SMB_THREAD_STATE_RUNNING;
12025d8538b6SGordon Ross cv_broadcast(&sv->sv_proc_cv);
12035d8538b6SGordon Ross
12045d8538b6SGordon Ross CALLB_CPR_SAFE_BEGIN(&cprinfo);
12055d8538b6SGordon Ross while (sv->sv_proc_state == SMB_THREAD_STATE_RUNNING)
12065d8538b6SGordon Ross cv_wait(&sv->sv_proc_cv, &sv->sv_proc_lock);
12075d8538b6SGordon Ross CALLB_CPR_SAFE_END(&cprinfo, &sv->sv_proc_lock);
12085d8538b6SGordon Ross
12095d8538b6SGordon Ross ASSERT(sv->sv_proc_state == SMB_THREAD_STATE_EXITING);
12105d8538b6SGordon Ross sv->sv_proc_state = SMB_THREAD_STATE_EXITED;
12115d8538b6SGordon Ross sv->sv_proc_p = NULL;
12125d8538b6SGordon Ross cv_broadcast(&sv->sv_proc_cv);
12135d8538b6SGordon Ross CALLB_CPR_EXIT(&cprinfo); /* mutex_exit sv_proc_lock */
12145d8538b6SGordon Ross
12155d8538b6SGordon Ross /* Note: lwp_exit() expects p_lock entered. */
12165d8538b6SGordon Ross mutex_enter(&curproc->p_lock);
12175d8538b6SGordon Ross lwp_exit();
12185d8538b6SGordon Ross }
12195d8538b6SGordon Ross
12205d8538b6SGordon Ross /*
12215d8538b6SGordon Ross * Delete the server proc (if any)
12225d8538b6SGordon Ross */
12235d8538b6SGordon Ross static void
smb_server_delproc(smb_server_t * sv)12245d8538b6SGordon Ross smb_server_delproc(smb_server_t *sv)
12255d8538b6SGordon Ross {
12265d8538b6SGordon Ross
12275d8538b6SGordon Ross mutex_enter(&sv->sv_proc_lock);
12285d8538b6SGordon Ross
12295d8538b6SGordon Ross if (sv->sv_proc_state != SMB_THREAD_STATE_RUNNING)
12305d8538b6SGordon Ross goto out;
12315d8538b6SGordon Ross ASSERT(sv->sv_proc_p != NULL);
12325d8538b6SGordon Ross
12335d8538b6SGordon Ross sv->sv_proc_state = SMB_THREAD_STATE_EXITING;
12345d8538b6SGordon Ross cv_broadcast(&sv->sv_proc_cv);
12355d8538b6SGordon Ross
12365d8538b6SGordon Ross /* Rendez-vous with proc thread. */
12375d8538b6SGordon Ross while (sv->sv_proc_state == SMB_THREAD_STATE_EXITING) {
12385d8538b6SGordon Ross cv_wait(&sv->sv_proc_cv, &sv->sv_proc_lock);
12395d8538b6SGordon Ross
12405d8538b6SGordon Ross }
12415d8538b6SGordon Ross if (sv->sv_proc_state != SMB_THREAD_STATE_EXITED) {
12425d8538b6SGordon Ross cmn_err(CE_WARN, "smb_server_delproc, state=%d",
12435d8538b6SGordon Ross sv->sv_proc_state);
12445d8538b6SGordon Ross goto out;
12455d8538b6SGordon Ross }
12465d8538b6SGordon Ross if (sv->sv_proc_did != 0) {
12475d8538b6SGordon Ross thread_join(sv->sv_proc_did);
12485d8538b6SGordon Ross sv->sv_proc_did = 0;
12495d8538b6SGordon Ross }
12505d8538b6SGordon Ross
12515d8538b6SGordon Ross out:
12525d8538b6SGordon Ross mutex_exit(&sv->sv_proc_lock);
12535d8538b6SGordon Ross }
12545d8538b6SGordon Ross
12555d8538b6SGordon Ross #endif /* _KERNEL */
12565d8538b6SGordon Ross
1257faa1795aSjb /*
1258faa1795aSjb * *****************************************************************************
1259faa1795aSjb * **************** Functions called from the internal layers ******************
1260faa1795aSjb * *****************************************************************************
1261faa1795aSjb *
1262faa1795aSjb * These functions are provided the relevant smb server by the caller.
1263faa1795aSjb */
1264faa1795aSjb
1265faa1795aSjb void
smb_server_get_cfg(smb_server_t * sv,smb_kmod_cfg_t * cfg)1266faa1795aSjb smb_server_get_cfg(smb_server_t *sv, smb_kmod_cfg_t *cfg)
1267faa1795aSjb {
1268faa1795aSjb rw_enter(&sv->sv_cfg_lock, RW_READER);
1269faa1795aSjb bcopy(&sv->sv_cfg, cfg, sizeof (*cfg));
1270faa1795aSjb rw_exit(&sv->sv_cfg_lock);
1271faa1795aSjb }
1272faa1795aSjb
1273148c5f43SAlan Wright /*
1274148c5f43SAlan Wright *
1275148c5f43SAlan Wright */
1276148c5f43SAlan Wright void
smb_server_inc_nbt_sess(smb_server_t * sv)1277148c5f43SAlan Wright smb_server_inc_nbt_sess(smb_server_t *sv)
1278148c5f43SAlan Wright {
1279148c5f43SAlan Wright SMB_SERVER_VALID(sv);
1280148c5f43SAlan Wright atomic_inc_32(&sv->sv_nbt_sess);
1281148c5f43SAlan Wright }
1282148c5f43SAlan Wright
1283148c5f43SAlan Wright void
smb_server_dec_nbt_sess(smb_server_t * sv)1284148c5f43SAlan Wright smb_server_dec_nbt_sess(smb_server_t *sv)
1285148c5f43SAlan Wright {
1286148c5f43SAlan Wright SMB_SERVER_VALID(sv);
1287148c5f43SAlan Wright atomic_dec_32(&sv->sv_nbt_sess);
1288148c5f43SAlan Wright }
1289148c5f43SAlan Wright
1290148c5f43SAlan Wright void
smb_server_inc_tcp_sess(smb_server_t * sv)1291148c5f43SAlan Wright smb_server_inc_tcp_sess(smb_server_t *sv)
1292148c5f43SAlan Wright {
1293148c5f43SAlan Wright SMB_SERVER_VALID(sv);
1294148c5f43SAlan Wright atomic_inc_32(&sv->sv_tcp_sess);
1295148c5f43SAlan Wright }
1296148c5f43SAlan Wright
1297148c5f43SAlan Wright void
smb_server_dec_tcp_sess(smb_server_t * sv)1298148c5f43SAlan Wright smb_server_dec_tcp_sess(smb_server_t *sv)
1299148c5f43SAlan Wright {
1300148c5f43SAlan Wright SMB_SERVER_VALID(sv);
1301148c5f43SAlan Wright atomic_dec_32(&sv->sv_tcp_sess);
1302148c5f43SAlan Wright }
1303148c5f43SAlan Wright
1304148c5f43SAlan Wright void
smb_server_inc_users(smb_server_t * sv)1305148c5f43SAlan Wright smb_server_inc_users(smb_server_t *sv)
1306148c5f43SAlan Wright {
1307148c5f43SAlan Wright SMB_SERVER_VALID(sv);
1308148c5f43SAlan Wright atomic_inc_32(&sv->sv_users);
1309148c5f43SAlan Wright }
1310148c5f43SAlan Wright
1311148c5f43SAlan Wright void
smb_server_dec_users(smb_server_t * sv)1312148c5f43SAlan Wright smb_server_dec_users(smb_server_t *sv)
1313148c5f43SAlan Wright {
1314148c5f43SAlan Wright SMB_SERVER_VALID(sv);
1315148c5f43SAlan Wright atomic_dec_32(&sv->sv_users);
1316148c5f43SAlan Wright }
1317148c5f43SAlan Wright
1318148c5f43SAlan Wright void
smb_server_inc_trees(smb_server_t * sv)1319148c5f43SAlan Wright smb_server_inc_trees(smb_server_t *sv)
1320148c5f43SAlan Wright {
1321148c5f43SAlan Wright SMB_SERVER_VALID(sv);
1322148c5f43SAlan Wright atomic_inc_32(&sv->sv_trees);
1323148c5f43SAlan Wright }
1324148c5f43SAlan Wright
1325148c5f43SAlan Wright void
smb_server_dec_trees(smb_server_t * sv)1326148c5f43SAlan Wright smb_server_dec_trees(smb_server_t *sv)
1327148c5f43SAlan Wright {
1328148c5f43SAlan Wright SMB_SERVER_VALID(sv);
1329148c5f43SAlan Wright atomic_dec_32(&sv->sv_trees);
1330148c5f43SAlan Wright }
1331148c5f43SAlan Wright
1332148c5f43SAlan Wright void
smb_server_inc_files(smb_server_t * sv)1333148c5f43SAlan Wright smb_server_inc_files(smb_server_t *sv)
1334148c5f43SAlan Wright {
1335148c5f43SAlan Wright SMB_SERVER_VALID(sv);
1336148c5f43SAlan Wright atomic_inc_32(&sv->sv_files);
1337148c5f43SAlan Wright }
1338148c5f43SAlan Wright
1339148c5f43SAlan Wright void
smb_server_dec_files(smb_server_t * sv)1340148c5f43SAlan Wright smb_server_dec_files(smb_server_t *sv)
1341148c5f43SAlan Wright {
1342148c5f43SAlan Wright SMB_SERVER_VALID(sv);
1343148c5f43SAlan Wright atomic_dec_32(&sv->sv_files);
1344148c5f43SAlan Wright }
1345148c5f43SAlan Wright
1346148c5f43SAlan Wright void
smb_server_inc_pipes(smb_server_t * sv)1347148c5f43SAlan Wright smb_server_inc_pipes(smb_server_t *sv)
1348148c5f43SAlan Wright {
1349148c5f43SAlan Wright SMB_SERVER_VALID(sv);
1350148c5f43SAlan Wright atomic_inc_32(&sv->sv_pipes);
1351148c5f43SAlan Wright }
1352148c5f43SAlan Wright
1353148c5f43SAlan Wright void
smb_server_dec_pipes(smb_server_t * sv)1354148c5f43SAlan Wright smb_server_dec_pipes(smb_server_t *sv)
1355148c5f43SAlan Wright {
1356148c5f43SAlan Wright SMB_SERVER_VALID(sv);
1357148c5f43SAlan Wright atomic_dec_32(&sv->sv_pipes);
1358148c5f43SAlan Wright }
1359148c5f43SAlan Wright
1360148c5f43SAlan Wright void
smb_server_add_rxb(smb_server_t * sv,int64_t value)1361148c5f43SAlan Wright smb_server_add_rxb(smb_server_t *sv, int64_t value)
1362148c5f43SAlan Wright {
1363148c5f43SAlan Wright SMB_SERVER_VALID(sv);
1364148c5f43SAlan Wright atomic_add_64(&sv->sv_rxb, value);
1365148c5f43SAlan Wright }
1366148c5f43SAlan Wright
1367148c5f43SAlan Wright void
smb_server_add_txb(smb_server_t * sv,int64_t value)1368148c5f43SAlan Wright smb_server_add_txb(smb_server_t *sv, int64_t value)
1369148c5f43SAlan Wright {
1370148c5f43SAlan Wright SMB_SERVER_VALID(sv);
1371148c5f43SAlan Wright atomic_add_64(&sv->sv_txb, value);
1372148c5f43SAlan Wright }
1373148c5f43SAlan Wright
1374148c5f43SAlan Wright void
smb_server_inc_req(smb_server_t * sv)1375148c5f43SAlan Wright smb_server_inc_req(smb_server_t *sv)
1376148c5f43SAlan Wright {
1377148c5f43SAlan Wright SMB_SERVER_VALID(sv);
1378148c5f43SAlan Wright atomic_inc_64(&sv->sv_nreq);
1379148c5f43SAlan Wright }
1380148c5f43SAlan Wright
1381faa1795aSjb /*
1382faa1795aSjb * *****************************************************************************
1383faa1795aSjb * *************************** Static Functions ********************************
1384faa1795aSjb * *****************************************************************************
1385faa1795aSjb */
1386faa1795aSjb
1387faa1795aSjb static void
smb_server_timers(smb_thread_t * thread,void * arg)1388faa1795aSjb smb_server_timers(smb_thread_t *thread, void *arg)
1389faa1795aSjb {
1390faa1795aSjb smb_server_t *sv = (smb_server_t *)arg;
1391faa1795aSjb
1392faa1795aSjb ASSERT(sv != NULL);
1393faa1795aSjb
1394b819cea2SGordon Ross /*
1395811599a4SMatt Barden * This kills old inactive sessions and expired durable
1396811599a4SMatt Barden * handles. The session code expects one call per minute.
1397b819cea2SGordon Ross */
1398b819cea2SGordon Ross while (smb_thread_continue_timedwait(thread, 60 /* Seconds */)) {
1399811599a4SMatt Barden if (sv->sv_cfg.skc_keepalive != 0)
1400811599a4SMatt Barden smb_session_timers(sv);
1401811599a4SMatt Barden smb2_durable_timers(sv);
1402faa1795aSjb }
1403faa1795aSjb }
1404faa1795aSjb
1405faa1795aSjb /*
1406faa1795aSjb * smb_server_kstat_init
1407faa1795aSjb */
1408148c5f43SAlan Wright static void
smb_server_kstat_init(smb_server_t * sv)1409faa1795aSjb smb_server_kstat_init(smb_server_t *sv)
1410faa1795aSjb {
1411cb174861Sjoyce mcintosh
14128622ec45SGordon Ross sv->sv_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, 0,
1413148c5f43SAlan Wright SMBSRV_KSTAT_STATISTICS, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_RAW,
1414148c5f43SAlan Wright sizeof (smbsrv_kstats_t), 0, sv->sv_zid);
1415148c5f43SAlan Wright
1416148c5f43SAlan Wright if (sv->sv_ksp != NULL) {
1417148c5f43SAlan Wright sv->sv_ksp->ks_update = smb_server_kstat_update;
1418148c5f43SAlan Wright sv->sv_ksp->ks_private = sv;
1419148c5f43SAlan Wright ((smbsrv_kstats_t *)sv->sv_ksp->ks_data)->ks_start_time =
1420148c5f43SAlan Wright sv->sv_start_time;
14218622ec45SGordon Ross smb_dispatch_stats_init(sv);
1422a90cf9f2SGordon Ross smb2_dispatch_stats_init(sv);
1423faa1795aSjb kstat_install(sv->sv_ksp);
1424148c5f43SAlan Wright } else {
1425148c5f43SAlan Wright cmn_err(CE_WARN, "SMB Server: Statistics unavailable");
1426faa1795aSjb }
1427cb174861Sjoyce mcintosh
14288622ec45SGordon Ross sv->sv_legacy_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, 0,
14298622ec45SGordon Ross SMBSRV_KSTAT_NAME, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_NAMED,
14308622ec45SGordon Ross sizeof (smb_server_legacy_kstat_t) / sizeof (kstat_named_t),
14318622ec45SGordon Ross 0, sv->sv_zid);
1432cb174861Sjoyce mcintosh
1433cb174861Sjoyce mcintosh if (sv->sv_legacy_ksp != NULL) {
1434cb174861Sjoyce mcintosh smb_server_legacy_kstat_t *ksd;
1435cb174861Sjoyce mcintosh
1436cb174861Sjoyce mcintosh ksd = sv->sv_legacy_ksp->ks_data;
1437cb174861Sjoyce mcintosh
1438cb174861Sjoyce mcintosh (void) strlcpy(ksd->ls_files.name, "open_files",
1439cb174861Sjoyce mcintosh sizeof (ksd->ls_files.name));
1440cb174861Sjoyce mcintosh ksd->ls_files.data_type = KSTAT_DATA_UINT32;
1441cb174861Sjoyce mcintosh
1442cb174861Sjoyce mcintosh (void) strlcpy(ksd->ls_trees.name, "connections",
1443cb174861Sjoyce mcintosh sizeof (ksd->ls_trees.name));
1444cb174861Sjoyce mcintosh ksd->ls_trees.data_type = KSTAT_DATA_UINT32;
1445cb174861Sjoyce mcintosh
1446cb174861Sjoyce mcintosh (void) strlcpy(ksd->ls_users.name, "connections",
1447cb174861Sjoyce mcintosh sizeof (ksd->ls_users.name));
1448cb174861Sjoyce mcintosh ksd->ls_users.data_type = KSTAT_DATA_UINT32;
1449cb174861Sjoyce mcintosh
1450cb174861Sjoyce mcintosh mutex_init(&sv->sv_legacy_ksmtx, NULL, MUTEX_DEFAULT, NULL);
1451cb174861Sjoyce mcintosh sv->sv_legacy_ksp->ks_lock = &sv->sv_legacy_ksmtx;
1452cb174861Sjoyce mcintosh sv->sv_legacy_ksp->ks_update = smb_server_legacy_kstat_update;
1453cb174861Sjoyce mcintosh kstat_install(sv->sv_legacy_ksp);
1454cb174861Sjoyce mcintosh }
1455faa1795aSjb }
1456faa1795aSjb
1457faa1795aSjb /*
1458faa1795aSjb * smb_server_kstat_fini
1459faa1795aSjb */
1460faa1795aSjb static void
smb_server_kstat_fini(smb_server_t * sv)1461faa1795aSjb smb_server_kstat_fini(smb_server_t *sv)
1462faa1795aSjb {
1463cb174861Sjoyce mcintosh if (sv->sv_legacy_ksp != NULL) {
1464cb174861Sjoyce mcintosh kstat_delete(sv->sv_legacy_ksp);
1465cb174861Sjoyce mcintosh mutex_destroy(&sv->sv_legacy_ksmtx);
1466cb174861Sjoyce mcintosh sv->sv_legacy_ksp = NULL;
1467cb174861Sjoyce mcintosh }
1468cb174861Sjoyce mcintosh
1469148c5f43SAlan Wright if (sv->sv_ksp != NULL) {
1470faa1795aSjb kstat_delete(sv->sv_ksp);
1471faa1795aSjb sv->sv_ksp = NULL;
14728622ec45SGordon Ross smb_dispatch_stats_fini(sv);
1473a90cf9f2SGordon Ross smb2_dispatch_stats_fini(sv);
1474faa1795aSjb }
1475faa1795aSjb }
1476faa1795aSjb
14778365a6eaSGordon Ross /*
14788365a6eaSGordon Ross * Verify the defines in smb_kstat.h used by ks_reqs1 ks_reqs2
14798365a6eaSGordon Ross */
14808365a6eaSGordon Ross CTASSERT(SMBSRV_KS_NREQS1 == SMB_COM_NUM);
14818365a6eaSGordon Ross CTASSERT(SMBSRV_KS_NREQS2 == SMB2__NCMDS);
14828365a6eaSGordon Ross
1483148c5f43SAlan Wright /*
1484148c5f43SAlan Wright * smb_server_kstat_update
1485148c5f43SAlan Wright */
1486faa1795aSjb static int
smb_server_kstat_update(kstat_t * ksp,int rw)1487148c5f43SAlan Wright smb_server_kstat_update(kstat_t *ksp, int rw)
1488faa1795aSjb {
1489faa1795aSjb smb_server_t *sv;
1490148c5f43SAlan Wright smbsrv_kstats_t *ksd;
1491faa1795aSjb
1492148c5f43SAlan Wright if (rw == KSTAT_READ) {
1493148c5f43SAlan Wright sv = ksp->ks_private;
14949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv);
1495148c5f43SAlan Wright ksd = (smbsrv_kstats_t *)ksp->ks_data;
1496148c5f43SAlan Wright /*
1497148c5f43SAlan Wright * Counters
1498148c5f43SAlan Wright */
1499148c5f43SAlan Wright ksd->ks_nbt_sess = sv->sv_nbt_sess;
1500148c5f43SAlan Wright ksd->ks_tcp_sess = sv->sv_tcp_sess;
1501148c5f43SAlan Wright ksd->ks_users = sv->sv_users;
1502148c5f43SAlan Wright ksd->ks_trees = sv->sv_trees;
1503148c5f43SAlan Wright ksd->ks_files = sv->sv_files;
1504148c5f43SAlan Wright ksd->ks_pipes = sv->sv_pipes;
1505148c5f43SAlan Wright /*
1506148c5f43SAlan Wright * Throughput
1507148c5f43SAlan Wright */
1508148c5f43SAlan Wright ksd->ks_txb = sv->sv_txb;
1509148c5f43SAlan Wright ksd->ks_rxb = sv->sv_rxb;
1510148c5f43SAlan Wright ksd->ks_nreq = sv->sv_nreq;
1511148c5f43SAlan Wright /*
1512148c5f43SAlan Wright * Busyness
1513148c5f43SAlan Wright */
1514148c5f43SAlan Wright ksd->ks_maxreqs = sv->sv_cfg.skc_maxworkers;
1515148c5f43SAlan Wright smb_srqueue_update(&sv->sv_srqueue,
1516148c5f43SAlan Wright &ksd->ks_utilization);
1517148c5f43SAlan Wright /*
1518148c5f43SAlan Wright * Latency & Throughput of the requests
1519148c5f43SAlan Wright */
1520a90cf9f2SGordon Ross smb_dispatch_stats_update(sv, ksd->ks_reqs1, 0, SMB_COM_NUM);
1521a90cf9f2SGordon Ross smb2_dispatch_stats_update(sv, ksd->ks_reqs2, 0, SMB2__NCMDS);
1522148c5f43SAlan Wright return (0);
1523faa1795aSjb }
1524148c5f43SAlan Wright if (rw == KSTAT_WRITE)
1525148c5f43SAlan Wright return (EACCES);
1526148c5f43SAlan Wright
1527148c5f43SAlan Wright return (EIO);
1528faa1795aSjb }
1529faa1795aSjb
1530cb174861Sjoyce mcintosh static int
smb_server_legacy_kstat_update(kstat_t * ksp,int rw)1531cb174861Sjoyce mcintosh smb_server_legacy_kstat_update(kstat_t *ksp, int rw)
1532cb174861Sjoyce mcintosh {
1533cb174861Sjoyce mcintosh smb_server_t *sv;
1534cb174861Sjoyce mcintosh smb_server_legacy_kstat_t *ksd;
1535cb174861Sjoyce mcintosh int rc;
1536cb174861Sjoyce mcintosh
1537cb174861Sjoyce mcintosh switch (rw) {
1538cb174861Sjoyce mcintosh case KSTAT_WRITE:
1539cb174861Sjoyce mcintosh rc = EACCES;
1540cb174861Sjoyce mcintosh break;
1541cb174861Sjoyce mcintosh case KSTAT_READ:
1542cb174861Sjoyce mcintosh if (!smb_server_lookup(&sv)) {
1543cb174861Sjoyce mcintosh ASSERT(MUTEX_HELD(ksp->ks_lock));
1544cb174861Sjoyce mcintosh ASSERT(sv->sv_legacy_ksp == ksp);
1545cb174861Sjoyce mcintosh ksd = (smb_server_legacy_kstat_t *)ksp->ks_data;
1546cb174861Sjoyce mcintosh ksd->ls_files.value.ui32 = sv->sv_files + sv->sv_pipes;
1547cb174861Sjoyce mcintosh ksd->ls_trees.value.ui32 = sv->sv_trees;
1548cb174861Sjoyce mcintosh ksd->ls_users.value.ui32 = sv->sv_users;
1549cb174861Sjoyce mcintosh smb_server_release(sv);
1550cb174861Sjoyce mcintosh rc = 0;
1551cb174861Sjoyce mcintosh break;
1552cb174861Sjoyce mcintosh }
15532d63d7e2SToomas Soome /* FALLTHROUGH */
1554cb174861Sjoyce mcintosh default:
1555cb174861Sjoyce mcintosh rc = EIO;
1556cb174861Sjoyce mcintosh break;
1557cb174861Sjoyce mcintosh }
1558cb174861Sjoyce mcintosh return (rc);
1559cb174861Sjoyce mcintosh
1560cb174861Sjoyce mcintosh }
1561cb174861Sjoyce mcintosh
156286184067SGordon Ross int smb_server_shutdown_wait1 = 15; /* seconds */
156386184067SGordon Ross
1564faa1795aSjb /*
15654163af6aSjose borrego * smb_server_shutdown
1566faa1795aSjb */
1567faa1795aSjb static void
smb_server_shutdown(smb_server_t * sv)15689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_shutdown(smb_server_t *sv)
1569faa1795aSjb {
1570811599a4SMatt Barden smb_llist_t *sl = &sv->sv_session_list;
1571811599a4SMatt Barden smb_session_t *session;
157286184067SGordon Ross clock_t time0, time1, time2;
1573811599a4SMatt Barden
15749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv);
1575faa1795aSjb
1576856399cfSGordon Ross /*
157786184067SGordon Ross * Stop the listeners first, so we can't get any more
157886184067SGordon Ross * new sessions while we're trying to shut down.
1579856399cfSGordon Ross */
1580856399cfSGordon Ross smb_server_listener_stop(&sv->sv_nbt_daemon);
1581856399cfSGordon Ross smb_server_listener_stop(&sv->sv_tcp_daemon);
1582856399cfSGordon Ross
158386184067SGordon Ross /*
158486184067SGordon Ross * Disconnect all of the sessions. This causes all the
158586184067SGordon Ross * smb_server_receiver threads to see a disconnect and
158686184067SGordon Ross * begin tear-down (in parallel) in smb_session_cancel.
158786184067SGordon Ross */
1588811599a4SMatt Barden smb_llist_enter(sl, RW_READER);
1589811599a4SMatt Barden session = smb_llist_head(sl);
1590811599a4SMatt Barden while (session != NULL) {
1591811599a4SMatt Barden smb_session_disconnect(session);
1592811599a4SMatt Barden session = smb_llist_next(sl, session);
1593811599a4SMatt Barden }
1594811599a4SMatt Barden smb_llist_exit(sl);
1595811599a4SMatt Barden
1596856399cfSGordon Ross /*
1597856399cfSGordon Ross * Wake up any threads we might have blocked.
1598856399cfSGordon Ross * Must precede kdoor_close etc. because those will
1599856399cfSGordon Ross * wait for such threads to get out.
1600856399cfSGordon Ross */
1601856399cfSGordon Ross smb_event_cancel(sv, 0);
1602856399cfSGordon Ross smb_threshold_wake_all(&sv->sv_ssetup_ct);
1603856399cfSGordon Ross smb_threshold_wake_all(&sv->sv_tcon_ct);
1604856399cfSGordon Ross smb_threshold_wake_all(&sv->sv_opipe_ct);
1605a9609934SGordon Ross smb_threshold_wake_all(&sv->sv_logoff_ct);
1606856399cfSGordon Ross
1607811599a4SMatt Barden /*
1608811599a4SMatt Barden * Wait for the session list to empty.
1609811599a4SMatt Barden * (cv_signal in smb_server_destroy_session)
1610811599a4SMatt Barden *
161186184067SGordon Ross * We must wait for all the SMB session readers to finish, or
161286184067SGordon Ross * we could proceed here while there might be worker threads
161386184067SGordon Ross * running in any of those sessions. See smb_session_logoff
161486184067SGordon Ross * for timeouts applied to session tear-down. If this takes
161586184067SGordon Ross * longer than expected, make some noise, and fire a dtrace
161686184067SGordon Ross * probe one might use to investigate.
1617811599a4SMatt Barden */
161886184067SGordon Ross time0 = ddi_get_lbolt();
161986184067SGordon Ross time1 = SEC_TO_TICK(smb_server_shutdown_wait1) + time0;
1620811599a4SMatt Barden mutex_enter(&sv->sv_mutex);
1621811599a4SMatt Barden while (sv->sv_session_list.ll_count != 0) {
162286184067SGordon Ross if (cv_timedwait(&sv->sv_cv, &sv->sv_mutex, time1) < 0) {
162386184067SGordon Ross cmn_err(CE_NOTE, "!shutdown waited %d seconds"
162486184067SGordon Ross " with %d sessions still remaining",
162586184067SGordon Ross smb_server_shutdown_wait1,
162686184067SGordon Ross sv->sv_session_list.ll_count);
162786184067SGordon Ross DTRACE_PROBE1(max__wait, smb_server_t *, sv);
1628811599a4SMatt Barden break;
162986184067SGordon Ross }
1630811599a4SMatt Barden }
163186184067SGordon Ross while (sv->sv_session_list.ll_count != 0) {
163286184067SGordon Ross cv_wait(&sv->sv_cv, &sv->sv_mutex);
1633811599a4SMatt Barden }
163486184067SGordon Ross mutex_exit(&sv->sv_mutex);
1635811599a4SMatt Barden
163686184067SGordon Ross time2 = ddi_get_lbolt();
163786184067SGordon Ross if (time2 > time1) {
163886184067SGordon Ross cmn_err(CE_NOTE, "!shutdown waited %d seconds"
163986184067SGordon Ross " for all sessions to finish",
164086184067SGordon Ross (int)TICK_TO_SEC(time2 - time0));
164186184067SGordon Ross }
1642811599a4SMatt Barden
16438622ec45SGordon Ross smb_kdoor_close(sv);
1644b819cea2SGordon Ross #ifdef _KERNEL
1645148c5f43SAlan Wright smb_kshare_door_fini(sv->sv_lmshrd);
1646b819cea2SGordon Ross #endif /* _KERNEL */
16470dcb3379Sjb sv->sv_lmshrd = NULL;
1648b819cea2SGordon Ross
16498622ec45SGordon Ross smb_export_stop(sv);
1650811599a4SMatt Barden smb_kshare_stop(sv);
165186184067SGordon Ross smb_thread_stop(&sv->si_thread_timers);
16528d96b23eSAlan Wright
1653811599a4SMatt Barden /*
1654811599a4SMatt Barden * Both kshare and the oplock break sub-systems may have
1655811599a4SMatt Barden * taskq jobs on the spcial "server" session, until we've
1656811599a4SMatt Barden * closed all ofiles and stopped the kshare exporter.
1657811599a4SMatt Barden * Now it's safe to destroy the server session, but first
1658811599a4SMatt Barden * wait for any requests on it to finish. Note that for
1659811599a4SMatt Barden * normal sessions, this happens in smb_session_cancel,
1660811599a4SMatt Barden * but that's not called for the server session.
1661811599a4SMatt Barden */
16628d94f651SGordon Ross if (sv->sv_rootuser != NULL) {
16638d94f651SGordon Ross smb_user_logoff(sv->sv_rootuser);
16648d94f651SGordon Ross smb_user_release(sv->sv_rootuser);
16658d94f651SGordon Ross sv->sv_rootuser = NULL;
16668d94f651SGordon Ross }
16674163af6aSjose borrego if (sv->sv_session != NULL) {
1668525641e8SGordon Ross smb_session_cancel_requests(sv->sv_session, NULL, NULL);
16694846df9bSKevin Crowe smb_slist_wait_for_empty(&sv->sv_session->s_req_list);
16704846df9bSKevin Crowe
16718d94f651SGordon Ross /* Just in case import left users and trees */
16728d94f651SGordon Ross smb_session_logoff(sv->sv_session);
16738d94f651SGordon Ross
1674faa1795aSjb smb_session_delete(sv->sv_session);
1675faa1795aSjb sv->sv_session = NULL;
1676faa1795aSjb }
16778d96b23eSAlan Wright
16784163af6aSjose borrego if (sv->sv_receiver_pool != NULL) {
16794163af6aSjose borrego taskq_destroy(sv->sv_receiver_pool);
16804163af6aSjose borrego sv->sv_receiver_pool = NULL;
16814163af6aSjose borrego }
16824163af6aSjose borrego
16834163af6aSjose borrego if (sv->sv_worker_pool != NULL) {
16844163af6aSjose borrego taskq_destroy(sv->sv_worker_pool);
16854163af6aSjose borrego sv->sv_worker_pool = NULL;
16868d96b23eSAlan Wright }
16878622ec45SGordon Ross
1688e515d096SGordon Ross if (sv->sv_notify_pool != NULL) {
1689e515d096SGordon Ross taskq_destroy(sv->sv_notify_pool);
1690e515d096SGordon Ross sv->sv_notify_pool = NULL;
1691e515d096SGordon Ross }
1692e515d096SGordon Ross
169386184067SGordon Ross /*
169486184067SGordon Ross * Clean out any durable handles. After this we should
169586184067SGordon Ross * have no ofiles remaining (and no more oplock breaks).
169686184067SGordon Ross */
169786184067SGordon Ross smb2_dh_shutdown(sv);
169886184067SGordon Ross
16998622ec45SGordon Ross smb_server_fsop_stop(sv);
17005d8538b6SGordon Ross
17015d8538b6SGordon Ross #ifdef _KERNEL
17025d8538b6SGordon Ross if (sv->sv_proc_p != NULL) {
17035d8538b6SGordon Ross smb_server_delproc(sv);
17045d8538b6SGordon Ross }
17055d8538b6SGordon Ross #endif
1706faa1795aSjb }
1707faa1795aSjb
17084163af6aSjose borrego /*
17094163af6aSjose borrego * smb_server_listener_init
17104163af6aSjose borrego *
17114163af6aSjose borrego * Initializes listener contexts.
17124163af6aSjose borrego */
17134163af6aSjose borrego static void
smb_server_listener_init(smb_server_t * sv,smb_listener_daemon_t * ld,char * name,in_port_t port,int family)17144163af6aSjose borrego smb_server_listener_init(
1715faa1795aSjb smb_server_t *sv,
1716faa1795aSjb smb_listener_daemon_t *ld,
17174163af6aSjose borrego char *name,
1718faa1795aSjb in_port_t port,
17194163af6aSjose borrego int family)
1720faa1795aSjb {
17214163af6aSjose borrego ASSERT(ld->ld_magic != SMB_LISTENER_MAGIC);
1722faa1795aSjb
17234163af6aSjose borrego bzero(ld, sizeof (*ld));
17244163af6aSjose borrego
17254163af6aSjose borrego ld->ld_sv = sv;
17264163af6aSjose borrego ld->ld_family = family;
17274163af6aSjose borrego ld->ld_port = port;
17284163af6aSjose borrego
17294163af6aSjose borrego if (family == AF_INET) {
17304163af6aSjose borrego ld->ld_sin.sin_family = (uint32_t)family;
17314163af6aSjose borrego ld->ld_sin.sin_port = htons(port);
17324163af6aSjose borrego ld->ld_sin.sin_addr.s_addr = htonl(INADDR_ANY);
17334163af6aSjose borrego } else {
17344163af6aSjose borrego ld->ld_sin6.sin6_family = (uint32_t)family;
17354163af6aSjose borrego ld->ld_sin6.sin6_port = htons(port);
17364163af6aSjose borrego (void) memset(&ld->ld_sin6.sin6_addr.s6_addr, 0,
17374163af6aSjose borrego sizeof (ld->ld_sin6.sin6_addr.s6_addr));
1738faa1795aSjb }
1739faa1795aSjb
174008344b29SGordon Ross smb_thread_init(&ld->ld_thread, name, smb_server_listener, ld,
17415d8538b6SGordon Ross smbsrv_listen_pri, sv);
17424163af6aSjose borrego ld->ld_magic = SMB_LISTENER_MAGIC;
17434163af6aSjose borrego }
17444163af6aSjose borrego
17454163af6aSjose borrego /*
17464163af6aSjose borrego * smb_server_listener_destroy
17474163af6aSjose borrego *
17484163af6aSjose borrego * Destroyes listener contexts.
17494163af6aSjose borrego */
17504163af6aSjose borrego static void
smb_server_listener_destroy(smb_listener_daemon_t * ld)17514163af6aSjose borrego smb_server_listener_destroy(smb_listener_daemon_t *ld)
17524163af6aSjose borrego {
175383d2dfe6SGordon Ross /*
175483d2dfe6SGordon Ross * Note that if startup fails early, we can legitimately
175583d2dfe6SGordon Ross * get here with an all-zeros object.
175683d2dfe6SGordon Ross */
175783d2dfe6SGordon Ross if (ld->ld_magic == 0)
175883d2dfe6SGordon Ross return;
175983d2dfe6SGordon Ross
17604163af6aSjose borrego SMB_LISTENER_VALID(ld);
17614163af6aSjose borrego ASSERT(ld->ld_so == NULL);
17624163af6aSjose borrego smb_thread_destroy(&ld->ld_thread);
17634163af6aSjose borrego ld->ld_magic = 0;
17644163af6aSjose borrego }
17654163af6aSjose borrego
17664163af6aSjose borrego /*
17674163af6aSjose borrego * smb_server_listener_start
17684163af6aSjose borrego *
17694163af6aSjose borrego * Starts the listener associated with the context passed in.
17704163af6aSjose borrego *
17714163af6aSjose borrego * Return: 0 Success
17724163af6aSjose borrego * not 0 Failure
17734163af6aSjose borrego */
17744163af6aSjose borrego static int
smb_server_listener_start(smb_listener_daemon_t * ld)17754163af6aSjose borrego smb_server_listener_start(smb_listener_daemon_t *ld)
17764163af6aSjose borrego {
17774163af6aSjose borrego int rc;
17784163af6aSjose borrego uint32_t on;
17794163af6aSjose borrego uint32_t off;
17804163af6aSjose borrego
17814163af6aSjose borrego SMB_LISTENER_VALID(ld);
17824163af6aSjose borrego
17834163af6aSjose borrego if (ld->ld_so != NULL)
17844163af6aSjose borrego return (EINVAL);
17854163af6aSjose borrego
17864163af6aSjose borrego ld->ld_so = smb_socreate(ld->ld_family, SOCK_STREAM, 0);
1787faa1795aSjb if (ld->ld_so == NULL) {
17884163af6aSjose borrego cmn_err(CE_WARN, "port %d: socket create failed", ld->ld_port);
17894163af6aSjose borrego return (ENOMEM);
17904163af6aSjose borrego }
17919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
17924163af6aSjose borrego off = 0;
17934163af6aSjose borrego (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET,
17944163af6aSjose borrego SO_MAC_EXEMPT, &off, sizeof (off), CRED());
17959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
17964163af6aSjose borrego on = 1;
17974163af6aSjose borrego (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET,
17984163af6aSjose borrego SO_REUSEADDR, &on, sizeof (on), CRED());
17999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
18004163af6aSjose borrego if (ld->ld_family == AF_INET) {
18014163af6aSjose borrego rc = ksocket_bind(ld->ld_so,
18024163af6aSjose borrego (struct sockaddr *)&ld->ld_sin,
18034163af6aSjose borrego sizeof (ld->ld_sin), CRED());
18044163af6aSjose borrego } else {
18054163af6aSjose borrego rc = ksocket_bind(ld->ld_so,
18064163af6aSjose borrego (struct sockaddr *)&ld->ld_sin6,
18074163af6aSjose borrego sizeof (ld->ld_sin6), CRED());
18084163af6aSjose borrego }
18099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
18104163af6aSjose borrego if (rc != 0) {
18114163af6aSjose borrego cmn_err(CE_WARN, "port %d: bind failed", ld->ld_port);
18124163af6aSjose borrego return (rc);
18134163af6aSjose borrego }
18149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
18154163af6aSjose borrego rc = ksocket_listen(ld->ld_so, 20, CRED());
18164163af6aSjose borrego if (rc < 0) {
18174163af6aSjose borrego cmn_err(CE_WARN, "port %d: listen failed", ld->ld_port);
18184163af6aSjose borrego return (rc);
1819faa1795aSjb }
1820faa1795aSjb
18214163af6aSjose borrego ksocket_hold(ld->ld_so);
18224163af6aSjose borrego rc = smb_thread_start(&ld->ld_thread);
18234163af6aSjose borrego if (rc != 0) {
18244163af6aSjose borrego ksocket_rele(ld->ld_so);
18254163af6aSjose borrego cmn_err(CE_WARN, "port %d: listener failed to start",
18264163af6aSjose borrego ld->ld_port);
18274163af6aSjose borrego return (rc);
18284163af6aSjose borrego }
18294163af6aSjose borrego return (0);
18304163af6aSjose borrego }
1831faa1795aSjb
18324163af6aSjose borrego /*
18334163af6aSjose borrego * smb_server_listener_stop
18344163af6aSjose borrego *
18354163af6aSjose borrego * Stops the listener associated with the context passed in.
18364163af6aSjose borrego */
18374163af6aSjose borrego static void
smb_server_listener_stop(smb_listener_daemon_t * ld)18384163af6aSjose borrego smb_server_listener_stop(smb_listener_daemon_t *ld)
18394163af6aSjose borrego {
18404163af6aSjose borrego SMB_LISTENER_VALID(ld);
18419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
18424163af6aSjose borrego if (ld->ld_so != NULL) {
18434163af6aSjose borrego smb_soshutdown(ld->ld_so);
18444163af6aSjose borrego smb_sodestroy(ld->ld_so);
18454163af6aSjose borrego smb_thread_stop(&ld->ld_thread);
18464163af6aSjose borrego ld->ld_so = NULL;
18474163af6aSjose borrego }
18484163af6aSjose borrego }
18499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
18504163af6aSjose borrego /*
18514163af6aSjose borrego * smb_server_listener
18524163af6aSjose borrego *
18534163af6aSjose borrego * Entry point of the listeners.
18544163af6aSjose borrego */
18554163af6aSjose borrego static void
smb_server_listener(smb_thread_t * thread,void * arg)18564163af6aSjose borrego smb_server_listener(smb_thread_t *thread, void *arg)
18574163af6aSjose borrego {
18584163af6aSjose borrego _NOTE(ARGUNUSED(thread))
18594163af6aSjose borrego smb_listener_daemon_t *ld;
18604163af6aSjose borrego ksocket_t s_so;
18614163af6aSjose borrego int on;
18624163af6aSjose borrego int txbuf_size;
18634163af6aSjose borrego
18644163af6aSjose borrego ld = (smb_listener_daemon_t *)arg;
18654163af6aSjose borrego
18664163af6aSjose borrego SMB_LISTENER_VALID(ld);
18674163af6aSjose borrego
18684163af6aSjose borrego DTRACE_PROBE1(so__wait__accept, struct sonode *, ld->ld_so);
18699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
18709a244c8eSGordon Ross while (smb_thread_continue_nowait(&ld->ld_thread) &&
18719a244c8eSGordon Ross ld->ld_sv->sv_state != SMB_SERVER_STATE_STOPPING) {
187241bd8510Skcrowenex int ret = ksocket_accept(ld->ld_so, NULL, NULL, &s_so, CRED());
187341bd8510Skcrowenex
187441bd8510Skcrowenex switch (ret) {
187541bd8510Skcrowenex case 0:
187641bd8510Skcrowenex break;
187741bd8510Skcrowenex case ECONNABORTED:
187841bd8510Skcrowenex continue;
18799a244c8eSGordon Ross
188041bd8510Skcrowenex case EINTR:
18819a244c8eSGordon Ross case EBADF:
18829a244c8eSGordon Ross case ENOTSOCK:
18839a244c8eSGordon Ross /* These are normal during shutdown. Silence. */
18849a244c8eSGordon Ross if (ld->ld_sv->sv_state == SMB_SERVER_STATE_STOPPING)
18859a244c8eSGordon Ross goto out;
18869a244c8eSGordon Ross /* FALLTHROUGH */
188741bd8510Skcrowenex default:
188841bd8510Skcrowenex cmn_err(CE_WARN,
18897b072888SToomas Soome "smb_server_listener: ksocket_accept failed (%d)",
189041bd8510Skcrowenex ret);
18919a244c8eSGordon Ross /* avoid a tight CPU-burn loop here */
18929a244c8eSGordon Ross delay(MSEC_TO_TICK(10));
18939a244c8eSGordon Ross continue;
189441bd8510Skcrowenex }
189541bd8510Skcrowenex
18969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States DTRACE_PROBE1(so__accept, struct sonode *, s_so);
18979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
18989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States on = 1;
18999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) ksocket_setsockopt(s_so, IPPROTO_TCP, TCP_NODELAY,
19009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States &on, sizeof (on), CRED());
19019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
19029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States on = 1;
19039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_KEEPALIVE,
19049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States &on, sizeof (on), CRED());
19059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
19069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States txbuf_size = 128*1024;
19079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_SNDBUF,
19089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (const void *)&txbuf_size, sizeof (txbuf_size), CRED());
19099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
19109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
19119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Create a session for this connection.
19129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */
19134163af6aSjose borrego smb_server_create_session(ld, s_so);
19149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
191541bd8510Skcrowenex out:
19164163af6aSjose borrego ksocket_rele(ld->ld_so);
19179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1918faa1795aSjb
19194163af6aSjose borrego /*
19204163af6aSjose borrego * smb_server_receiver
19214163af6aSjose borrego *
19224163af6aSjose borrego * Entry point of the receiver threads.
1923811599a4SMatt Barden * Also does cleanup when socket disconnected.
19244163af6aSjose borrego */
19254163af6aSjose borrego static void
smb_server_receiver(void * arg)19264163af6aSjose borrego smb_server_receiver(void *arg)
19279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
1928811599a4SMatt Barden smb_session_t *session;
1929811599a4SMatt Barden
1930811599a4SMatt Barden session = (smb_session_t *)arg;
19319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
1932811599a4SMatt Barden /* We stay in here until socket disconnect. */
19334163af6aSjose borrego smb_session_receiver(session);
1934811599a4SMatt Barden
1935811599a4SMatt Barden smb_server_destroy_session(session);
1936faa1795aSjb }
1937faa1795aSjb
1938faa1795aSjb /*
1939faa1795aSjb * smb_server_lookup
1940faa1795aSjb *
19418622ec45SGordon Ross * This function finds the server associated with the zone of the
19428622ec45SGordon Ross * caller. Note: requires a fix in the dynamic taskq code:
19438622ec45SGordon Ross * 1501 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0
1944faa1795aSjb */
19454846df9bSKevin Crowe int
smb_server_lookup(smb_server_t ** psv)1946faa1795aSjb smb_server_lookup(smb_server_t **psv)
1947faa1795aSjb {
1948faa1795aSjb zoneid_t zid;
1949faa1795aSjb smb_server_t *sv;
1950faa1795aSjb
1951faa1795aSjb zid = getzoneid();
1952faa1795aSjb
1953faa1795aSjb smb_llist_enter(&smb_servers, RW_READER);
1954faa1795aSjb sv = smb_llist_head(&smb_servers);
1955faa1795aSjb while (sv) {
19569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv);
1957faa1795aSjb if (sv->sv_zid == zid) {
1958faa1795aSjb mutex_enter(&sv->sv_mutex);
1959faa1795aSjb if (sv->sv_state != SMB_SERVER_STATE_DELETING) {
1960faa1795aSjb sv->sv_refcnt++;
1961faa1795aSjb mutex_exit(&sv->sv_mutex);
1962faa1795aSjb smb_llist_exit(&smb_servers);
1963faa1795aSjb *psv = sv;
1964faa1795aSjb return (0);
1965faa1795aSjb }
1966faa1795aSjb mutex_exit(&sv->sv_mutex);
1967faa1795aSjb break;
1968faa1795aSjb }
1969faa1795aSjb sv = smb_llist_next(&smb_servers, sv);
1970faa1795aSjb }
1971faa1795aSjb smb_llist_exit(&smb_servers);
1972*34bbc83aSGordon Ross return (ENXIO);
1973faa1795aSjb }
1974faa1795aSjb
1975faa1795aSjb /*
1976faa1795aSjb * smb_server_release
1977faa1795aSjb *
1978faa1795aSjb * This function decrements the reference count of the server and signals its
1979faa1795aSjb * condition variable if the state of the server is SMB_SERVER_STATE_DELETING.
1980faa1795aSjb */
19814846df9bSKevin Crowe void
smb_server_release(smb_server_t * sv)1982faa1795aSjb smb_server_release(smb_server_t *sv)
1983faa1795aSjb {
19849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv);
1985faa1795aSjb
1986faa1795aSjb mutex_enter(&sv->sv_mutex);
1987faa1795aSjb ASSERT(sv->sv_refcnt);
1988faa1795aSjb sv->sv_refcnt--;
1989faa1795aSjb if ((sv->sv_refcnt == 0) && (sv->sv_state == SMB_SERVER_STATE_DELETING))
1990faa1795aSjb cv_signal(&sv->sv_cv);
1991faa1795aSjb mutex_exit(&sv->sv_mutex);
1992faa1795aSjb }
1993faa1795aSjb
199497264293SGordon Ross /*
199597264293SGordon Ross * smb_server_lookup_user
199697264293SGordon Ross *
199797264293SGordon Ross * Find an smb_user by its user_id
199897264293SGordon Ross * Optional ssn_id (if non-zero) restricts search to a specific session.
199997264293SGordon Ross *
200097264293SGordon Ross * Returns smb_user_t * held. Caller must smb_user_rele(user)
200197264293SGordon Ross * Returns NULL if not found.
200297264293SGordon Ross */
200397264293SGordon Ross smb_user_t *
smb_server_lookup_user(smb_server_t * sv,uint64_t ssn_id,uint64_t user_id)200497264293SGordon Ross smb_server_lookup_user(smb_server_t *sv, uint64_t ssn_id, uint64_t user_id)
200597264293SGordon Ross {
200697264293SGordon Ross smb_llist_t *slist = &sv->sv_session_list;
200797264293SGordon Ross smb_session_t *sn;
200897264293SGordon Ross smb_user_t *user = NULL;
200997264293SGordon Ross
201097264293SGordon Ross smb_llist_enter(slist, RW_READER);
201197264293SGordon Ross
201297264293SGordon Ross for (sn = smb_llist_head(slist);
201397264293SGordon Ross sn != NULL && user == NULL;
201497264293SGordon Ross sn = smb_llist_next(slist, sn)) {
201597264293SGordon Ross SMB_SESSION_VALID(sn);
201697264293SGordon Ross
201797264293SGordon Ross if (ssn_id != 0 && ssn_id != sn->s_kid)
201897264293SGordon Ross continue;
201997264293SGordon Ross if (sn->s_state != SMB_SESSION_STATE_NEGOTIATED)
202097264293SGordon Ross continue;
202197264293SGordon Ross
202297264293SGordon Ross user = smb_session_lookup_ssnid(sn, user_id);
202397264293SGordon Ross }
202497264293SGordon Ross smb_llist_exit(slist);
202597264293SGordon Ross
202697264293SGordon Ross return (user);
202797264293SGordon Ross }
202897264293SGordon Ross
20291fcced4cSJordan Brown /*
20301fcced4cSJordan Brown * Enumerate the users associated with a session list.
20311fcced4cSJordan Brown */
20321fcced4cSJordan Brown static void
smb_server_enum_users(smb_server_t * sv,smb_svcenum_t * svcenum)20338d94f651SGordon Ross smb_server_enum_users(smb_server_t *sv, smb_svcenum_t *svcenum)
20341fcced4cSJordan Brown {
20358d94f651SGordon Ross smb_llist_t *ll = &sv->sv_session_list;
20361fcced4cSJordan Brown smb_session_t *sn;
20371fcced4cSJordan Brown smb_llist_t *ulist;
20381fcced4cSJordan Brown smb_user_t *user;
20391fcced4cSJordan Brown int rc = 0;
20401fcced4cSJordan Brown
20414163af6aSjose borrego smb_llist_enter(ll, RW_READER);
20424163af6aSjose borrego sn = smb_llist_head(ll);
20431fcced4cSJordan Brown
20441fcced4cSJordan Brown while (sn != NULL) {
20454163af6aSjose borrego SMB_SESSION_VALID(sn);
20461fcced4cSJordan Brown ulist = &sn->s_user_list;
20471fcced4cSJordan Brown smb_llist_enter(ulist, RW_READER);
20481fcced4cSJordan Brown user = smb_llist_head(ulist);
20491fcced4cSJordan Brown
20501fcced4cSJordan Brown while (user != NULL) {
20511fcced4cSJordan Brown if (smb_user_hold(user)) {
20521fcced4cSJordan Brown rc = smb_user_enum(user, svcenum);
20531fcced4cSJordan Brown smb_user_release(user);
20543b13a1efSThomas Keiser if (rc != 0)
20553b13a1efSThomas Keiser break;
20561fcced4cSJordan Brown }
20571fcced4cSJordan Brown
20581fcced4cSJordan Brown user = smb_llist_next(ulist, user);
20591fcced4cSJordan Brown }
20601fcced4cSJordan Brown
20611fcced4cSJordan Brown smb_llist_exit(ulist);
20621fcced4cSJordan Brown
20631fcced4cSJordan Brown if (rc != 0)
20641fcced4cSJordan Brown break;
20651fcced4cSJordan Brown
20664163af6aSjose borrego sn = smb_llist_next(ll, sn);
20671fcced4cSJordan Brown }
20681fcced4cSJordan Brown
20694163af6aSjose borrego smb_llist_exit(ll);
20701fcced4cSJordan Brown }
20711fcced4cSJordan Brown
20723b13a1efSThomas Keiser /*
20733b13a1efSThomas Keiser * Enumerate the trees/files associated with a session list.
20743b13a1efSThomas Keiser */
20753b13a1efSThomas Keiser static void
smb_server_enum_trees(smb_server_t * sv,smb_svcenum_t * svcenum)20768d94f651SGordon Ross smb_server_enum_trees(smb_server_t *sv, smb_svcenum_t *svcenum)
20773b13a1efSThomas Keiser {
20788d94f651SGordon Ross smb_llist_t *ll = &sv->sv_session_list;
20793b13a1efSThomas Keiser smb_session_t *sn;
20803b13a1efSThomas Keiser smb_llist_t *tlist;
20813b13a1efSThomas Keiser smb_tree_t *tree;
20823b13a1efSThomas Keiser int rc = 0;
20833b13a1efSThomas Keiser
20843b13a1efSThomas Keiser smb_llist_enter(ll, RW_READER);
20853b13a1efSThomas Keiser sn = smb_llist_head(ll);
20863b13a1efSThomas Keiser
20873b13a1efSThomas Keiser while (sn != NULL) {
20883b13a1efSThomas Keiser SMB_SESSION_VALID(sn);
20893b13a1efSThomas Keiser tlist = &sn->s_tree_list;
20903b13a1efSThomas Keiser smb_llist_enter(tlist, RW_READER);
20913b13a1efSThomas Keiser tree = smb_llist_head(tlist);
20923b13a1efSThomas Keiser
20933b13a1efSThomas Keiser while (tree != NULL) {
20943b13a1efSThomas Keiser if (smb_tree_hold(tree)) {
20953b13a1efSThomas Keiser rc = smb_tree_enum(tree, svcenum);
20963b13a1efSThomas Keiser smb_tree_release(tree);
20973b13a1efSThomas Keiser if (rc != 0)
20983b13a1efSThomas Keiser break;
20993b13a1efSThomas Keiser }
21003b13a1efSThomas Keiser
21013b13a1efSThomas Keiser tree = smb_llist_next(tlist, tree);
21023b13a1efSThomas Keiser }
21033b13a1efSThomas Keiser
21043b13a1efSThomas Keiser smb_llist_exit(tlist);
21053b13a1efSThomas Keiser
21063b13a1efSThomas Keiser if (rc != 0)
21073b13a1efSThomas Keiser break;
21083b13a1efSThomas Keiser
21093b13a1efSThomas Keiser sn = smb_llist_next(ll, sn);
21103b13a1efSThomas Keiser }
21113b13a1efSThomas Keiser
21123b13a1efSThomas Keiser smb_llist_exit(ll);
21133b13a1efSThomas Keiser }
21143b13a1efSThomas Keiser
21151fcced4cSJordan Brown /*
21161fcced4cSJordan Brown * Disconnect sessions associated with the specified client and username.
21171fcced4cSJordan Brown * Empty strings are treated as wildcards.
21181fcced4cSJordan Brown */
2119faa1795aSjb static int
smb_server_session_disconnect(smb_server_t * sv,const char * client,const char * name)21208d94f651SGordon Ross smb_server_session_disconnect(smb_server_t *sv,
21211fcced4cSJordan Brown const char *client, const char *name)
2122faa1795aSjb {
21238d94f651SGordon Ross smb_llist_t *ll = &sv->sv_session_list;
21241fcced4cSJordan Brown smb_session_t *sn;
21251fcced4cSJordan Brown smb_llist_t *ulist;
21261fcced4cSJordan Brown smb_user_t *user;
21271fcced4cSJordan Brown int count = 0;
2128faa1795aSjb
21294163af6aSjose borrego smb_llist_enter(ll, RW_READER);
21301fcced4cSJordan Brown
2131811599a4SMatt Barden for (sn = smb_llist_head(ll);
2132811599a4SMatt Barden sn != NULL;
2133811599a4SMatt Barden sn = smb_llist_next(ll, sn)) {
21344163af6aSjose borrego SMB_SESSION_VALID(sn);
21351fcced4cSJordan Brown
2136811599a4SMatt Barden if (*client != '\0' && !smb_session_isclient(sn, client))
21371fcced4cSJordan Brown continue;
21381fcced4cSJordan Brown
2139faa1795aSjb ulist = &sn->s_user_list;
2140faa1795aSjb smb_llist_enter(ulist, RW_READER);
21411fcced4cSJordan Brown
2142811599a4SMatt Barden for (user = smb_llist_head(ulist);
2143811599a4SMatt Barden user != NULL;
2144811599a4SMatt Barden user = smb_llist_next(ulist, user)) {
21451fcced4cSJordan Brown
2146811599a4SMatt Barden if (smb_user_hold(user)) {
2147896d9552SGordon Ross
2148896d9552SGordon Ross if (*name == '\0' ||
2149896d9552SGordon Ross smb_user_namecmp(user, name)) {
2150896d9552SGordon Ross smb_user_logoff(user);
2151896d9552SGordon Ross count++;
2152896d9552SGordon Ross }
2153896d9552SGordon Ross
21541fcced4cSJordan Brown smb_user_release(user);
2155faa1795aSjb }
2156faa1795aSjb }
21571fcced4cSJordan Brown
2158faa1795aSjb smb_llist_exit(ulist);
2159faa1795aSjb }
21601fcced4cSJordan Brown
21614163af6aSjose borrego smb_llist_exit(ll);
21621fcced4cSJordan Brown return (count);
21631fcced4cSJordan Brown }
21641fcced4cSJordan Brown
21651fcced4cSJordan Brown /*
21661fcced4cSJordan Brown * Close a file by its unique id.
21671fcced4cSJordan Brown */
21681fcced4cSJordan Brown static int
smb_server_fclose(smb_server_t * sv,uint32_t uniqid)21698d94f651SGordon Ross smb_server_fclose(smb_server_t *sv, uint32_t uniqid)
21701fcced4cSJordan Brown {
21718d94f651SGordon Ross smb_llist_t *ll;
21721fcced4cSJordan Brown smb_session_t *sn;
21733b13a1efSThomas Keiser smb_llist_t *tlist;
21743b13a1efSThomas Keiser smb_tree_t *tree;
21751fcced4cSJordan Brown int rc = ENOENT;
21761fcced4cSJordan Brown
21778d94f651SGordon Ross ll = &sv->sv_session_list;
21784163af6aSjose borrego smb_llist_enter(ll, RW_READER);
21794163af6aSjose borrego sn = smb_llist_head(ll);
21801fcced4cSJordan Brown
21811fcced4cSJordan Brown while ((sn != NULL) && (rc == ENOENT)) {
21824163af6aSjose borrego SMB_SESSION_VALID(sn);
21833b13a1efSThomas Keiser tlist = &sn->s_tree_list;
21843b13a1efSThomas Keiser smb_llist_enter(tlist, RW_READER);
21853b13a1efSThomas Keiser tree = smb_llist_head(tlist);
21863b13a1efSThomas Keiser
21873b13a1efSThomas Keiser while ((tree != NULL) && (rc == ENOENT)) {
21883b13a1efSThomas Keiser if (smb_tree_hold(tree)) {
21893b13a1efSThomas Keiser rc = smb_tree_fclose(tree, uniqid);
21903b13a1efSThomas Keiser smb_tree_release(tree);
21911fcced4cSJordan Brown }
21921fcced4cSJordan Brown
21933b13a1efSThomas Keiser tree = smb_llist_next(tlist, tree);
21941fcced4cSJordan Brown }
21951fcced4cSJordan Brown
21963b13a1efSThomas Keiser smb_llist_exit(tlist);
21974163af6aSjose borrego sn = smb_llist_next(ll, sn);
21981fcced4cSJordan Brown }
21991fcced4cSJordan Brown
22004163af6aSjose borrego smb_llist_exit(ll);
22011fcced4cSJordan Brown return (rc);
2202faa1795aSjb }
2203faa1795aSjb
2204811599a4SMatt Barden /*
2205811599a4SMatt Barden * This is used by SMB2 session setup to logoff a previous session,
2206811599a4SMatt Barden * so it can force a logoff that we haven't noticed yet.
2207811599a4SMatt Barden * This is not called frequently, so we just walk the list of
2208811599a4SMatt Barden * connections searching for the user.
22091baeef30SPrashanth Badari *
22101baeef30SPrashanth Badari * Note that this must wait for any durable handles (ofiles)
22111baeef30SPrashanth Badari * owned by this user to become "orphaned", so that a reconnect
22121baeef30SPrashanth Badari * that may immediately follow can find and use such ofiles.
2213811599a4SMatt Barden */
2214811599a4SMatt Barden void
smb_server_logoff_ssnid(smb_request_t * sr,uint64_t ssnid)2215811599a4SMatt Barden smb_server_logoff_ssnid(smb_request_t *sr, uint64_t ssnid)
2216811599a4SMatt Barden {
2217811599a4SMatt Barden smb_server_t *sv = sr->sr_server;
2218811599a4SMatt Barden smb_llist_t *sess_list;
2219811599a4SMatt Barden smb_session_t *sess;
22201baeef30SPrashanth Badari smb_user_t *user = NULL;
22210c5f22c1SGordon Ross boolean_t do_logoff = B_FALSE;
22221baeef30SPrashanth Badari
22231baeef30SPrashanth Badari SMB_SERVER_VALID(sv);
2224811599a4SMatt Barden
2225811599a4SMatt Barden if (sv->sv_state != SMB_SERVER_STATE_RUNNING)
2226811599a4SMatt Barden return;
2227811599a4SMatt Barden
2228811599a4SMatt Barden sess_list = &sv->sv_session_list;
2229811599a4SMatt Barden smb_llist_enter(sess_list, RW_READER);
2230811599a4SMatt Barden
2231811599a4SMatt Barden for (sess = smb_llist_head(sess_list);
2232811599a4SMatt Barden sess != NULL;
2233811599a4SMatt Barden sess = smb_llist_next(sess_list, sess)) {
2234811599a4SMatt Barden
2235811599a4SMatt Barden SMB_SESSION_VALID(sess);
2236811599a4SMatt Barden
2237811599a4SMatt Barden if (sess->dialect < SMB_VERS_2_BASE)
2238811599a4SMatt Barden continue;
2239811599a4SMatt Barden
22401baeef30SPrashanth Badari switch (sess->s_state) {
22411baeef30SPrashanth Badari case SMB_SESSION_STATE_NEGOTIATED:
22421baeef30SPrashanth Badari case SMB_SESSION_STATE_TERMINATED:
22431baeef30SPrashanth Badari case SMB_SESSION_STATE_DISCONNECTED:
22441baeef30SPrashanth Badari break;
22451baeef30SPrashanth Badari default:
2246811599a4SMatt Barden continue;
22471baeef30SPrashanth Badari }
2248811599a4SMatt Barden
22491baeef30SPrashanth Badari /*
22501baeef30SPrashanth Badari * Normal situation is to find a LOGGED_ON user.
22511baeef30SPrashanth Badari */
22521baeef30SPrashanth Badari user = smb_session_lookup_uid_st(sess, ssnid, 0,
22531baeef30SPrashanth Badari SMB_USER_STATE_LOGGED_ON);
22541baeef30SPrashanth Badari if (user != NULL) {
22551baeef30SPrashanth Badari if (smb_is_same_user(user->u_cred, sr->user_cr)) {
22560c5f22c1SGordon Ross do_logoff = B_TRUE;
22571baeef30SPrashanth Badari break;
22581baeef30SPrashanth Badari }
22591baeef30SPrashanth Badari smb_user_release(user);
22601baeef30SPrashanth Badari user = NULL;
22611baeef30SPrashanth Badari }
2262811599a4SMatt Barden
22631baeef30SPrashanth Badari /*
22641baeef30SPrashanth Badari * If we raced with disconnect, may find LOGGING_OFF,
22651baeef30SPrashanth Badari * in which case we want to just wait for it.
22661baeef30SPrashanth Badari */
22671baeef30SPrashanth Badari user = smb_session_lookup_uid_st(sess, ssnid, 0,
22681baeef30SPrashanth Badari SMB_USER_STATE_LOGGING_OFF);
22691baeef30SPrashanth Badari if (user != NULL) {
22701baeef30SPrashanth Badari if (smb_is_same_user(user->u_cred, sr->user_cr))
22711baeef30SPrashanth Badari break;
2272811599a4SMatt Barden smb_user_release(user);
22731baeef30SPrashanth Badari user = NULL;
2274811599a4SMatt Barden }
22751baeef30SPrashanth Badari }
2276811599a4SMatt Barden
22771baeef30SPrashanth Badari smb_llist_exit(sess_list);
22781baeef30SPrashanth Badari
22790c5f22c1SGordon Ross /*
22800c5f22c1SGordon Ross * Note that smb_user_logoff() can block for a while if
22810c5f22c1SGordon Ross * smb_session_disconnect_owned_trees, smb_ofile_close_all
22820c5f22c1SGordon Ross * ends up blocked on locks held by running requests.
22830c5f22c1SGordon Ross * Do that while not holding the session list rwlock.
22840c5f22c1SGordon Ross */
22851baeef30SPrashanth Badari if (user != NULL) {
22860c5f22c1SGordon Ross if (do_logoff) {
22870c5f22c1SGordon Ross /* Treat this as if we lost the connection */
22880c5f22c1SGordon Ross user->preserve_opens = SMB2_DH_PRESERVE_SOME;
22890c5f22c1SGordon Ross smb_user_logoff(user);
22900c5f22c1SGordon Ross }
22910c5f22c1SGordon Ross
22921baeef30SPrashanth Badari /*
22931baeef30SPrashanth Badari * Wait for durable handles to be orphaned.
22941baeef30SPrashanth Badari * Note: not holding the sess list rwlock.
22951baeef30SPrashanth Badari */
22961baeef30SPrashanth Badari smb_user_wait_trees(user);
2297811599a4SMatt Barden
2298811599a4SMatt Barden /*
22991baeef30SPrashanth Badari * Could be doing the last release on a user below,
23001baeef30SPrashanth Badari * which can leave work on the delete queues for
23011baeef30SPrashanth Badari * s_user_list or s_tree_list so flush those.
23021baeef30SPrashanth Badari * Must hold the session list after the user release
23031baeef30SPrashanth Badari * so that the session can't go away while we flush.
2304811599a4SMatt Barden */
23051baeef30SPrashanth Badari smb_llist_enter(sess_list, RW_READER);
23061baeef30SPrashanth Badari
23071baeef30SPrashanth Badari sess = user->u_session;
23081baeef30SPrashanth Badari smb_user_release(user);
23091baeef30SPrashanth Badari
2310811599a4SMatt Barden smb_llist_flush(&sess->s_tree_list);
2311811599a4SMatt Barden smb_llist_flush(&sess->s_user_list);
2312811599a4SMatt Barden
23131baeef30SPrashanth Badari smb_llist_exit(sess_list);
23141baeef30SPrashanth Badari }
2315811599a4SMatt Barden }
2316811599a4SMatt Barden
231712b65585SGordon Ross /* See also: libsmb smb_kmod_setcfg */
2318faa1795aSjb static void
smb_server_store_cfg(smb_server_t * sv,smb_ioc_cfg_t * ioc)231929bd2886SAlan Wright smb_server_store_cfg(smb_server_t *sv, smb_ioc_cfg_t *ioc)
2320faa1795aSjb {
232129bd2886SAlan Wright if (ioc->maxconnections == 0)
232229bd2886SAlan Wright ioc->maxconnections = 0xFFFFFFFF;
2323faa1795aSjb
23241160dcf7SMatt Barden if (ioc->encrypt == SMB_CONFIG_REQUIRED &&
23251160dcf7SMatt Barden ioc->max_protocol < SMB_VERS_3_0) {
23261160dcf7SMatt Barden cmn_err(CE_WARN, "Server set to require encryption; "
23271160dcf7SMatt Barden "forcing max_protocol to 3.0");
23281160dcf7SMatt Barden ioc->max_protocol = SMB_VERS_3_0;
23291160dcf7SMatt Barden }
233029bd2886SAlan Wright sv->sv_cfg.skc_maxworkers = ioc->maxworkers;
233129bd2886SAlan Wright sv->sv_cfg.skc_maxconnections = ioc->maxconnections;
233229bd2886SAlan Wright sv->sv_cfg.skc_keepalive = ioc->keepalive;
233329bd2886SAlan Wright sv->sv_cfg.skc_restrict_anon = ioc->restrict_anon;
233429bd2886SAlan Wright sv->sv_cfg.skc_signing_enable = ioc->signing_enable;
233529bd2886SAlan Wright sv->sv_cfg.skc_signing_required = ioc->signing_required;
233629bd2886SAlan Wright sv->sv_cfg.skc_oplock_enable = ioc->oplock_enable;
233729bd2886SAlan Wright sv->sv_cfg.skc_sync_enable = ioc->sync_enable;
233829bd2886SAlan Wright sv->sv_cfg.skc_secmode = ioc->secmode;
233912b65585SGordon Ross sv->sv_cfg.skc_netbios_enable = ioc->netbios_enable;
234029bd2886SAlan Wright sv->sv_cfg.skc_ipv6_enable = ioc->ipv6_enable;
2341cb174861Sjoyce mcintosh sv->sv_cfg.skc_print_enable = ioc->print_enable;
23425f1ef25cSAram Hăvărneanu sv->sv_cfg.skc_traverse_mounts = ioc->traverse_mounts;
2343814e0daaSGordon Ross sv->sv_cfg.skc_short_names = ioc->short_names;
2344a90cf9f2SGordon Ross sv->sv_cfg.skc_max_protocol = ioc->max_protocol;
23453e2c0c09SMatt Barden sv->sv_cfg.skc_min_protocol = ioc->min_protocol;
23461160dcf7SMatt Barden sv->sv_cfg.skc_encrypt = ioc->encrypt;
2347b0bb0d63SGordon Ross sv->sv_cfg.skc_encrypt_ciphers = ioc->encrypt_ciphers;
2348148c5f43SAlan Wright sv->sv_cfg.skc_execflags = ioc->exec_flags;
234912b65585SGordon Ross sv->sv_cfg.skc_negtok_len = ioc->negtok_len;
23502cf6b79fSGordon Ross sv->sv_cfg.skc_max_opens = ioc->max_opens;
2351148c5f43SAlan Wright sv->sv_cfg.skc_version = ioc->version;
2352a90cf9f2SGordon Ross sv->sv_cfg.skc_initial_credits = ioc->initial_credits;
2353a90cf9f2SGordon Ross sv->sv_cfg.skc_maximum_credits = ioc->maximum_credits;
2354a90cf9f2SGordon Ross
235512b65585SGordon Ross (void) memcpy(sv->sv_cfg.skc_machine_uuid, ioc->machine_uuid,
235612b65585SGordon Ross sizeof (uuid_t));
235712b65585SGordon Ross (void) memcpy(sv->sv_cfg.skc_negtok, ioc->negtok,
235812b65585SGordon Ross sizeof (sv->sv_cfg.skc_negtok));
235912b65585SGordon Ross (void) memcpy(sv->sv_cfg.skc_native_os, ioc->native_os,
236012b65585SGordon Ross sizeof (sv->sv_cfg.skc_native_os));
236112b65585SGordon Ross (void) memcpy(sv->sv_cfg.skc_native_lm, ioc->native_lm,
236212b65585SGordon Ross sizeof (sv->sv_cfg.skc_native_lm));
236312b65585SGordon Ross
236429bd2886SAlan Wright (void) strlcpy(sv->sv_cfg.skc_nbdomain, ioc->nbdomain,
236529bd2886SAlan Wright sizeof (sv->sv_cfg.skc_nbdomain));
236629bd2886SAlan Wright (void) strlcpy(sv->sv_cfg.skc_fqdn, ioc->fqdn,
236729bd2886SAlan Wright sizeof (sv->sv_cfg.skc_fqdn));
236829bd2886SAlan Wright (void) strlcpy(sv->sv_cfg.skc_hostname, ioc->hostname,
236929bd2886SAlan Wright sizeof (sv->sv_cfg.skc_hostname));
237029bd2886SAlan Wright (void) strlcpy(sv->sv_cfg.skc_system_comment, ioc->system_comment,
237129bd2886SAlan Wright sizeof (sv->sv_cfg.skc_system_comment));
2372faa1795aSjb }
2373faa1795aSjb
2374faa1795aSjb static int
smb_server_fsop_start(smb_server_t * sv)2375faa1795aSjb smb_server_fsop_start(smb_server_t *sv)
2376faa1795aSjb {
2377faa1795aSjb int error;
2378faa1795aSjb
23798622ec45SGordon Ross error = smb_node_root_init(sv, &sv->si_root_smb_node);
2380faa1795aSjb if (error != 0)
2381faa1795aSjb sv->si_root_smb_node = NULL;
2382faa1795aSjb
2383faa1795aSjb return (error);
2384faa1795aSjb }
2385faa1795aSjb
2386faa1795aSjb static void
smb_server_fsop_stop(smb_server_t * sv)2387faa1795aSjb smb_server_fsop_stop(smb_server_t *sv)
2388faa1795aSjb {
2389faa1795aSjb if (sv->si_root_smb_node != NULL) {
2390faa1795aSjb smb_node_release(sv->si_root_smb_node);
2391faa1795aSjb sv->si_root_smb_node = NULL;
2392faa1795aSjb }
2393faa1795aSjb }
23949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
23959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_t *
smb_event_create(smb_server_t * sv,int timeout)23968622ec45SGordon Ross smb_event_create(smb_server_t *sv, int timeout)
23979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
23989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_t *event;
23999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24008622ec45SGordon Ross if (smb_server_is_stopping(sv))
24019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (NULL);
24029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24038622ec45SGordon Ross event = kmem_cache_alloc(smb_cache_event, KM_SLEEP);
24049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States bzero(event, sizeof (smb_event_t));
24069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_init(&event->se_mutex, NULL, MUTEX_DEFAULT, NULL);
24079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_init(&event->se_cv, NULL, CV_DEFAULT, NULL);
24089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_magic = SMB_EVENT_MAGIC;
24099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_txid = smb_event_alloc_txid();
24109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_server = sv;
2411cb174861Sjoyce mcintosh event->se_timeout = timeout;
24129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_enter(&sv->sv_event_list, RW_WRITER);
24149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_insert_tail(&sv->sv_event_list, event);
24159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_exit(&sv->sv_event_list);
24169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (event);
24189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
24199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
smb_event_destroy(smb_event_t * event)24219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_destroy(smb_event_t *event)
24229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
24239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_t *sv;
24249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (event == NULL)
24269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return;
24279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event);
24299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ASSERT(event->se_waittime == 0);
24308622ec45SGordon Ross sv = event->se_server;
24318622ec45SGordon Ross SMB_SERVER_VALID(sv);
24329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_enter(&sv->sv_event_list, RW_WRITER);
24349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_remove(&sv->sv_event_list, event);
24359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_exit(&sv->sv_event_list);
24369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_magic = (uint32_t)~SMB_EVENT_MAGIC;
24389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_destroy(&event->se_cv);
24399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_destroy(&event->se_mutex);
24409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24418622ec45SGordon Ross kmem_cache_free(smb_cache_event, event);
24429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
24439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
24459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Get the txid for the specified event.
24469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */
24479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t
smb_event_txid(smb_event_t * event)24489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_txid(smb_event_t *event)
24499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
24509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (event != NULL) {
24519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event);
24529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (event->se_txid);
24539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
24549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cmn_err(CE_NOTE, "smb_event_txid failed");
24569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return ((uint32_t)-1);
24579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
24589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
24609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Wait for event notification.
24619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */
24629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
smb_event_wait(smb_event_t * event)24639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_wait(smb_event_t *event)
24649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
24659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int seconds = 1;
24669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int ticks;
2467856399cfSGordon Ross int err;
24689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (event == NULL)
24709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (EINVAL);
24719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event);
24739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&event->se_mutex);
24759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_waittime = 1;
24769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_errno = 0;
24779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States while (!(event->se_notified)) {
2479c5866007SKeyur Desai if (smb_event_debug && ((event->se_waittime % 30) == 0))
24809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cmn_err(CE_NOTE, "smb_event_wait[%d] (%d sec)",
24819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_txid, event->se_waittime);
24829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (event->se_errno != 0)
24849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break;
24859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
2486cb174861Sjoyce mcintosh if (event->se_waittime > event->se_timeout) {
24879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_errno = ETIME;
24889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break;
24899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
24909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
24919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ticks = SEC_TO_TICK(seconds);
24929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) cv_reltimedwait(&event->se_cv,
24939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States &event->se_mutex, (clock_t)ticks, TR_CLOCK_TICK);
24949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ++event->se_waittime;
24959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
24969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
2497856399cfSGordon Ross err = event->se_errno;
24989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_waittime = 0;
24999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_notified = B_FALSE;
25009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_signal(&event->se_cv);
25019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&event->se_mutex);
2502856399cfSGordon Ross return (err);
25039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
25049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
25069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * If txid is non-zero, cancel the specified event.
25079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Otherwise, cancel all events.
25089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */
25099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void
smb_event_cancel(smb_server_t * sv,uint32_t txid)25109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_cancel(smb_server_t *sv, uint32_t txid)
25119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
25129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_t *event;
25139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_t *event_list;
25149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv);
25169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event_list = &sv->sv_event_list;
25189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_enter(event_list, RW_WRITER);
25199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event = smb_llist_head(event_list);
25219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States while (event) {
25229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event);
25239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid == 0 || event->se_txid == txid) {
25259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&event->se_mutex);
25269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_errno = ECANCELED;
25279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_notified = B_TRUE;
25289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_signal(&event->se_cv);
25299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&event->se_mutex);
25309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid != 0)
25329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break;
25339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
25349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event = smb_llist_next(event_list, event);
25369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
25379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_exit(event_list);
25399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
25409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
25429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * If txid is non-zero, notify the specified event.
25439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Otherwise, notify all events.
25449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */
2545cb174861Sjoyce mcintosh void
smb_event_notify(smb_server_t * sv,uint32_t txid)25469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_notify(smb_server_t *sv, uint32_t txid)
25479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
25489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_t *event;
25499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_t *event_list;
25509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv);
25529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event_list = &sv->sv_event_list;
25549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_enter(event_list, RW_READER);
25559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event = smb_llist_head(event_list);
25579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States while (event) {
25589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event);
25599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid == 0 || event->se_txid == txid) {
25619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&event->se_mutex);
25629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_notified = B_TRUE;
25639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_signal(&event->se_cv);
25649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&event->se_mutex);
25659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid != 0)
25679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break;
25689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
25699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event = smb_llist_next(event_list, event);
25719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
25729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_exit(event_list);
25749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
25759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /*
25779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Allocate a new transaction id (txid).
25789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States *
25799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 0 or -1 are not assigned because they are used to detect invalid
25809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * conditions or to indicate all open id's.
25819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */
25829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static uint32_t
smb_event_alloc_txid(void)25839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_alloc_txid(void)
25849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
25859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static kmutex_t txmutex;
25869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static uint32_t txid;
25879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t txid_ret;
25889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&txmutex);
25909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid == 0)
25929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States txid = ddi_get_lbolt() << 11;
25939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States do {
25959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ++txid;
25969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } while (txid == 0 || txid == (uint32_t)-1);
25979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
25989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States txid_ret = txid;
25999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&txmutex);
26009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
26019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (txid_ret);
26029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
2603cb174861Sjoyce mcintosh
2604cb174861Sjoyce mcintosh /*
2605cb174861Sjoyce mcintosh * Called by the ioctl to find the corresponding
2606cb174861Sjoyce mcintosh * spooldoc node. removes node on success
2607cb174861Sjoyce mcintosh *
2608cb174861Sjoyce mcintosh * Return values
2609cb174861Sjoyce mcintosh * rc
2610cb174861Sjoyce mcintosh * B_FALSE - not found
2611cb174861Sjoyce mcintosh * B_TRUE - found
2612cb174861Sjoyce mcintosh *
2613cb174861Sjoyce mcintosh */
2614cb174861Sjoyce mcintosh
261523a9c295SGordon Ross static boolean_t
smb_spool_lookup_doc_byfid(smb_server_t * sv,uint16_t fid,smb_kspooldoc_t * spdoc)261623a9c295SGordon Ross smb_spool_lookup_doc_byfid(smb_server_t *sv, uint16_t fid,
261723a9c295SGordon Ross smb_kspooldoc_t *spdoc)
2618cb174861Sjoyce mcintosh {
2619cb174861Sjoyce mcintosh smb_kspooldoc_t *sp;
2620cb174861Sjoyce mcintosh smb_llist_t *splist;
2621cb174861Sjoyce mcintosh
2622cb174861Sjoyce mcintosh splist = &sv->sp_info.sp_list;
2623cb174861Sjoyce mcintosh smb_llist_enter(splist, RW_WRITER);
2624cb174861Sjoyce mcintosh sp = smb_llist_head(splist);
2625cb174861Sjoyce mcintosh while (sp != NULL) {
2626cb174861Sjoyce mcintosh /*
2627cb174861Sjoyce mcintosh * check for a matching fid
2628cb174861Sjoyce mcintosh */
2629cb174861Sjoyce mcintosh if (sp->sd_fid == fid) {
2630cb174861Sjoyce mcintosh *spdoc = *sp;
2631cb174861Sjoyce mcintosh smb_llist_remove(splist, sp);
2632cb174861Sjoyce mcintosh smb_llist_exit(splist);
2633cb174861Sjoyce mcintosh kmem_free(sp, sizeof (smb_kspooldoc_t));
2634cb174861Sjoyce mcintosh return (B_TRUE);
2635cb174861Sjoyce mcintosh }
2636cb174861Sjoyce mcintosh sp = smb_llist_next(splist, sp);
2637cb174861Sjoyce mcintosh }
2638cb174861Sjoyce mcintosh cmn_err(CE_WARN, "smb_spool_lookup_user_byfid: no fid:%d", fid);
2639cb174861Sjoyce mcintosh smb_llist_exit(splist);
2640cb174861Sjoyce mcintosh return (B_FALSE);
2641cb174861Sjoyce mcintosh }
2642cb174861Sjoyce mcintosh
2643cb174861Sjoyce mcintosh /*
2644cb174861Sjoyce mcintosh * Adds the spool fid to a linked list to be used
2645cb174861Sjoyce mcintosh * as a search key in the spooldoc queue
2646cb174861Sjoyce mcintosh *
2647cb174861Sjoyce mcintosh * Return values
2648cb174861Sjoyce mcintosh * rc non-zero error
2649cb174861Sjoyce mcintosh * rc zero success
2650cb174861Sjoyce mcintosh *
2651cb174861Sjoyce mcintosh */
2652cb174861Sjoyce mcintosh
265386d7016bSGordon Ross void
smb_spool_add_fid(smb_server_t * sv,uint16_t fid)265486d7016bSGordon Ross smb_spool_add_fid(smb_server_t *sv, uint16_t fid)
2655cb174861Sjoyce mcintosh {
2656cb174861Sjoyce mcintosh smb_llist_t *fidlist;
2657cb174861Sjoyce mcintosh smb_spoolfid_t *sf;
2658cb174861Sjoyce mcintosh
265986d7016bSGordon Ross if (sv->sv_cfg.skc_print_enable == 0)
266086d7016bSGordon Ross return;
2661cb174861Sjoyce mcintosh
2662cb174861Sjoyce mcintosh sf = kmem_zalloc(sizeof (smb_spoolfid_t), KM_SLEEP);
2663cb174861Sjoyce mcintosh fidlist = &sv->sp_info.sp_fidlist;
2664cb174861Sjoyce mcintosh smb_llist_enter(fidlist, RW_WRITER);
2665cb174861Sjoyce mcintosh sf->sf_fid = fid;
2666cb174861Sjoyce mcintosh smb_llist_insert_tail(fidlist, sf);
2667cb174861Sjoyce mcintosh smb_llist_exit(fidlist);
266886d7016bSGordon Ross cv_broadcast(&sv->sp_info.sp_cv);
2669cb174861Sjoyce mcintosh }
2670cb174861Sjoyce mcintosh
2671cb174861Sjoyce mcintosh /*
2672cb174861Sjoyce mcintosh * Called by the ioctl to get and remove the head of the fid list
2673cb174861Sjoyce mcintosh *
2674cb174861Sjoyce mcintosh * Return values
2675cb174861Sjoyce mcintosh * int fd
2676cb174861Sjoyce mcintosh * greater than 0 success
2677cb174861Sjoyce mcintosh * 0 - error
2678cb174861Sjoyce mcintosh *
2679cb174861Sjoyce mcintosh */
2680cb174861Sjoyce mcintosh
268123a9c295SGordon Ross static uint16_t
smb_spool_get_fid(smb_server_t * sv)268223a9c295SGordon Ross smb_spool_get_fid(smb_server_t *sv)
2683cb174861Sjoyce mcintosh {
2684cb174861Sjoyce mcintosh smb_spoolfid_t *spfid;
2685cb174861Sjoyce mcintosh smb_llist_t *splist;
2686cb174861Sjoyce mcintosh uint16_t fid;
2687cb174861Sjoyce mcintosh
2688cb174861Sjoyce mcintosh splist = &sv->sp_info.sp_fidlist;
2689cb174861Sjoyce mcintosh smb_llist_enter(splist, RW_WRITER);
2690cb174861Sjoyce mcintosh spfid = smb_llist_head(splist);
2691cb174861Sjoyce mcintosh if (spfid != NULL) {
2692cb174861Sjoyce mcintosh fid = spfid->sf_fid;
2693cb174861Sjoyce mcintosh smb_llist_remove(&sv->sp_info.sp_fidlist, spfid);
2694cb174861Sjoyce mcintosh kmem_free(spfid, sizeof (smb_spoolfid_t));
2695cb174861Sjoyce mcintosh } else {
2696cb174861Sjoyce mcintosh fid = 0;
2697cb174861Sjoyce mcintosh }
2698cb174861Sjoyce mcintosh smb_llist_exit(splist);
2699cb174861Sjoyce mcintosh return (fid);
2700cb174861Sjoyce mcintosh }
2701cb174861Sjoyce mcintosh
2702cb174861Sjoyce mcintosh /*
2703cb174861Sjoyce mcintosh * Adds the spooldoc to the tail of the spooldoc list
2704cb174861Sjoyce mcintosh *
2705cb174861Sjoyce mcintosh * Return values
2706cb174861Sjoyce mcintosh * rc non-zero error
2707cb174861Sjoyce mcintosh * rc zero success
2708cb174861Sjoyce mcintosh */
2709cb174861Sjoyce mcintosh int
smb_spool_add_doc(smb_tree_t * tree,smb_kspooldoc_t * sp)27108622ec45SGordon Ross smb_spool_add_doc(smb_tree_t *tree, smb_kspooldoc_t *sp)
2711cb174861Sjoyce mcintosh {
2712cb174861Sjoyce mcintosh smb_llist_t *splist;
27138622ec45SGordon Ross smb_server_t *sv = tree->t_server;
2714cb174861Sjoyce mcintosh int rc = 0;
2715cb174861Sjoyce mcintosh
2716cb174861Sjoyce mcintosh splist = &sv->sp_info.sp_list;
2717cb174861Sjoyce mcintosh smb_llist_enter(splist, RW_WRITER);
271823a9c295SGordon Ross sp->sd_spool_num = atomic_inc_32_nv(&sv->sp_info.sp_cnt);
2719cb174861Sjoyce mcintosh smb_llist_insert_tail(splist, sp);
2720cb174861Sjoyce mcintosh smb_llist_exit(splist);
27218622ec45SGordon Ross
2722cb174861Sjoyce mcintosh return (rc);
2723cb174861Sjoyce mcintosh }
27244163af6aSjose borrego
27254163af6aSjose borrego /*
27264163af6aSjose borrego * smb_server_create_session
27274163af6aSjose borrego */
27284163af6aSjose borrego static void
smb_server_create_session(smb_listener_daemon_t * ld,ksocket_t s_so)27294163af6aSjose borrego smb_server_create_session(smb_listener_daemon_t *ld, ksocket_t s_so)
27304163af6aSjose borrego {
273161b20185SGordon Ross smb_server_t *sv = ld->ld_sv;
27324163af6aSjose borrego smb_session_t *session;
2733811599a4SMatt Barden smb_llist_t *sl;
273461b20185SGordon Ross taskqid_t tqid;
273561b20185SGordon Ross clock_t now;
27364163af6aSjose borrego
2737811599a4SMatt Barden session = smb_session_create(s_so, ld->ld_port, sv,
27384163af6aSjose borrego ld->ld_family);
27394163af6aSjose borrego
27408622ec45SGordon Ross if (session == NULL) {
274161b20185SGordon Ross /* This should be rare (create sleeps) */
27428622ec45SGordon Ross smb_soshutdown(s_so);
27438622ec45SGordon Ross smb_sodestroy(s_so);
27448622ec45SGordon Ross cmn_err(CE_WARN, "SMB Session: alloc failed");
27458622ec45SGordon Ross return;
27468622ec45SGordon Ross }
27474163af6aSjose borrego
2748811599a4SMatt Barden sl = &sv->sv_session_list;
2749811599a4SMatt Barden smb_llist_enter(sl, RW_WRITER);
275061b20185SGordon Ross if (smb_llist_get_count(sl) >= sv->sv_cfg.skc_maxconnections) {
275161b20185SGordon Ross /*
275261b20185SGordon Ross * New session not in sv_session_list, so we can just
275361b20185SGordon Ross * delete it directly.
275461b20185SGordon Ross */
275561b20185SGordon Ross smb_llist_exit(sl);
275661b20185SGordon Ross DTRACE_PROBE1(maxconn, smb_session_t *, session);
275761b20185SGordon Ross smb_soshutdown(session->sock);
275861b20185SGordon Ross smb_session_delete(session);
275961b20185SGordon Ross goto logmaxconn;
276061b20185SGordon Ross }
2761811599a4SMatt Barden smb_llist_insert_tail(sl, session);
2762811599a4SMatt Barden smb_llist_exit(sl);
27638622ec45SGordon Ross
27648622ec45SGordon Ross /*
27658622ec45SGordon Ross * These taskq entries must run independently of one another,
27668622ec45SGordon Ross * so TQ_NOQUEUE. TQ_SLEEP (==0) just for clarity.
27678622ec45SGordon Ross */
2768811599a4SMatt Barden tqid = taskq_dispatch(sv->sv_receiver_pool,
2769811599a4SMatt Barden smb_server_receiver, session, TQ_NOQUEUE | TQ_SLEEP);
27709788d6deSGordon Ross if (tqid != TASKQID_INVALID) {
27719788d6deSGordon Ross /* Success */
27729788d6deSGordon Ross return;
27734163af6aSjose borrego }
277461b20185SGordon Ross
27759788d6deSGordon Ross /*
27769788d6deSGordon Ross * Have: tqid == TASKQID_INVALID
27779788d6deSGordon Ross * We never entered smb_server_receiver()
27789788d6deSGordon Ross * so need to do its return cleanup
27799788d6deSGordon Ross */
27809788d6deSGordon Ross DTRACE_PROBE1(maxconn, smb_session_t *, session);
27819788d6deSGordon Ross smb_session_disconnect(session);
27829788d6deSGordon Ross smb_session_logoff(session);
27839788d6deSGordon Ross smb_server_destroy_session(session);
278461b20185SGordon Ross
278561b20185SGordon Ross logmaxconn:
278661b20185SGordon Ross /*
278761b20185SGordon Ross * If we hit max_connections, log something so an admin
278861b20185SGordon Ross * can find out why new connections are failing, but
278961b20185SGordon Ross * log this no more than once a minute.
279061b20185SGordon Ross */
279161b20185SGordon Ross now = ddi_get_lbolt();
279261b20185SGordon Ross if (now > ld->ld_quiet) {
279361b20185SGordon Ross ld->ld_quiet = now + SEC_TO_TICK(60);
279461b20185SGordon Ross cmn_err(CE_WARN, "SMB can't create session: "
279561b20185SGordon Ross "Would exceed max_connections.");
279661b20185SGordon Ross }
27974163af6aSjose borrego }
27984163af6aSjose borrego
27994163af6aSjose borrego static void
smb_server_destroy_session(smb_session_t * session)2800811599a4SMatt Barden smb_server_destroy_session(smb_session_t *session)
28014163af6aSjose borrego {
2802811599a4SMatt Barden smb_server_t *sv;
2803811599a4SMatt Barden smb_llist_t *ll;
2804811599a4SMatt Barden uint32_t count;
2805811599a4SMatt Barden
2806811599a4SMatt Barden ASSERT(session->s_server != NULL);
2807811599a4SMatt Barden sv = session->s_server;
2808811599a4SMatt Barden ll = &sv->sv_session_list;
2809811599a4SMatt Barden
2810811599a4SMatt Barden smb_llist_flush(&session->s_tree_list);
2811811599a4SMatt Barden smb_llist_flush(&session->s_user_list);
2812811599a4SMatt Barden
2813811599a4SMatt Barden smb_llist_enter(ll, RW_WRITER);
2814811599a4SMatt Barden smb_llist_remove(ll, session);
2815811599a4SMatt Barden count = ll->ll_count;
2816811599a4SMatt Barden smb_llist_exit(ll);
2817811599a4SMatt Barden
28187f5d80fdSGordon Ross /*
28197f5d80fdSGordon Ross * Normally, the session should have state SHUTDOWN here.
28207f5d80fdSGordon Ross * If the session has any ofiles remaining, eg. due to
28217f5d80fdSGordon Ross * forgotten ofile references or something, the state
28227f5d80fdSGordon Ross * will be _DISCONNECTED or _TERMINATED. Keep such
28237f5d80fdSGordon Ross * sessions in the list of zombies (for debugging).
28247f5d80fdSGordon Ross */
28257f5d80fdSGordon Ross if (session->s_state == SMB_SESSION_STATE_SHUTDOWN) {
28267f5d80fdSGordon Ross smb_session_delete(session);
28277f5d80fdSGordon Ross } else {
282886184067SGordon Ross cmn_err(CE_NOTE, "!Leaked session: 0x%p", (void *)session);
282986184067SGordon Ross DTRACE_PROBE1(new__zombie, smb_session_t *, session);
28307f5d80fdSGordon Ross smb_llist_enter(&smb_server_session_zombies, RW_WRITER);
28317f5d80fdSGordon Ross smb_llist_insert_head(&smb_server_session_zombies, session);
28327f5d80fdSGordon Ross smb_llist_exit(&smb_server_session_zombies);
28337f5d80fdSGordon Ross }
28347f5d80fdSGordon Ross
2835811599a4SMatt Barden if (count == 0) {
2836811599a4SMatt Barden /* See smb_server_shutdown */
2837811599a4SMatt Barden cv_signal(&sv->sv_cv);
2838811599a4SMatt Barden }
28394163af6aSjose borrego }
2840