Print this page
NEX-14666 Need to provide SMB 2.1 Client
NEX-17187 panic in smbfs_acl_store
NEX-17231 smbfs create xattr files finds wrong file
NEX-17224 smbfs lookup EINVAL should be ENOENT
NEX-17260 SMB1 client fails to list directory after NEX-14666
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
and: (cleanup)
NEX-16824 SMB client connection setup rework
NEX-17232 SMB client reconnect failures
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
and: (improve debug)
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/fs/smbclnt/netsmb/smb_usr.c
+++ new/usr/src/uts/common/fs/smbclnt/netsmb/smb_usr.c
1 1 /*
2 2 * Copyright (c) 2000-2001 Boris Popov
3 3 * All rights reserved.
4 4 *
5 5 * Redistribution and use in source and binary forms, with or without
6 6 * modification, are permitted provided that the following conditions
7 7 * are met:
8 8 * 1. Redistributions of source code must retain the above copyright
9 9 * notice, this list of conditions and the following disclaimer.
10 10 * 2. Redistributions in binary form must reproduce the above copyright
11 11 * notice, this list of conditions and the following disclaimer in the
12 12 * documentation and/or other materials provided with the distribution.
13 13 * 3. All advertising materials mentioning features or use of this software
14 14 * must display the following acknowledgement:
15 15 * This product includes software developed by Boris Popov.
16 16 * 4. Neither the name of the author nor the names of any co-contributors
17 17 * may be used to endorse or promote products derived from this software
18 18 * without specific prior written permission.
19 19 *
20 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
26 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 30 * SUCH DAMAGE.
31 31 *
32 32 * $Id: smb_usr.c,v 1.15 2004/12/13 00:25:18 lindak Exp $
33 33 */
34 34
35 35 /*
36 - * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
37 36 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
38 37 * Use is subject to license terms.
38 + *
39 + * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
39 40 */
40 41
41 42 #include <sys/param.h>
42 43 #include <sys/kmem.h>
43 44 #include <sys/systm.h>
44 45 #include <sys/policy.h>
45 46 #include <sys/conf.h>
46 47 #include <sys/proc.h>
47 48 #include <sys/fcntl.h>
48 49 #include <sys/file.h>
49 50 #include <sys/socket.h>
50 51 #include <sys/sunddi.h>
51 52 #include <sys/cmn_err.h>
52 53
53 54 #include <netsmb/smb_osdep.h>
54 55
56 +#include <smb/winioctl.h>
55 57 #include <netsmb/smb.h>
56 58 #include <netsmb/smb_conn.h>
57 59 #include <netsmb/smb_rq.h>
58 60 #include <netsmb/smb_subr.h>
59 61 #include <netsmb/smb_dev.h>
60 62
61 63 static int smb_cpdatain(struct mbchain *mbp, int len, char *data, int seg);
62 64
63 65 /*
64 - * Ioctl function for SMBIOC_FLAGS2
65 - */
66 -int
67 -smb_usr_get_flags2(smb_dev_t *sdp, intptr_t arg, int flags)
68 -{
69 - struct smb_vc *vcp = NULL;
70 -
71 - /* This ioctl requires a session. */
72 - if ((vcp = sdp->sd_vc) == NULL)
73 - return (ENOTCONN);
74 -
75 - /*
76 - * Return the flags2 value.
77 - */
78 - if (ddi_copyout(&vcp->vc_hflags2, (void *)arg,
79 - sizeof (u_int16_t), flags))
80 - return (EFAULT);
81 -
82 - return (0);
83 -}
84 -
85 -/*
86 66 * Ioctl function for SMBIOC_GETSSNKEY
87 67 * Size copied out is SMBIOC_HASH_SZ.
88 68 *
89 69 * The RPC library needs this for encrypting things
90 70 * like "set password" requests. This is called
91 71 * with an active RPC binding, so the connection
92 72 * will already be active (but this checks).
93 73 */
94 74 int
95 75 smb_usr_get_ssnkey(smb_dev_t *sdp, intptr_t arg, int flags)
96 76 {
97 77 struct smb_vc *vcp = NULL;
|
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
98 78
99 79 /* This ioctl requires an active session. */
100 80 if ((vcp = sdp->sd_vc) == NULL)
101 81 return (ENOTCONN);
102 82 if (vcp->vc_state != SMBIOD_ST_VCACTIVE)
103 83 return (ENOTCONN);
104 84
105 85 /*
106 86 * Return the session key.
107 87 */
108 - if (ddi_copyout(vcp->vc_ssn_key, (void *)arg,
88 + if (vcp->vc_ssnkey == NULL ||
89 + vcp->vc_ssnkeylen < SMBIOC_HASH_SZ)
90 + return (EINVAL);
91 + if (ddi_copyout(vcp->vc_ssnkey, (void *)arg,
109 92 SMBIOC_HASH_SZ, flags))
110 93 return (EFAULT);
111 94
112 95 return (0);
113 96 }
114 97
115 98 /*
116 - * Ioctl function for SMBIOC_REQUEST
99 + * Ioctl function for SMBIOC_XACTNP (transact named pipe)
117 100 */
118 101 int
119 -smb_usr_simplerq(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr)
102 +smb_usr_xnp(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr)
120 103 {
121 104 struct smb_cred scred;
122 105 struct smb_share *ssp;
123 - smbioc_rq_t *ioc = NULL;
124 - struct smb_rq *rqp = NULL;
125 - struct mbchain *mbp;
126 - struct mdchain *mdp;
127 - uint32_t rsz;
106 + struct smb_fh *fhp;
107 + smbioc_xnp_t *ioc = NULL;
108 + struct mbchain send_mb;
109 + struct mdchain recv_md;
110 + uint32_t rdlen;
128 111 int err, mbseg;
129 112
130 - /* This ioctl requires a share. */
131 - if ((ssp = sdp->sd_share) == NULL)
132 - return (ENOTCONN);
113 + /* This ioctl requires a file handle. */
114 + if ((fhp = sdp->sd_fh) == NULL)
115 + return (EINVAL);
116 + ssp = FHTOSS(fhp);
133 117
134 - smb_credinit(&scred, cr);
118 + /* After reconnect, force close+reopen */
119 + if (fhp->fh_vcgenid != ssp->ss_vcgenid)
120 + return (ESTALE);
121 +
122 + bzero(&send_mb, sizeof (send_mb));
123 + bzero(&recv_md, sizeof (recv_md));
124 +
135 125 ioc = kmem_alloc(sizeof (*ioc), KM_SLEEP);
136 126 if (ddi_copyin((void *) arg, ioc, sizeof (*ioc), flags)) {
137 127 err = EFAULT;
138 128 goto out;
139 129 }
140 130
141 - /* See ddi_copyin, ddi_copyout */
142 - mbseg = (flags & FKIOCTL) ? MB_MSYSTEM : MB_MUSER;
143 -
144 131 /*
145 - * Lots of SMB commands could be safe, but
146 - * these are the only ones used by libsmbfs.
132 + * Copyin the send data, into an mbchain,
133 + * save output buffer size.
147 134 */
148 - switch (ioc->ioc_cmd) {
149 - /* These are OK */
150 - case SMB_COM_CLOSE:
151 - case SMB_COM_FLUSH:
152 - case SMB_COM_NT_CREATE_ANDX:
153 - case SMB_COM_OPEN_PRINT_FILE:
154 - case SMB_COM_CLOSE_PRINT_FILE:
155 - break;
156 -
157 - default:
158 - err = EPERM;
159 - goto out;
160 - }
161 -
162 - err = smb_rq_alloc(SSTOCP(ssp), ioc->ioc_cmd, &scred, &rqp);
135 + mbseg = (flags & FKIOCTL) ? MB_MSYSTEM : MB_MUSER;
136 + err = smb_cpdatain(&send_mb, ioc->ioc_tdlen, ioc->ioc_tdata, mbseg);
163 137 if (err)
164 138 goto out;
139 + rdlen = ioc->ioc_rdlen;
165 140
166 - mbp = &rqp->sr_rq;
167 - err = mb_put_mem(mbp, ioc->ioc_tbuf, ioc->ioc_tbufsz, mbseg);
168 -
169 - err = smb_rq_simple(rqp);
170 - if (err == 0) {
171 - /*
172 - * This may have been an open, so save the
173 - * generation ID of the share, which we
174 - * check before trying read or write.
175 - */
176 - sdp->sd_vcgenid = ssp->ss_vcgenid;
177 -
178 - /*
179 - * Have reply data. to copyout.
180 - * SMB header already parsed.
181 - */
182 - mdp = &rqp->sr_rp;
183 - rsz = msgdsize(mdp->md_top) - SMB_HDRLEN;
184 - if (ioc->ioc_rbufsz < rsz) {
185 - err = EOVERFLOW;
186 - goto out;
187 - }
188 - ioc->ioc_rbufsz = rsz;
189 - err = md_get_mem(mdp, ioc->ioc_rbuf, rsz, mbseg);
190 - if (err)
191 - goto out;
192 -
193 - }
194 -
195 - ioc->ioc_errclass = rqp->sr_errclass;
196 - ioc->ioc_serror = rqp->sr_serror;
197 - ioc->ioc_error = rqp->sr_error;
198 - (void) ddi_copyout(ioc, (void *)arg, sizeof (*ioc), flags);
199 -
200 -out:
201 - if (rqp != NULL)
202 - smb_rq_done(rqp); /* free rqp */
203 - kmem_free(ioc, sizeof (*ioc));
204 - smb_credrele(&scred);
205 -
206 - return (err);
207 -
208 -}
209 -
210 -/*
211 - * Ioctl function for SMBIOC_T2RQ
212 - */
213 -int
214 -smb_usr_t2request(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr)
215 -{
216 - struct smb_cred scred;
217 - struct smb_share *ssp;
218 - smbioc_t2rq_t *ioc = NULL;
219 - struct smb_t2rq *t2p = NULL;
220 - struct mdchain *mdp;
221 - int err, len, mbseg;
222 -
223 - /* This ioctl requires a share. */
224 - if ((ssp = sdp->sd_share) == NULL)
225 - return (ENOTCONN);
226 -
227 - smb_credinit(&scred, cr);
228 - ioc = kmem_alloc(sizeof (*ioc), KM_SLEEP);
229 - if (ddi_copyin((void *) arg, ioc, sizeof (*ioc), flags)) {
230 - err = EFAULT;
231 - goto out;
232 - }
233 -
234 - /* See ddi_copyin, ddi_copyout */
235 - mbseg = (flags & FKIOCTL) ? MB_MSYSTEM : MB_MUSER;
236 -
237 - if (ioc->ioc_setupcnt > SMBIOC_T2RQ_MAXSETUP) {
238 - err = EINVAL;
239 - goto out;
240 - }
241 -
242 141 /*
243 - * Fill in the FID for libsmbfs transact named pipe.
142 + * Run the SMB2 ioctl or SMB1 trans2
244 143 */
245 - if (ioc->ioc_setupcnt > 1 && ioc->ioc_setup[1] == 0xFFFF) {
246 - if (sdp->sd_vcgenid != ssp->ss_vcgenid) {
247 - err = ESTALE;
248 - goto out;
249 - }
250 - ioc->ioc_setup[1] = (uint16_t)sdp->sd_smbfid;
144 + smb_credinit(&scred, cr);
145 + if (SSTOVC(ssp)->vc_flags & SMBV_SMB2) {
146 + err = smb2_smb_ioctl(ssp, &fhp->fh_fid2,
147 + &send_mb, &recv_md, &rdlen,
148 + FSCTL_PIPE_TRANSCEIVE, &scred);
149 + } else {
150 + err = smb_t2_xnp(ssp, fhp->fh_fid1,
151 + &send_mb, &recv_md, &rdlen,
152 + &ioc->ioc_more, &scred);
251 153 }
154 + smb_credrele(&scred);
252 155
253 - t2p = kmem_alloc(sizeof (*t2p), KM_SLEEP);
254 - err = smb_t2_init(t2p, SSTOCP(ssp),
255 - ioc->ioc_setup, ioc->ioc_setupcnt, &scred);
256 - if (err)
257 - goto out;
258 - t2p->t2_setupcount = ioc->ioc_setupcnt;
259 - t2p->t2_setupdata = ioc->ioc_setup;
260 -
261 - /* This ioc member is a fixed-size array. */
262 - if (ioc->ioc_name[0]) {
263 - /* Get the name length - carefully! */
264 - ioc->ioc_name[SMBIOC_T2RQ_MAXNAME-1] = '\0';
265 - t2p->t_name_len = strlen(ioc->ioc_name);
266 - t2p->t_name = ioc->ioc_name;
267 - }
268 - t2p->t2_maxscount = 0;
269 - t2p->t2_maxpcount = ioc->ioc_rparamcnt;
270 - t2p->t2_maxdcount = ioc->ioc_rdatacnt;
271 -
272 - /* Transmit parameters */
273 - err = smb_cpdatain(&t2p->t2_tparam,
274 - ioc->ioc_tparamcnt, ioc->ioc_tparam, mbseg);
275 - if (err)
276 - goto out;
277 -
278 - /* Transmit data */
279 - err = smb_cpdatain(&t2p->t2_tdata,
280 - ioc->ioc_tdatacnt, ioc->ioc_tdata, mbseg);
281 - if (err)
282 - goto out;
283 -
284 - err = smb_t2_request(t2p);
285 -
286 - /* Copyout returned parameters. */
287 - mdp = &t2p->t2_rparam;
288 - if (err == 0 && mdp->md_top != NULL) {
289 - /* User's buffer large enough? */
290 - len = m_fixhdr(mdp->md_top);
291 - if (len > ioc->ioc_rparamcnt) {
292 - err = EMSGSIZE;
293 - goto out;
294 - }
295 - ioc->ioc_rparamcnt = (ushort_t)len;
296 - err = md_get_mem(mdp, ioc->ioc_rparam, len, mbseg);
297 - if (err)
298 - goto out;
299 - } else
300 - ioc->ioc_rparamcnt = 0;
301 -
302 156 /* Copyout returned data. */
303 - mdp = &t2p->t2_rdata;
304 - if (err == 0 && mdp->md_top != NULL) {
305 - /* User's buffer large enough? */
306 - len = m_fixhdr(mdp->md_top);
307 - if (len > ioc->ioc_rdatacnt) {
157 + if (err == 0 && recv_md.md_top != NULL) {
158 + /* User's buffer large enough for copyout? */
159 + size_t len = m_fixhdr(recv_md.md_top);
160 + if (len > ioc->ioc_rdlen) {
308 161 err = EMSGSIZE;
309 162 goto out;
310 163 }
311 - ioc->ioc_rdatacnt = (ushort_t)len;
312 - err = md_get_mem(mdp, ioc->ioc_rdata, len, mbseg);
164 + err = md_get_mem(&recv_md, ioc->ioc_rdata, len, mbseg);
313 165 if (err)
314 166 goto out;
315 167 } else
316 - ioc->ioc_rdatacnt = 0;
168 + ioc->ioc_rdlen = 0;
317 169
318 - ioc->ioc_errclass = t2p->t2_sr_errclass;
319 - ioc->ioc_serror = t2p->t2_sr_serror;
320 - ioc->ioc_error = t2p->t2_sr_error;
321 - ioc->ioc_rpflags2 = t2p->t2_sr_rpflags2;
170 + /* Tell caller received length */
171 + if (rdlen <= ioc->ioc_rdlen) {
172 + /* Normal case */
173 + ioc->ioc_rdlen = rdlen;
174 + } else {
175 + /* Buffer overlow. Leave ioc_rdlen */
176 + ioc->ioc_more = 1;
177 + }
322 178
323 179 (void) ddi_copyout(ioc, (void *)arg, sizeof (*ioc), flags);
324 180
325 -
326 181 out:
327 - if (t2p != NULL) {
328 - /* Note: t2p->t_name no longer allocated */
329 - smb_t2_done(t2p);
330 - kmem_free(t2p, sizeof (*t2p));
331 - }
332 182 kmem_free(ioc, sizeof (*ioc));
333 - smb_credrele(&scred);
334 183
335 184 return (err);
336 185 }
337 186
338 187 /* helper for _t2request */
339 188 static int
340 189 smb_cpdatain(struct mbchain *mbp, int len, char *data, int mbseg)
341 190 {
342 191 int error;
343 192
344 193 if (len == 0)
345 194 return (0);
346 195 error = mb_init(mbp);
347 196 if (error)
348 197 return (error);
349 198 return (mb_put_mem(mbp, data, len, mbseg));
350 199 }
|
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
351 200
352 201 /*
353 202 * Helper for nsmb_ioctl cases
354 203 * SMBIOC_READ, SMBIOC_WRITE
355 204 */
356 205 int
357 206 smb_usr_rw(smb_dev_t *sdp, int cmd, intptr_t arg, int flags, cred_t *cr)
358 207 {
359 208 struct smb_cred scred;
360 209 struct smb_share *ssp;
210 + struct smb_fh *fhp;
361 211 smbioc_rw_t *ioc = NULL;
362 212 struct iovec aiov[1];
363 213 struct uio auio;
364 - uint16_t fh;
365 214 int err;
366 215 uio_rw_t rw;
367 216
368 - /* This ioctl requires a share. */
369 - if ((ssp = sdp->sd_share) == NULL)
370 - return (ENOTCONN);
217 + /* This ioctl requires a file handle. */
218 + if ((fhp = sdp->sd_fh) == NULL)
219 + return (EINVAL);
220 + ssp = FHTOSS(fhp);
371 221
372 222 /* After reconnect, force close+reopen */
373 - if (sdp->sd_vcgenid != ssp->ss_vcgenid)
223 + if (fhp->fh_vcgenid != ssp->ss_vcgenid)
374 224 return (ESTALE);
375 225
376 - smb_credinit(&scred, cr);
377 226 ioc = kmem_alloc(sizeof (*ioc), KM_SLEEP);
378 227 if (ddi_copyin((void *) arg, ioc, sizeof (*ioc), flags)) {
379 228 err = EFAULT;
380 229 goto out;
381 230 }
382 231
383 232 switch (cmd) {
384 233 case SMBIOC_READ:
385 234 rw = UIO_READ;
386 235 break;
387 236 case SMBIOC_WRITE:
388 237 rw = UIO_WRITE;
389 238 break;
390 239 default:
391 240 err = ENODEV;
392 241 goto out;
393 242 }
394 243
395 - /*
396 - * If caller passes -1 in ioc_fh, then
397 - * use the FID from SMBIOC_NTCREATE.
398 - */
399 - if (ioc->ioc_fh == -1)
400 - fh = (uint16_t)sdp->sd_smbfid;
401 - else
402 - fh = (uint16_t)ioc->ioc_fh;
403 -
404 244 aiov[0].iov_base = ioc->ioc_base;
405 245 aiov[0].iov_len = (size_t)ioc->ioc_cnt;
406 246
407 247 auio.uio_iov = aiov;
408 248 auio.uio_iovcnt = 1;
409 249 auio.uio_loffset = ioc->ioc_offset;
410 250 auio.uio_segflg = (flags & FKIOCTL) ?
411 251 UIO_SYSSPACE : UIO_USERSPACE;
412 252 auio.uio_fmode = 0;
413 253 auio.uio_resid = (size_t)ioc->ioc_cnt;
414 254
415 - err = smb_rwuio(ssp, fh, rw, &auio, &scred, 0);
255 + smb_credinit(&scred, cr);
256 + err = smb_rwuio(fhp, rw, &auio, &scred, 0);
257 + smb_credrele(&scred);
416 258
417 259 /*
418 260 * On return ioc_cnt holds the
419 261 * number of bytes transferred.
420 262 */
421 263 ioc->ioc_cnt -= auio.uio_resid;
422 264
423 265 (void) ddi_copyout(ioc, (void *)arg, sizeof (*ioc), flags);
424 266
425 267 out:
426 268 kmem_free(ioc, sizeof (*ioc));
427 - smb_credrele(&scred);
428 269
429 270 return (err);
430 271 }
431 272
432 273 /*
433 274 * Helper for nsmb_ioctl case
434 275 * SMBIOC_NTCREATE
435 276 */
436 277 int
437 278 smb_usr_ntcreate(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr)
438 279 {
439 280 struct smb_cred scred;
440 281 struct mbchain name_mb;
441 282 struct smb_share *ssp;
283 + struct smb_fh *fhp = NULL;
442 284 smbioc_ntcreate_t *ioc = NULL;
443 - uint16_t fid;
444 285 int err, nmlen;
445 286
287 + mb_init(&name_mb);
288 +
446 289 /* This ioctl requires a share. */
447 290 if ((ssp = sdp->sd_share) == NULL)
448 291 return (ENOTCONN);
449 292
450 - /* Must not be already open. */
451 - if (sdp->sd_smbfid != -1)
293 + /* Must not already have a file handle. */
294 + if (sdp->sd_fh != NULL)
452 295 return (EINVAL);
453 296
454 - mb_init(&name_mb);
455 - smb_credinit(&scred, cr);
456 297 ioc = kmem_alloc(sizeof (*ioc), KM_SLEEP);
457 298 if (ddi_copyin((void *) arg, ioc, sizeof (*ioc), flags)) {
458 299 err = EFAULT;
459 300 goto out;
460 301 }
461 302
462 303 /* Build name_mb */
463 304 ioc->ioc_name[SMBIOC_MAX_NAME-1] = '\0';
464 305 nmlen = strnlen(ioc->ioc_name, SMBIOC_MAX_NAME-1);
465 306 err = smb_put_dmem(&name_mb, SSTOVC(ssp),
466 307 ioc->ioc_name, nmlen,
467 308 SMB_CS_NONE, NULL);
468 309 if (err != 0)
469 310 goto out;
470 311
471 - /* Do the OtW open, save the FID. */
312 + err = smb_fh_create(ssp, &fhp);
313 + if (err != 0)
314 + goto out;
315 +
316 + /*
317 + * Do the OtW open, save the FID.
318 + */
319 + smb_credinit(&scred, cr);
472 320 err = smb_smb_ntcreate(ssp, &name_mb,
473 321 0, /* create flags */
474 322 ioc->ioc_req_acc,
475 323 ioc->ioc_efattr,
476 324 ioc->ioc_share_acc,
477 325 ioc->ioc_open_disp,
478 326 ioc->ioc_creat_opts,
479 327 NTCREATEX_IMPERSONATION_IMPERSONATION,
480 328 &scred,
481 - &fid,
329 + fhp,
482 330 NULL,
483 331 NULL);
332 + smb_credrele(&scred);
484 333 if (err != 0)
485 334 goto out;
486 335
487 - sdp->sd_smbfid = fid;
488 - sdp->sd_vcgenid = ssp->ss_vcgenid;
336 + fhp->fh_rights = ioc->ioc_req_acc;
337 + smb_fh_opened(fhp);
338 + sdp->sd_fh = fhp;
339 + fhp = NULL;
489 340
490 341 out:
342 + if (fhp != NULL)
343 + smb_fh_rele(fhp);
491 344 kmem_free(ioc, sizeof (*ioc));
492 - smb_credrele(&scred);
493 345 mb_done(&name_mb);
494 346
495 347 return (err);
496 348 }
497 349
498 350 /*
499 351 * Helper for nsmb_ioctl case
500 352 * SMBIOC_PRINTJOB
501 353 */
502 354 int
503 355 smb_usr_printjob(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr)
504 356 {
357 + static const char invalid_chars[] = SMB_FILENAME_INVALID_CHARS;
505 358 struct smb_cred scred;
359 + struct mbchain name_mb;
506 360 struct smb_share *ssp;
361 + struct smb_fh *fhp = NULL;
507 362 smbioc_printjob_t *ioc = NULL;
508 - uint16_t fid;
509 - int err;
363 + int err, cklen, nmlen;
364 + uint32_t access = SA_RIGHT_FILE_WRITE_DATA |
365 + SA_RIGHT_FILE_READ_ATTRIBUTES;
510 366
367 + mb_init(&name_mb);
368 +
511 369 /* This ioctl requires a share. */
512 370 if ((ssp = sdp->sd_share) == NULL)
513 371 return (ENOTCONN);
514 372
515 373 /* The share must be a print queue. */
516 374 if (ssp->ss_type != STYPE_PRINTQ)
517 375 return (EINVAL);
518 376
519 - /* Must not be already open. */
520 - if (sdp->sd_smbfid != -1)
377 + /* Must not already have a file handle. */
378 + if (sdp->sd_fh != NULL)
521 379 return (EINVAL);
522 380
523 381 smb_credinit(&scred, cr);
524 382 ioc = kmem_alloc(sizeof (*ioc), KM_SLEEP);
525 383 if (ddi_copyin((void *) arg, ioc, sizeof (*ioc), flags)) {
526 384 err = EFAULT;
527 385 goto out;
528 386 }
387 +
388 + /*
389 + * Use the print job title as the file name to open, but
390 + * check for invalid characters first. See the notes in
391 + * libsmbfs/smb/print.c about job name sanitizing.
392 + */
529 393 ioc->ioc_title[SMBIOC_MAX_NAME-1] = '\0';
394 + nmlen = strnlen(ioc->ioc_title, SMBIOC_MAX_NAME-1);
395 + cklen = strcspn(ioc->ioc_title, invalid_chars);
396 + if (cklen < nmlen) {
397 + err = EINVAL;
398 + goto out;
399 + }
530 400
531 - /* Do the OtW open, save the FID. */
532 - err = smb_smb_open_prjob(ssp, ioc->ioc_title,
533 - ioc->ioc_setuplen, ioc->ioc_prmode,
534 - &scred, &fid);
401 + /* Build name_mb */
402 + err = smb_put_dmem(&name_mb, SSTOVC(ssp),
403 + ioc->ioc_title, nmlen,
404 + SMB_CS_NONE, NULL);
535 405 if (err != 0)
536 406 goto out;
537 407
538 - sdp->sd_smbfid = fid;
539 - sdp->sd_vcgenid = ssp->ss_vcgenid;
408 + err = smb_fh_create(ssp, &fhp);
409 + if (err != 0)
410 + goto out;
540 411
412 + /*
413 + * Do the OtW open, save the FID.
414 + */
415 + smb_credinit(&scred, cr);
416 + if (SSTOVC(ssp)->vc_flags & SMBV_SMB2) {
417 + err = smb2_smb_ntcreate(ssp, &name_mb,
418 + NULL, NULL, /* cctx in, out */
419 + 0, /* create flags */
420 + access,
421 + SMB_EFA_NORMAL,
422 + NTCREATEX_SHARE_ACCESS_NONE,
423 + NTCREATEX_DISP_CREATE,
424 + NTCREATEX_OPTIONS_NON_DIRECTORY_FILE,
425 + NTCREATEX_IMPERSONATION_IMPERSONATION,
426 + &scred,
427 + &fhp->fh_fid2,
428 + NULL,
429 + NULL);
430 + } else {
431 + err = smb_smb_open_prjob(ssp, ioc->ioc_title,
432 + ioc->ioc_setuplen, ioc->ioc_prmode,
433 + &scred, &fhp->fh_fid1);
434 + }
435 + smb_credrele(&scred);
436 + if (err != 0)
437 + goto out;
438 +
439 + fhp->fh_rights = access;
440 + smb_fh_opened(fhp);
441 + sdp->sd_fh = fhp;
442 + fhp = NULL;
443 +
541 444 out:
445 + if (fhp != NULL)
446 + smb_fh_rele(fhp);
542 447 kmem_free(ioc, sizeof (*ioc));
543 - smb_credrele(&scred);
448 + mb_done(&name_mb);
544 449
545 450 return (err);
546 451 }
547 452
548 453 /*
549 454 * Helper for nsmb_ioctl case
550 455 * SMBIOC_CLOSEFH
551 456 */
457 +/*ARGSUSED*/
552 458 int
553 459 smb_usr_closefh(smb_dev_t *sdp, cred_t *cr)
554 460 {
555 - struct smb_cred scred;
556 - struct smb_share *ssp;
557 - uint16_t fid;
558 - int err;
461 + struct smb_fh *fhp;
559 462
560 - /* This ioctl requires a share. */
561 - if ((ssp = sdp->sd_share) == NULL)
562 - return (ENOTCONN);
463 + /* This ioctl requires a file handle. */
464 + if ((fhp = sdp->sd_fh) == NULL)
465 + return (EINVAL);
466 + sdp->sd_fh = NULL;
563 467
564 - if (sdp->sd_smbfid == -1)
565 - return (0);
566 - fid = (uint16_t)sdp->sd_smbfid;
567 - sdp->sd_smbfid = -1;
468 + smb_fh_close(fhp);
469 + smb_fh_rele(fhp);
568 470
569 - smb_credinit(&scred, cr);
570 - if (ssp->ss_type == STYPE_PRINTQ)
571 - err = smb_smb_close_prjob(ssp, fid, &scred);
572 - else
573 - err = smb_smb_close(ssp, fid, NULL, &scred);
574 - smb_credrele(&scred);
575 -
576 - return (err);
471 + return (0);
577 472 }
578 473
579 474 /*
580 475 * Ioctl functions: SMBIOC_SSN_FIND, SMBIOC_SSN_CREATE
581 476 * Find or create a session (a.k.a. "VC" in here)
582 477 */
583 478 int
584 479 smb_usr_get_ssn(smb_dev_t *sdp, int cmd, intptr_t arg, int flags, cred_t *cr)
585 480 {
586 481 struct smb_cred scred;
587 482 smbioc_ossn_t *ossn = NULL;
588 483 struct smb_vc *vcp = NULL;
589 484 int error = 0;
590 485 uid_t realuid;
591 486
592 487 /* Should be no VC */
593 488 if (sdp->sd_vc != NULL)
594 489 return (EISCONN);
595 490
596 491 smb_credinit(&scred, cr);
597 492 ossn = kmem_alloc(sizeof (*ossn), KM_SLEEP);
598 493 if (ddi_copyin((void *)arg, ossn, sizeof (*ossn), flags)) {
599 494 error = EFAULT;
600 495 goto out;
601 496 }
602 497
603 498 /*
604 499 * Only superuser can specify a UID or GID.
605 500 */
606 501 realuid = crgetruid(cr);
607 502 if (ossn->ssn_owner == SMBM_ANY_OWNER)
608 503 ossn->ssn_owner = realuid;
609 504 else {
610 505 /*
611 506 * Do we have the privilege to create with the
612 507 * specified uid? (does uid == cr->cr_uid, etc.)
613 508 */
614 509 if (secpolicy_vnode_owner(cr, ossn->ssn_owner)) {
615 510 error = EPERM;
616 511 goto out;
617 512 }
618 513 /* ossn->ssn_owner is OK */
619 514 }
620 515
621 516 /*
622 517 * Make sure the strings are null terminated.
623 518 */
624 519 ossn->ssn_srvname[SMBIOC_MAX_NAME-1] = '\0';
625 520 ossn->ssn_id.id_domain[ SMBIOC_MAX_NAME-1] = '\0';
626 521 ossn->ssn_id.id_user[ SMBIOC_MAX_NAME-1] = '\0';
627 522
628 523 if (cmd == SMBIOC_SSN_CREATE)
629 524 ossn->ssn_vopt |= SMBVOPT_CREATE;
630 525 else /* FIND */
631 526 ossn->ssn_vopt &= ~SMBVOPT_CREATE;
632 527
633 528 error = smb_vc_findcreate(ossn, &scred, &vcp);
634 529 if (error)
635 530 goto out;
636 531 ASSERT(vcp != NULL);
637 532
638 533 /*
639 534 * We have a VC, held, but not locked.
640 535 * If we're creating, mark this instance as
641 536 * an open from IOD so close can do cleanup.
642 537 *
643 538 * XXX: Would be nice to have a back pointer
644 539 * from the VC to this (IOD) sdp instance.
645 540 */
646 541 if (cmd == SMBIOC_SSN_CREATE) {
647 542 if (vcp->iod_thr != NULL) {
648 543 error = EEXIST;
649 544 goto out;
650 545 }
651 546 sdp->sd_flags |= NSMBFL_IOD;
652 547 } else {
653 548 /*
654 549 * Wait for it to finish connecting
655 550 * (or reconnect) if necessary.
656 551 */
657 552 if (vcp->vc_state != SMBIOD_ST_VCACTIVE) {
658 553 error = smb_iod_reconnect(vcp);
659 554 if (error != 0)
660 555 goto out;
661 556 }
662 557 }
663 558
664 559 /*
665 560 * The VC has a hold from _findvc
666 561 * which we keep until _SSN_RELE
667 562 * or nsmb_close().
668 563 */
669 564 sdp->sd_level = SMBL_VC;
670 565 sdp->sd_vc = vcp;
671 566 vcp = NULL;
672 567 (void) ddi_copyout(ossn, (void *)arg, sizeof (*ossn), flags);
673 568
674 569 out:
675 570 if (vcp) {
676 571 /* Error path: rele hold from _findcreate */
677 572 smb_vc_rele(vcp);
678 573 }
679 574 kmem_free(ossn, sizeof (*ossn));
680 575 smb_credrele(&scred);
681 576
682 577 return (error);
683 578 }
684 579
685 580 /*
686 581 * Ioctl functions: SMBIOC_SSN_RELE, SMBIOC_SSN_KILL
687 582 * Release or kill the current session.
688 583 */
689 584 int
690 585 smb_usr_drop_ssn(smb_dev_t *sdp, int cmd)
691 586 {
692 587 struct smb_vc *vcp = NULL;
693 588
694 589 /* Must have a VC. */
695 590 if ((vcp = sdp->sd_vc) == NULL)
696 591 return (ENOTCONN);
697 592
698 593 /* If we have a share ref, drop it too. */
699 594 if (sdp->sd_share) {
700 595 smb_share_rele(sdp->sd_share);
701 596 sdp->sd_share = NULL;
702 597 sdp->sd_level = SMBL_VC;
703 598 }
704 599
705 600 if (cmd == SMBIOC_SSN_KILL)
706 601 smb_vc_kill(vcp);
707 602
708 603 /* Drop the VC ref. */
709 604 smb_vc_rele(vcp);
710 605 sdp->sd_vc = NULL;
711 606 sdp->sd_level = 0;
712 607
713 608 return (0);
714 609 }
715 610
716 611 /*
717 612 * Find or create a tree (connected share)
718 613 */
719 614 int
720 615 smb_usr_get_tree(smb_dev_t *sdp, int cmd, intptr_t arg, int flags, cred_t *cr)
721 616 {
722 617 struct smb_cred scred;
723 618 smbioc_tcon_t *tcon = NULL;
724 619 struct smb_vc *vcp = NULL;
725 620 struct smb_share *ssp = NULL;
726 621 int error = 0;
727 622
728 623 /* Must have a VC. */
729 624 if ((vcp = sdp->sd_vc) == NULL)
730 625 return (ENOTCONN);
731 626 /* Should not have a share. */
732 627 if (sdp->sd_share != NULL)
733 628 return (EISCONN);
734 629
735 630 smb_credinit(&scred, cr);
736 631 tcon = kmem_alloc(sizeof (*tcon), KM_SLEEP);
737 632 if (ddi_copyin((void *)arg, tcon, sizeof (*tcon), flags)) {
738 633 error = EFAULT;
739 634 goto out;
740 635 }
741 636
742 637 /*
743 638 * Make sure the strings are null terminated.
744 639 */
745 640 tcon->tc_sh.sh_name[SMBIOC_MAX_NAME-1] = '\0';
746 641 tcon->tc_sh.sh_pass[SMBIOC_MAX_NAME-1] = '\0';
747 642
748 643 if (cmd == SMBIOC_TREE_CONNECT)
749 644 tcon->tc_opt |= SMBSOPT_CREATE;
750 645 else /* FIND */
751 646 tcon->tc_opt &= ~SMBSOPT_CREATE;
752 647
753 648 error = smb_share_findcreate(tcon, vcp, &ssp, &scred);
754 649 if (error)
755 650 goto out;
756 651 ASSERT(ssp != NULL);
757 652
758 653 /*
759 654 * We have a share, held, but not locked.
760 655 * If we're creating, do tree connect now,
761 656 * otherwise let that wait for a request.
762 657 */
763 658 if (cmd == SMBIOC_TREE_CONNECT) {
764 659 error = smb_share_tcon(ssp, &scred);
765 660 if (error)
766 661 goto out;
767 662 }
768 663
769 664 /*
770 665 * Give caller the real share type from
771 666 * the tree connect response, so they can
772 667 * see if they got the requested type.
773 668 */
774 669 tcon->tc_sh.sh_type = ssp->ss_type;
775 670
776 671 /*
777 672 * The share has a hold from _tcon
778 673 * which we keep until nsmb_close()
779 674 * or the SMBIOC_TDIS below.
780 675 */
781 676 sdp->sd_level = SMBL_SHARE;
782 677 sdp->sd_share = ssp;
783 678 ssp = NULL;
784 679 (void) ddi_copyout(tcon, (void *)arg, sizeof (*tcon), flags);
785 680
786 681 out:
787 682 if (ssp) {
788 683 /* Error path: rele hold from _findcreate */
789 684 smb_share_rele(ssp);
790 685 }
791 686 /*
792 687 * This structure may contain a
793 688 * cleartext password, so zap it.
794 689 */
795 690 bzero(tcon, sizeof (*tcon));
796 691 kmem_free(tcon, sizeof (*tcon));
797 692 smb_credrele(&scred);
798 693
799 694 return (error);
800 695 }
801 696
802 697 /*
803 698 * Ioctl functions: SMBIOC_TREE_RELE, SMBIOC_TREE_KILL
804 699 * Release or kill the current tree
805 700 */
806 701 int
807 702 smb_usr_drop_tree(smb_dev_t *sdp, int cmd)
808 703 {
809 704 struct smb_share *ssp = NULL;
810 705
811 706 /* Must have a VC and a share. */
812 707 if (sdp->sd_vc == NULL)
813 708 return (ENOTCONN);
814 709 if ((ssp = sdp->sd_share) == NULL)
815 710 return (ENOTCONN);
816 711
817 712 if (cmd == SMBIOC_TREE_KILL)
|
↓ open down ↓ |
231 lines elided |
↑ open up ↑ |
818 713 smb_share_kill(ssp);
819 714
820 715 /* Drop the share ref. */
821 716 smb_share_rele(sdp->sd_share);
822 717 sdp->sd_share = NULL;
823 718 sdp->sd_level = SMBL_VC;
824 719
825 720 return (0);
826 721 }
827 722
828 -
829 723 /*
830 - * Ioctl function: SMBIOC_IOD_WORK
831 - *
832 - * Become the reader (IOD) thread, until either the connection is
833 - * reset by the server, or until the connection is idle longer than
834 - * some max time. (max idle time not yet implemented)
724 + * Ioctl handler for all SMBIOC_IOD_...
835 725 */
836 726 int
837 -smb_usr_iod_work(smb_dev_t *sdp, intptr_t arg, int flags, cred_t *cr)
727 +smb_usr_iod_ioctl(smb_dev_t *sdp, int cmd, intptr_t arg, int flags, cred_t *cr)
838 728 {
839 - struct smb_vc *vcp = NULL;
729 + struct smb_vc *vcp;
840 730 int err = 0;
841 731
842 - /* Must have a valid session. */
732 + /* Must be the IOD. */
733 + if ((sdp->sd_flags & NSMBFL_IOD) == 0)
734 + return (EINVAL);
735 + /* Must have a VC and no share. */
843 736 if ((vcp = sdp->sd_vc) == NULL)
844 737 return (EINVAL);
845 - if (vcp->vc_flags & SMBV_GONE)
738 + if (sdp->sd_share != NULL)
846 739 return (EINVAL);
847 740
848 741 /*
849 742 * Is there already an IOD for this VC?
850 743 * (Should never happen.)
851 744 */
852 745 SMB_VC_LOCK(vcp);
853 746 if (vcp->iod_thr == NULL)
854 747 vcp->iod_thr = curthread;
855 748 else
856 749 err = EEXIST;
857 750 SMB_VC_UNLOCK(vcp);
858 751 if (err)
859 752 return (err);
860 753
861 754 /*
862 - * Copy the "work" state, etc. into the VC
863 - * The MAC key is copied separately.
755 + * Copy the "work" state, etc. into the VC,
756 + * and back to the caller on the way out.
757 + * Clear the "out only" part.
864 758 */
865 759 if (ddi_copyin((void *)arg, &vcp->vc_work,
866 760 sizeof (smbioc_ssn_work_t), flags)) {
867 761 err = EFAULT;
868 762 goto out;
869 763 }
870 - if (vcp->vc_u_maclen) {
871 - vcp->vc_mackeylen = vcp->vc_u_maclen;
872 - vcp->vc_mackey = kmem_alloc(vcp->vc_mackeylen, KM_SLEEP);
873 - if (ddi_copyin(vcp->vc_u_mackey.lp_ptr, vcp->vc_mackey,
874 - vcp->vc_mackeylen, flags)) {
875 - err = EFAULT;
876 - goto out;
877 - }
878 - }
764 + vcp->vc_work.wk_out_state = 0;
879 765
880 - err = smb_iod_vc_work(vcp, cr);
766 + switch (cmd) {
881 767
882 - /* Caller wants state here. */
883 - vcp->vc_work.wk_out_state = vcp->vc_state;
768 + case SMBIOC_IOD_CONNECT:
769 + err = nsmb_iod_connect(vcp, cr);
770 + break;
884 771
885 - (void) ddi_copyout(&vcp->vc_work, (void *)arg,
886 - sizeof (smbioc_ssn_work_t), flags);
772 + case SMBIOC_IOD_NEGOTIATE:
773 + err = nsmb_iod_negotiate(vcp, cr);
774 + break;
887 775
888 -out:
889 - if (vcp->vc_mackey) {
890 - kmem_free(vcp->vc_mackey, vcp->vc_mackeylen);
891 - vcp->vc_mackey = NULL;
892 - vcp->vc_mackeylen = 0;
776 + case SMBIOC_IOD_SSNSETUP:
777 + err = nsmb_iod_ssnsetup(vcp, cr);
778 + break;
779 +
780 + case SMBIOC_IOD_WORK:
781 + err = smb_iod_vc_work(vcp, flags, cr);
782 + break;
783 +
784 + case SMBIOC_IOD_IDLE:
785 + err = smb_iod_vc_idle(vcp);
786 + break;
787 +
788 + case SMBIOC_IOD_RCFAIL:
789 + err = smb_iod_vc_rcfail(vcp);
790 + break;
791 +
792 + default:
793 + err = ENOTTY;
794 + break;
893 795 }
894 796
797 +out:
798 + vcp->vc_work.wk_out_state = vcp->vc_state;
799 + (void) ddi_copyout(&vcp->vc_work, (void *)arg,
800 + sizeof (smbioc_ssn_work_t), flags);
801 +
895 802 /*
896 803 * The IOD thread is leaving the driver. Clear iod_thr,
897 804 * and wake up anybody waiting for us to quit.
898 805 */
899 806 SMB_VC_LOCK(vcp);
900 807 vcp->iod_thr = NULL;
901 808 cv_broadcast(&vcp->vc_statechg);
902 809 SMB_VC_UNLOCK(vcp);
903 810
904 811 return (err);
905 812 }
906 813
907 -/*
908 - * Ioctl functions: SMBIOC_IOD_IDLE, SMBIOC_IOD_RCFAIL
909 - *
910 - * Wait for user-level requests to be enqueued on this session,
911 - * and then return to the user-space helper, which will then
912 - * initiate a reconnect, etc.
913 - */
914 814 int
915 -smb_usr_iod_ioctl(smb_dev_t *sdp, int cmd, intptr_t arg, int flags)
815 +smb_usr_ioctl(smb_dev_t *sdp, int cmd, intptr_t arg, int flags, cred_t *cr)
916 816 {
917 - struct smb_vc *vcp = NULL;
918 - int err = 0;
817 + int err;
919 818
920 - /* Must have a valid session. */
921 - if ((vcp = sdp->sd_vc) == NULL)
922 - return (EINVAL);
923 - if (vcp->vc_flags & SMBV_GONE)
924 - return (EINVAL);
925 -
926 819 /*
927 - * Is there already an IOD for this VC?
928 - * (Should never happen.)
820 + * Serialize ioctl calls. The smb_usr_... functions
821 + * don't expect concurrent calls on a given sdp.
929 822 */
930 - SMB_VC_LOCK(vcp);
931 - if (vcp->iod_thr == NULL)
932 - vcp->iod_thr = curthread;
933 - else
934 - err = EEXIST;
935 - SMB_VC_UNLOCK(vcp);
936 - if (err)
937 - return (err);
823 + mutex_enter(&sdp->sd_lock);
824 + if ((sdp->sd_flags & NSMBFL_IOCTL) != 0) {
825 + mutex_exit(&sdp->sd_lock);
826 + return (EBUSY);
827 + }
828 + sdp->sd_flags |= NSMBFL_IOCTL;
829 + mutex_exit(&sdp->sd_lock);
938 830
939 - /* nothing to copyin */
940 -
831 + err = 0;
941 832 switch (cmd) {
942 - case SMBIOC_IOD_IDLE:
943 - err = smb_iod_vc_idle(vcp);
833 + case SMBIOC_GETVERS:
834 + (void) ddi_copyout(&nsmb_version, (void *)arg,
835 + sizeof (nsmb_version), flags);
944 836 break;
945 837
838 + case SMBIOC_GETSSNKEY:
839 + err = smb_usr_get_ssnkey(sdp, arg, flags);
840 + break;
841 +
842 + case SMBIOC_DUP_DEV:
843 + err = smb_usr_dup_dev(sdp, arg, flags);
844 + break;
845 +
846 + case SMBIOC_XACTNP:
847 + err = smb_usr_xnp(sdp, arg, flags, cr);
848 + break;
849 +
850 + case SMBIOC_READ:
851 + case SMBIOC_WRITE:
852 + err = smb_usr_rw(sdp, cmd, arg, flags, cr);
853 + break;
854 +
855 + case SMBIOC_NTCREATE:
856 + err = smb_usr_ntcreate(sdp, arg, flags, cr);
857 + break;
858 +
859 + case SMBIOC_PRINTJOB:
860 + err = smb_usr_printjob(sdp, arg, flags, cr);
861 + break;
862 +
863 + case SMBIOC_CLOSEFH:
864 + err = smb_usr_closefh(sdp, cr);
865 + break;
866 +
867 + case SMBIOC_SSN_CREATE:
868 + case SMBIOC_SSN_FIND:
869 + err = smb_usr_get_ssn(sdp, cmd, arg, flags, cr);
870 + break;
871 +
872 + case SMBIOC_SSN_KILL:
873 + case SMBIOC_SSN_RELE:
874 + err = smb_usr_drop_ssn(sdp, cmd);
875 + break;
876 +
877 + case SMBIOC_TREE_CONNECT:
878 + case SMBIOC_TREE_FIND:
879 + err = smb_usr_get_tree(sdp, cmd, arg, flags, cr);
880 + break;
881 +
882 + case SMBIOC_TREE_KILL:
883 + case SMBIOC_TREE_RELE:
884 + err = smb_usr_drop_tree(sdp, cmd);
885 + break;
886 +
887 + case SMBIOC_IOD_CONNECT:
888 + case SMBIOC_IOD_NEGOTIATE:
889 + case SMBIOC_IOD_SSNSETUP:
890 + case SMBIOC_IOD_WORK:
891 + case SMBIOC_IOD_IDLE:
946 892 case SMBIOC_IOD_RCFAIL:
947 - err = smb_iod_vc_rcfail(vcp);
893 + err = smb_usr_iod_ioctl(sdp, cmd, arg, flags, cr);
948 894 break;
949 895
896 + case SMBIOC_PK_ADD:
897 + case SMBIOC_PK_DEL:
898 + case SMBIOC_PK_CHK:
899 + case SMBIOC_PK_DEL_OWNER:
900 + case SMBIOC_PK_DEL_EVERYONE:
901 + err = smb_pkey_ioctl(cmd, arg, flags, cr);
902 + break;
903 +
950 904 default:
951 905 err = ENOTTY;
952 - goto out;
906 + break;
953 907 }
954 908
955 - /* Both of these ioctls copy out the new state. */
956 - (void) ddi_copyout(&vcp->vc_state, (void *)arg,
957 - sizeof (int), flags);
909 + mutex_enter(&sdp->sd_lock);
910 + sdp->sd_flags &= ~NSMBFL_IOCTL;
911 + mutex_exit(&sdp->sd_lock);
958 912
959 -out:
960 - /*
961 - * The IOD thread is leaving the driver. Clear iod_thr,
962 - * and wake up anybody waiting for us to quit.
963 - */
964 - SMB_VC_LOCK(vcp);
965 - vcp->iod_thr = NULL;
966 - cv_broadcast(&vcp->vc_statechg);
967 - SMB_VC_UNLOCK(vcp);
968 -
969 913 return (err);
970 914 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX