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