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-1643 dtrace provider for smbsrv
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-5844 want SMB2 ioctl FSCTL_SRV_COPYCHUNK
NEX-6124 smb_fsop_read/write should allow file != sr->fid_ofile
NEX-6125 smbtorture invalid response with smb2.ioctl
Reviewed by: Evan Layton <evan.layton@nexenta.com>
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-2188 Browsing top level share produces RPC error 1728
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-48 Panic with smbtorture raw.scan-eamax (fix dtrace probes)
SMB-39 Use AF_UNIX pipes for RPC
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-48 Panic with smbtorture raw.scan-eamax
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
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/fs/smbsrv/smb_common_transact.c
+++ new/usr/src/uts/common/fs/smbsrv/smb_common_transact.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 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
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 /*
23 23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 - * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
24 + * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
25 25 */
26 26
27 27 #include <smbsrv/smb_kproto.h>
28 28 #include <smbsrv/smb_fsops.h>
29 29 #include <smbsrv/smb_share.h>
30 30 #include <smbsrv/string.h>
31 31 #include <smbsrv/nmpipes.h>
32 32 #include <smbsrv/mailslot.h>
33 -#include <smbsrv/winioctl.h>
33 +#include <smb/winioctl.h>
34 34
35 35 /*
36 36 * count of bytes in server response packet
37 37 * except parameters and data. Note that setup
38 38 * word count is zero.
39 39 */
40 40 #define RESP_HEADER_LEN 24
41 41
42 42 /*
43 43 * We started by using common functions for transaction/transaction2
44 44 * and transaction_secondary/transaction2_secondary because they
45 45 * are respectively so similar. However, it turned out to be a bad
46 46 * idea because of quirky differences. Be sure if you modify one
47 47 * of these four functions to check and see if the modification should
|
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
48 48 * be applied to its peer.
49 49 */
50 50
51 51 static int smb_trans_ready(smb_xa_t *);
52 52 static smb_sdrc_t smb_trans_dispatch(smb_request_t *, smb_xa_t *);
53 53 static smb_sdrc_t smb_trans2_dispatch(smb_request_t *, smb_xa_t *);
54 54
55 55 smb_sdrc_t
56 56 smb_pre_transaction(smb_request_t *sr)
57 57 {
58 - DTRACE_SMB_1(op__Transaction__start, smb_request_t *, sr);
58 + DTRACE_SMB_START(op__Transaction, smb_request_t *, sr);
59 59 return (SDRC_SUCCESS);
60 60 }
61 61
62 62 void
63 63 smb_post_transaction(smb_request_t *sr)
64 64 {
65 - DTRACE_SMB_1(op__Transaction__done, smb_request_t *, sr);
65 + DTRACE_SMB_DONE(op__Transaction, smb_request_t *, sr);
66 66 }
67 67
68 68 smb_sdrc_t
69 69 smb_com_transaction(smb_request_t *sr)
70 70 {
71 71 int rc;
72 72 unsigned char msrcnt, suwcnt;
73 73 uint16_t tpscnt, tdscnt, mprcnt, mdrcnt, flags;
74 74 uint16_t pscnt, psoff, dscnt, dsoff;
75 75 uint32_t timeo;
76 76 struct smb_xa *xa;
77 77 char *stn;
78 78 int ready;
79 79
80 80 if (!STYPE_ISIPC(sr->tid_tree->t_res_type)) {
81 81 smbsr_error(sr, 0, ERRDOS, ERRnoaccess);
82 82 return (SDRC_ERROR);
83 83 }
84 84
85 85 rc = smbsr_decode_vwv(sr, SMB_TRANSHDR_ED_FMT,
86 86 &tpscnt, &tdscnt, &mprcnt, &mdrcnt, &msrcnt, &flags,
87 87 &timeo, &pscnt, &psoff, &dscnt, &dsoff, &suwcnt);
88 88
89 89 if (rc != 0)
90 90 return (SDRC_ERROR);
91 91
92 92 xa = smb_xa_create(sr->session, sr, tpscnt, tdscnt, mprcnt, mdrcnt,
93 93 msrcnt, suwcnt);
94 94 if (xa == NULL) {
95 95 smbsr_error(sr, 0, ERRSRV, ERRnoroom);
96 96 return (SDRC_ERROR);
97 97 }
98 98
99 99 /* Should be some alignment stuff here in SMB? */
100 100 if (sr->smb_flg2 & SMB_FLAGS2_UNICODE) {
101 101 rc = smbsr_decode_data(sr, "%.U", sr, &stn);
102 102 } else {
103 103 rc = smbsr_decode_data(sr, "%s", sr, &stn);
104 104 }
105 105 if (rc != 0) {
106 106 smb_xa_rele(sr->session, xa);
107 107 return (SDRC_ERROR);
108 108 }
109 109
110 110 xa->xa_pipe_name = smb_mem_strdup(stn);
111 111 xa->smb_flags = flags;
112 112 xa->smb_timeout = timeo;
113 113 xa->req_disp_param = pscnt;
114 114 xa->req_disp_data = dscnt;
115 115
116 116 if (smb_mbc_copy(&xa->req_setup_mb, &sr->smb_vwv,
117 117 sr->smb_vwv.chain_offset, suwcnt * 2)) {
118 118 smb_xa_rele(sr->session, xa);
119 119 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
120 120 return (SDRC_ERROR);
121 121 }
122 122 if (smb_mbc_copy(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
123 123 smb_xa_rele(sr->session, xa);
124 124 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
125 125 return (SDRC_ERROR);
126 126 }
127 127 if (smb_mbc_copy(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
128 128 smb_xa_rele(sr->session, xa);
129 129 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
130 130 return (SDRC_ERROR);
131 131 }
132 132
133 133 ready = smb_trans_ready(xa);
134 134
135 135 if (smb_xa_open(xa)) {
136 136 smb_xa_rele(sr->session, xa);
137 137 smbsr_error(sr, 0, ERRSRV, ERRsrverror);
138 138 return (SDRC_ERROR);
139 139 }
140 140 sr->r_xa = xa;
141 141
142 142 if (!ready) {
143 143 rc = smbsr_encode_empty_result(sr);
144 144 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
145 145 }
146 146
147 147 if (!smb_xa_complete(xa)) {
148 148 smb_xa_close(xa);
|
↓ open down ↓ |
73 lines elided |
↑ open up ↑ |
149 149 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
150 150 return (SDRC_ERROR);
151 151 }
152 152
153 153 return (smb_trans_dispatch(sr, xa));
154 154 }
155 155
156 156 smb_sdrc_t
157 157 smb_pre_transaction_secondary(smb_request_t *sr)
158 158 {
159 - DTRACE_SMB_1(op__TransactionSecondary__start, smb_request_t *, sr);
159 + DTRACE_SMB_START(op__TransactionSecondary, smb_request_t *, sr);
160 160 return (SDRC_SUCCESS);
161 161 }
162 162
163 163 void
164 164 smb_post_transaction_secondary(smb_request_t *sr)
165 165 {
166 - DTRACE_SMB_1(op__TransactionSecondary__done, smb_request_t *, sr);
166 + DTRACE_SMB_DONE(op__TransactionSecondary, smb_request_t *, sr);
167 167 }
168 168
169 169 smb_sdrc_t
170 170 smb_com_transaction_secondary(smb_request_t *sr)
171 171 {
172 172 uint16_t tpscnt, tdscnt, pscnt, psdisp;
173 173 uint16_t dscnt, dsoff, dsdisp, psoff;
174 174 smb_xa_t *xa;
175 175 int rc;
176 176
177 177 if ((xa = smbsr_lookup_xa(sr)) == 0) {
178 178 smbsr_error(sr, 0, ERRSRV, ERRsrverror);
179 179 return (SDRC_ERROR);
180 180 }
181 181
182 182 if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
183 183 if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
184 184 smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
185 185 ERRDOS, ERRnoaccess);
186 186 return (SDRC_ERROR);
187 187 }
188 188 }
189 189
190 190 if (xa->smb_com != SMB_COM_TRANSACTION) {
191 191 return (SDRC_DROP_VC);
192 192 }
193 193
194 194 rc = smbsr_decode_vwv(sr, SMB_TRANSSHDR_ED_FMT, &tpscnt, &tdscnt,
195 195 &pscnt, &psoff, &psdisp, &dscnt, &dsoff, &dsdisp);
196 196
197 197 if (rc != 0)
198 198 return (SDRC_ERROR);
199 199
200 200 mutex_enter(&xa->xa_mutex);
201 201 if (xa->smb_tpscnt > tpscnt)
202 202 xa->smb_tpscnt = tpscnt;
203 203 if (xa->smb_tdscnt > tdscnt)
204 204 xa->smb_tdscnt = tdscnt;
205 205 xa->req_disp_param = psdisp + pscnt;
206 206 xa->req_disp_data = dsdisp + dscnt;
207 207
208 208 /*
209 209 * The words psdisp, dsdisp, tell us what displacement
210 210 * into the entire trans parameter and data buffers
211 211 * where we should put the params & data that are
212 212 * delivered by this request. [MS-CIFS] says all the
213 213 * parameters and data SHOULD be sent sequentially, so
214 214 * so we can normally reassemble by simply appending.
215 215 * However, the components MAY come out of order, so
216 216 * check and set the current offset. This is rare,
217 217 * and we might like to know when this happens, so
218 218 * fire some static dtrace probes when it does.
219 219 */
220 220 if (xa->req_param_mb.chain_offset != psdisp) {
221 221 DTRACE_PROBE2(trans_param_disp,
222 222 smb_xa_t *, xa, uint16_t, psdisp);
223 223 xa->req_param_mb.chain_offset = psdisp;
224 224 }
225 225 if (xa->req_data_mb.chain_offset != dsdisp) {
226 226 DTRACE_PROBE2(trans_data_disp,
227 227 smb_xa_t *, xa, uint16_t, dsdisp);
228 228 xa->req_data_mb.chain_offset = dsdisp;
229 229 }
230 230
231 231 if (smb_mbc_copy(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
232 232 mutex_exit(&xa->xa_mutex);
233 233 smb_xa_close(xa);
234 234 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
235 235 return (SDRC_ERROR);
236 236 }
237 237 if (smb_mbc_copy(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
238 238 mutex_exit(&xa->xa_mutex);
239 239 smb_xa_close(xa);
240 240 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
241 241 return (SDRC_ERROR);
242 242 }
243 243 mutex_exit(&xa->xa_mutex);
244 244
245 245 if (!smb_trans_ready(xa))
246 246 return (SDRC_NO_REPLY);
|
↓ open down ↓ |
70 lines elided |
↑ open up ↑ |
247 247
248 248 if (!smb_xa_complete(xa))
249 249 return (SDRC_NO_REPLY);
250 250
251 251 return (smb_trans_dispatch(sr, xa));
252 252 }
253 253
254 254 smb_sdrc_t
255 255 smb_pre_ioctl(smb_request_t *sr)
256 256 {
257 - DTRACE_SMB_1(op__Ioctl__start, smb_request_t *, sr);
257 + DTRACE_SMB_START(op__Ioctl, smb_request_t *, sr);
258 258 return (SDRC_SUCCESS);
259 259 }
260 260
261 261 void
262 262 smb_post_ioctl(smb_request_t *sr)
263 263 {
264 - DTRACE_SMB_1(op__Ioctl__done, smb_request_t *, sr);
264 + DTRACE_SMB_DONE(op__Ioctl, smb_request_t *, sr);
265 265 }
266 266
267 267 smb_sdrc_t
268 268 smb_com_ioctl(smb_request_t *sr)
269 269 {
270 270 uint16_t fid, category, function, tpscnt, tdscnt, mprcnt;
271 271 uint16_t mdrcnt, pscnt, pdoff, dscnt, dsoff;
272 272 uint32_t timeout;
273 273 int rc;
274 274
275 275 rc = smbsr_decode_vwv(sr, "wwwwwwwl2.wwww", &fid, &category, &function,
276 276 &tpscnt, &tdscnt, &mprcnt, &mdrcnt, &timeout, &pscnt,
277 277 &pdoff, &dscnt, &dsoff);
|
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
278 278
279 279 if (rc != 0)
280 280 return (SDRC_ERROR);
281 281
282 282 return (SDRC_NOT_IMPLEMENTED);
283 283 }
284 284
285 285 smb_sdrc_t
286 286 smb_pre_transaction2(smb_request_t *sr)
287 287 {
288 - DTRACE_SMB_1(op__Transaction2__start, smb_request_t *, sr);
288 + DTRACE_SMB_START(op__Transaction2, smb_request_t *, sr);
289 289 return (SDRC_SUCCESS);
290 290 }
291 291
292 292 void
293 293 smb_post_transaction2(smb_request_t *sr)
294 294 {
295 - DTRACE_SMB_1(op__Transaction2__done, smb_request_t *, sr);
295 + DTRACE_SMB_DONE(op__Transaction2, smb_request_t *, sr);
296 296 }
297 297
298 298 smb_sdrc_t
299 299 smb_com_transaction2(struct smb_request *sr)
300 300 {
301 301 unsigned char msrcnt, suwcnt;
302 302 uint16_t tpscnt, tdscnt, mprcnt, mdrcnt, flags;
303 303 uint16_t pscnt, psoff, dscnt, dsoff;
304 304 uint32_t timeo;
305 305 smb_xa_t *xa;
306 306 int ready;
307 307 int rc;
308 308
309 309 rc = smbsr_decode_vwv(sr, SMB_TRANSHDR_ED_FMT, &tpscnt, &tdscnt,
310 310 &mprcnt, &mdrcnt, &msrcnt, &flags, &timeo, &pscnt, &psoff, &dscnt,
311 311 &dsoff, &suwcnt);
312 312
313 313 if (rc != 0)
314 314 return (SDRC_ERROR);
315 315
316 316 xa = smb_xa_create(sr->session, sr, tpscnt, tdscnt, mprcnt, mdrcnt,
317 317 msrcnt, suwcnt);
318 318 if (xa == 0) {
319 319 smbsr_error(sr, 0, ERRSRV, ERRnoroom);
320 320 return (SDRC_ERROR);
321 321 }
322 322
323 323 xa->smb_flags = flags;
324 324 xa->smb_timeout = timeo;
325 325 xa->req_disp_param = pscnt;
326 326 xa->req_disp_data = dscnt;
327 327
328 328 if (smb_mbc_copy(&xa->req_setup_mb, &sr->smb_vwv,
329 329 sr->smb_vwv.chain_offset, suwcnt*2)) {
330 330 smb_xa_rele(sr->session, xa);
331 331 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
332 332 return (SDRC_ERROR);
333 333 }
334 334 if (smb_mbc_copy(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
335 335 smb_xa_rele(sr->session, xa);
336 336 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
337 337 return (SDRC_ERROR);
338 338 }
339 339 if (smb_mbc_copy(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
340 340 smb_xa_rele(sr->session, xa);
341 341 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
342 342 return (SDRC_ERROR);
343 343 }
344 344
345 345 ready = smb_trans_ready(xa);
346 346
347 347 if (smb_xa_open(xa)) {
348 348 smb_xa_rele(sr->session, xa);
349 349 smbsr_error(sr, 0, ERRSRV, ERRsrverror);
350 350 return (SDRC_ERROR);
351 351 }
352 352 sr->r_xa = xa;
353 353
354 354 if (!ready) {
355 355 rc = smbsr_encode_empty_result(sr);
356 356 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
357 357 }
358 358
359 359 if (!smb_xa_complete(xa)) {
360 360 smb_xa_close(xa);
|
↓ open down ↓ |
55 lines elided |
↑ open up ↑ |
361 361 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
362 362 return (SDRC_ERROR);
363 363 }
364 364
365 365 return (smb_trans2_dispatch(sr, xa));
366 366 }
367 367
368 368 smb_sdrc_t
369 369 smb_pre_transaction2_secondary(smb_request_t *sr)
370 370 {
371 - DTRACE_SMB_1(op__Transaction2Secondary__start, smb_request_t *, sr);
371 + DTRACE_SMB_START(op__Transaction2Secondary, smb_request_t *, sr);
372 372 return (SDRC_SUCCESS);
373 373 }
374 374
375 375 void
376 376 smb_post_transaction2_secondary(smb_request_t *sr)
377 377 {
378 - DTRACE_SMB_1(op__Transaction2Secondary__done, smb_request_t *, sr);
378 + DTRACE_SMB_DONE(op__Transaction2Secondary, smb_request_t *, sr);
379 379 }
380 380
381 381 smb_sdrc_t
382 382 smb_com_transaction2_secondary(smb_request_t *sr)
383 383 {
384 384 uint16_t tpscnt, tdscnt, fid;
385 385 uint16_t pscnt, psoff, psdisp, dscnt, dsoff, dsdisp;
386 386 smb_xa_t *xa;
387 387 int rc;
388 388
389 389 if ((xa = smbsr_lookup_xa(sr)) == 0) {
390 390 smbsr_error(sr, 0, ERRSRV, ERRsrverror);
391 391 return (SDRC_ERROR);
392 392 }
393 393
394 394 if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
395 395 if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
396 396 smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
397 397 ERRDOS, ERRnoaccess);
398 398 return (SDRC_ERROR);
399 399 }
400 400 }
401 401
402 402 if (xa->smb_com != SMB_COM_TRANSACTION2) {
403 403 return (SDRC_DROP_VC);
404 404 }
405 405
406 406 rc = smbsr_decode_vwv(sr, SMB_TRANS2SHDR_ED_FMT, &tpscnt, &tdscnt,
407 407 &pscnt, &psoff, &psdisp, &dscnt, &dsoff, &dsdisp, &fid);
408 408
409 409 if (rc != 0)
410 410 return (SDRC_ERROR);
411 411
412 412 mutex_enter(&xa->xa_mutex);
413 413 if (xa->smb_tpscnt > tpscnt)
414 414 xa->smb_tpscnt = tpscnt;
415 415 if (xa->smb_tdscnt > tdscnt)
416 416 xa->smb_tdscnt = tdscnt;
417 417 if (fid != 0xFFFF)
418 418 xa->xa_smb_fid = fid;
419 419 xa->req_disp_param = psdisp + pscnt;
420 420 xa->req_disp_data = dsdisp + dscnt;
421 421
422 422 /*
423 423 * See comment in smb_com_transaction_secondary
424 424 */
425 425 if (xa->req_param_mb.chain_offset != psdisp) {
426 426 DTRACE_PROBE2(trans_param_disp,
427 427 smb_xa_t *, xa, uint16_t, psdisp);
428 428 xa->req_param_mb.chain_offset = psdisp;
429 429 }
430 430 if (xa->req_data_mb.chain_offset != dsdisp) {
431 431 DTRACE_PROBE2(trans_data_disp,
432 432 smb_xa_t *, xa, uint16_t, dsdisp);
433 433 xa->req_data_mb.chain_offset = dsdisp;
434 434 }
435 435
436 436 if (smb_mbc_copy(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
437 437 mutex_exit(&xa->xa_mutex);
438 438 smb_xa_close(xa);
439 439 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
440 440 return (SDRC_ERROR);
441 441 }
442 442 if (smb_mbc_copy(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
443 443 mutex_exit(&xa->xa_mutex);
444 444 smb_xa_close(xa);
445 445 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
446 446 return (SDRC_ERROR);
447 447 }
448 448 mutex_exit(&xa->xa_mutex);
449 449
450 450 if (!smb_trans_ready(xa))
451 451 return (SDRC_NO_REPLY);
452 452
453 453 if (!smb_xa_complete(xa))
454 454 return (SDRC_NO_REPLY);
455 455
456 456 return (smb_trans2_dispatch(sr, xa));
457 457 }
458 458
459 459 static smb_sdrc_t
460 460 smb_nt_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
461 461 {
462 462 int rc;
463 463 int total_bytes, n_setup, n_param, n_data;
464 464 int param_off, param_pad, data_off, data_pad;
465 465
466 466 switch (xa->smb_func) {
467 467 case NT_TRANSACT_CREATE:
468 468 if ((rc = smb_pre_nt_transact_create(sr, xa)) == 0)
469 469 rc = smb_nt_transact_create(sr, xa);
470 470 smb_post_nt_transact_create(sr, xa);
471 471 break;
472 472 case NT_TRANSACT_NOTIFY_CHANGE:
473 473 rc = smb_nt_transact_notify_change(sr, xa);
474 474 break;
475 475 case NT_TRANSACT_QUERY_SECURITY_DESC:
476 476 rc = smb_nt_transact_query_security_info(sr, xa);
477 477 break;
478 478 case NT_TRANSACT_SET_SECURITY_DESC:
479 479 rc = smb_nt_transact_set_security_info(sr, xa);
480 480 break;
481 481 case NT_TRANSACT_IOCTL:
482 482 rc = smb_nt_transact_ioctl(sr, xa);
483 483 break;
484 484 case NT_TRANSACT_QUERY_QUOTA:
485 485 rc = smb_nt_transact_query_quota(sr, xa);
486 486 break;
487 487 case NT_TRANSACT_SET_QUOTA:
488 488 rc = smb_nt_transact_set_quota(sr, xa);
489 489 break;
490 490 case NT_TRANSACT_RENAME:
491 491 rc = smb_nt_transact_rename(sr, xa);
492 492 break;
493 493
494 494 default:
495 495 smbsr_error(sr, 0, ERRSRV, ERRsmbcmd);
496 496 return (SDRC_ERROR);
497 497 }
498 498
499 499 switch (rc) {
500 500 case SDRC_SUCCESS:
501 501 break;
502 502
503 503 case SDRC_DROP_VC:
504 504 case SDRC_NO_REPLY:
505 505 case SDRC_ERROR:
506 506 case SDRC_SR_KEPT:
507 507 return (rc);
508 508
509 509 case SDRC_NOT_IMPLEMENTED:
510 510 smbsr_error(sr, 0, ERRSRV, ERRsmbcmd);
511 511 return (SDRC_ERROR);
512 512
513 513 default:
514 514 break;
515 515 }
516 516
517 517 n_setup = MBC_LENGTH(&xa->rep_setup_mb);
518 518 n_param = MBC_LENGTH(&xa->rep_param_mb);
519 519 n_data = MBC_LENGTH(&xa->rep_data_mb);
520 520
521 521 if (xa->smb_msrcnt < n_setup ||
522 522 xa->smb_mprcnt < n_param ||
523 523 xa->smb_mdrcnt < n_data) {
524 524 smbsr_error(sr, 0, ERRSRV, ERRsmbcmd);
525 525 return (SDRC_ERROR);
526 526 }
527 527
528 528 /* neato, blast it over there */
529 529
530 530 n_setup = (n_setup + 1) / 2; /* Conver to setup words */
531 531 param_pad = 1; /* must be one */
532 532 param_off = param_pad + 32 + 37 + (n_setup << 1) + 2;
533 533 data_pad = (4 - ((param_off + n_param) & 3)) % 4; /* Pad to 4 byte */
534 534 data_off = param_off + n_param + data_pad; /* Param off from hdr */
535 535 total_bytes = param_pad + n_param + data_pad + n_data;
536 536
537 537 rc = smbsr_encode_result(sr, 18+n_setup, total_bytes,
538 538 "b3.llllllllbCw#.C#.C",
539 539 18 + n_setup, /* wct */
540 540 n_param, /* Total Parameter Bytes */
541 541 n_data, /* Total Data Bytes */
542 542 n_param, /* Total Parameter Bytes this buffer */
543 543 param_off, /* Param offset from header start */
544 544 0, /* Param displacement */
545 545 n_data, /* Total Data Bytes this buffer */
546 546 data_off, /* Data offset from header start */
547 547 0, /* Data displacement */
548 548 n_setup, /* suwcnt */
549 549 &xa->rep_setup_mb, /* setup[] */
550 550 total_bytes, /* Total data bytes */
|
↓ open down ↓ |
162 lines elided |
↑ open up ↑ |
551 551 param_pad,
552 552 &xa->rep_param_mb,
553 553 data_pad,
554 554 &xa->rep_data_mb);
555 555 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
556 556 }
557 557
558 558 smb_sdrc_t
559 559 smb_pre_nt_transact(smb_request_t *sr)
560 560 {
561 - DTRACE_SMB_1(op__NtTransact__start, smb_request_t *, sr);
561 + DTRACE_SMB_START(op__NtTransact, smb_request_t *, sr);
562 562 return (SDRC_SUCCESS);
563 563 }
564 564
565 565 void
566 566 smb_post_nt_transact(smb_request_t *sr)
567 567 {
568 - DTRACE_SMB_1(op__NtTransact__done, smb_request_t *, sr);
568 + DTRACE_SMB_DONE(op__NtTransact, smb_request_t *, sr);
569 569 }
570 570
571 571 smb_sdrc_t
572 572 smb_com_nt_transact(struct smb_request *sr)
573 573 {
574 574 uint16_t Function;
575 575 unsigned char MaxSetupCount, SetupCount;
576 576 uint32_t TotalParameterCount, TotalDataCount;
577 577 uint32_t MaxParameterCount, MaxDataCount, pscnt;
578 578 uint32_t psoff, dscnt, dsoff;
579 579 smb_xa_t *xa;
580 580 int ready;
581 581 int rc;
582 582
583 583 rc = smbsr_decode_vwv(sr, SMB_NT_TRANSHDR_ED_FMT, &MaxSetupCount,
584 584 &TotalParameterCount, &TotalDataCount, &MaxParameterCount,
585 585 &MaxDataCount, &pscnt, &psoff, &dscnt,
586 586 &dsoff, &SetupCount, &Function);
587 587
588 588 if (rc != 0)
589 589 return (SDRC_ERROR);
590 590
591 591 xa = smb_xa_create(sr->session, sr, TotalParameterCount, TotalDataCount,
592 592 MaxParameterCount, MaxDataCount, MaxSetupCount, SetupCount);
593 593 if (xa == 0) {
594 594 smbsr_error(sr, 0, ERRSRV, ERRnoroom);
595 595 return (SDRC_ERROR);
596 596 }
597 597
598 598 xa->smb_flags = 0;
599 599 xa->smb_timeout = 0;
600 600 xa->smb_func = Function;
601 601 xa->req_disp_param = pscnt;
602 602 xa->req_disp_data = dscnt;
603 603
604 604 if (smb_mbc_copy(&xa->req_setup_mb, &sr->smb_vwv,
605 605 sr->smb_vwv.chain_offset, SetupCount * 2)) {
606 606 smb_xa_rele(sr->session, xa);
607 607 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
608 608 return (SDRC_ERROR);
609 609 }
610 610 if (smb_mbc_copy(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
611 611 smb_xa_rele(sr->session, xa);
612 612 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
613 613 return (SDRC_ERROR);
614 614 }
615 615 if (smb_mbc_copy(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
616 616 smb_xa_rele(sr->session, xa);
617 617 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
618 618 return (SDRC_ERROR);
619 619 }
620 620
621 621 ready = smb_trans_ready(xa);
622 622
623 623 if (smb_xa_open(xa)) {
624 624 smb_xa_rele(sr->session, xa);
625 625 smbsr_error(sr, 0, ERRSRV, ERRsrverror);
626 626 return (SDRC_ERROR);
627 627 }
628 628 sr->r_xa = xa;
629 629
630 630 if (!ready) {
631 631 rc = smbsr_encode_empty_result(sr);
632 632 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
633 633 }
634 634
635 635 if (!smb_xa_complete(xa)) {
636 636 smb_xa_close(xa);
|
↓ open down ↓ |
58 lines elided |
↑ open up ↑ |
637 637 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
638 638 return (SDRC_ERROR);
639 639 }
640 640
641 641 return (smb_nt_trans_dispatch(sr, xa));
642 642 }
643 643
644 644 smb_sdrc_t
645 645 smb_pre_nt_transact_secondary(smb_request_t *sr)
646 646 {
647 - DTRACE_SMB_1(op__NtTransactSecondary__start, smb_request_t *, sr);
647 + DTRACE_SMB_START(op__NtTransactSecondary, smb_request_t *, sr);
648 648 return (SDRC_SUCCESS);
649 649 }
650 650
651 651 void
652 652 smb_post_nt_transact_secondary(smb_request_t *sr)
653 653 {
654 - DTRACE_SMB_1(op__NtTransactSecondary__done, smb_request_t *, sr);
654 + DTRACE_SMB_DONE(op__NtTransactSecondary, smb_request_t *, sr);
655 655 }
656 656
657 657 smb_sdrc_t
658 658 smb_com_nt_transact_secondary(struct smb_request *sr)
659 659 {
660 660 uint16_t tpscnt, tdscnt, fid;
661 661 uint16_t pscnt, psoff, psdisp, dscnt, dsoff, dsdisp;
662 662 smb_xa_t *xa;
663 663 int rc;
664 664
665 665 if ((xa = smbsr_lookup_xa(sr)) == 0) {
666 666 smbsr_error(sr, 0, ERRSRV, ERRsrverror);
667 667 return (SDRC_ERROR);
668 668 }
669 669
670 670 if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
671 671 if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
672 672 smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
673 673 ERRDOS, ERRnoaccess);
674 674 return (SDRC_ERROR);
675 675 }
676 676 }
677 677
678 678 if (xa->smb_com != SMB_COM_TRANSACTION2) {
679 679 return (SDRC_DROP_VC);
680 680 }
681 681
682 682 rc = smbsr_decode_vwv(sr, SMB_TRANS2SHDR_ED_FMT, &tpscnt, &tdscnt,
683 683 &pscnt, &psoff, &psdisp, &dscnt, &dsoff, &dsdisp, &fid);
684 684
685 685 if (rc != 0)
686 686 return (SDRC_ERROR);
687 687
688 688 mutex_enter(&xa->xa_mutex);
689 689 if (xa->smb_tpscnt > tpscnt)
690 690 xa->smb_tpscnt = tpscnt;
691 691 if (xa->smb_tdscnt > tdscnt)
692 692 xa->smb_tdscnt = tdscnt;
693 693 if (fid != 0xFFFF)
694 694 xa->xa_smb_fid = fid;
695 695 xa->req_disp_param = psdisp + pscnt;
696 696 xa->req_disp_data = dsdisp + dscnt;
697 697
698 698 /*
699 699 * See comment in smb_com_transaction_secondary
700 700 */
701 701 if (xa->req_param_mb.chain_offset != psdisp) {
702 702 DTRACE_PROBE2(trans_param_disp,
703 703 smb_xa_t *, xa, uint16_t, psdisp);
704 704 xa->req_param_mb.chain_offset = psdisp;
705 705 }
706 706 if (xa->req_data_mb.chain_offset != dsdisp) {
707 707 DTRACE_PROBE2(trans_data_disp,
708 708 smb_xa_t *, xa, uint16_t, dsdisp);
709 709 xa->req_data_mb.chain_offset = dsdisp;
710 710 }
711 711
712 712 if (smb_mbc_copy(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
713 713 mutex_exit(&xa->xa_mutex);
714 714 smb_xa_close(xa);
715 715 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
716 716 return (SDRC_ERROR);
717 717 }
718 718 if (smb_mbc_copy(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
719 719 mutex_exit(&xa->xa_mutex);
720 720 smb_xa_close(xa);
721 721 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
722 722 return (SDRC_ERROR);
723 723 }
724 724 mutex_exit(&xa->xa_mutex);
725 725
726 726 if (!smb_trans_ready(xa))
727 727 return (SDRC_NO_REPLY);
728 728
729 729 if (!smb_xa_complete(xa))
730 730 return (SDRC_NO_REPLY);
731 731
732 732 return (smb_nt_trans_dispatch(sr, xa));
733 733 }
734 734
735 735 static int
736 736 smb_trans_ready(smb_xa_t *xa)
737 737 {
738 738 int rc;
739 739
740 740 mutex_enter(&xa->xa_mutex);
741 741 rc = xa->req_disp_data >= xa->smb_tdscnt &&
742 742 xa->req_disp_param >= xa->smb_tpscnt;
743 743 mutex_exit(&xa->xa_mutex);
744 744
745 745 return (rc);
746 746 }
747 747
748 748 static void
749 749 smb_encode_SHARE_INFO_1(struct mbuf_chain *output, struct mbuf_chain *text,
750 750 char *oem_name, uint16_t type, char *comment)
751 751 {
752 752 (void) smb_mbc_encodef(output, "13c.wl", oem_name,
753 753 type, MBC_LENGTH(text));
754 754
755 755 (void) smb_mbc_encodef(text, "s", comment ? comment : "");
756 756 }
757 757
758 758 static void
759 759 smb_encode_SHARE_INFO_2(struct mbuf_chain *output, struct mbuf_chain *text,
760 760 smb_request_t *sr, char *oem_name, uint16_t type,
761 761 char *comment, uint16_t access, char *path, char *password)
762 762 {
763 763 unsigned char pword[9];
764 764
765 765 bzero(pword, sizeof (pword));
766 766 (void) strncpy((char *)pword, password, sizeof (pword));
767 767 smb_encode_SHARE_INFO_1(output, text, oem_name, type, comment);
768 768 (void) smb_mbc_encodef(output, "wwwl9c.",
769 769 access,
770 770 sr->sr_cfg->skc_maxconnections,
771 771 smb_server_get_session_count(sr->sr_server),
772 772 MBC_LENGTH(text),
773 773 pword);
774 774 (void) smb_mbc_encodef(text, "s", path);
775 775 }
776 776
777 777 int
778 778 smb_trans_net_share_enum(struct smb_request *sr, struct smb_xa *xa)
779 779 {
780 780 uint16_t pid_hi, pid_lo;
781 781
782 782 /*
783 783 * Number of data bytes that will
784 784 * be sent in the current response
785 785 */
786 786 uint16_t data_scnt;
787 787
788 788 /*
789 789 * Total number of data bytes that
790 790 * are sent till now. This is only
791 791 * used for calculating current data
792 792 * displacement
793 793 */
794 794 uint16_t tot_data_scnt;
795 795
796 796 /*
797 797 * Number of parameter bytes should
798 798 * be sent for the current response.
799 799 * It is 8 for the 1st response and
800 800 * 0 for others
801 801 */
802 802 uint16_t param_scnt;
803 803
804 804 /* number of setup and parameter bytes */
805 805 uint16_t n_setup, n_param;
806 806
807 807 /* data and parameter displacement */
808 808 uint16_t data_disp, param_disp;
809 809
810 810 /* parameter and data offset and pad */
811 811 int param_off, param_pad, data_off, data_pad;
812 812
813 813 /*
814 814 * total bytes of parameters and data
815 815 * in the packet, plus the pad bytes.
816 816 */
817 817 int tot_packet_bytes;
818 818
819 819 boolean_t first_resp;
820 820
821 821 char fmt[16];
822 822 struct mbuf_chain reply;
823 823
824 824 uint16_t level;
825 825 uint16_t pkt_bufsize;
826 826 smb_enumshare_info_t esi;
827 827 char *sent_buf;
828 828
829 829 ASSERT(sr->uid_user);
830 830
831 831 if (smb_mbc_decodef(&xa->req_param_mb, "ww", &level,
832 832 &esi.es_bufsize) != 0)
833 833 return (SDRC_NOT_IMPLEMENTED);
834 834
835 835 if (level != 1) {
836 836 /*
837 837 * Only level 1 is valid for NetShareEnum
838 838 * None of the error codes in the spec are meaningful
839 839 * here. This error code is returned by Windows.
840 840 */
841 841 (void) smb_mbc_encodef(&xa->rep_param_mb, "wwww",
842 842 ERROR_INVALID_LEVEL, 0, 0, 0);
843 843 return (SDRC_SUCCESS);
844 844 }
845 845
846 846 esi.es_buf = smb_srm_zalloc(sr, esi.es_bufsize);
847 847 esi.es_posix_uid = crgetuid(sr->uid_user->u_cred);
848 848 smb_kshare_enum(sr->sr_server, &esi);
849 849
850 850 /* client buffer size is not big enough to hold any shares */
851 851 if (esi.es_nsent == 0) {
852 852 (void) smb_mbc_encodef(&xa->rep_param_mb, "wwww",
853 853 ERROR_MORE_DATA, 0, esi.es_nsent, esi.es_ntotal);
854 854 return (SDRC_SUCCESS);
855 855 }
856 856
857 857 /*
858 858 * Initialize the reply mbuf chain. Note that we re-initialize
859 859 * this on each pass through the loop below.
860 860 */
861 861 MBC_SETUP(&reply, smb_maxbufsize);
862 862
863 863 /*
864 864 * The rep_setup_mb is already initialized in smb_trans_dispatch().
865 865 * Calling MBC_INIT() will initialized the structure and so the
866 866 * pointer to the mbuf chains will be lost. Therefore, we need
867 867 * to free the resources before calling MBC_INIT() again.
868 868 */
869 869 n_setup = 0; /* Setup count for NetShareEnum SMB is 0 */
870 870 MBC_FLUSH(&xa->rep_setup_mb);
871 871
872 872 n_param = 8;
873 873 pkt_bufsize = sr->session->smb_msg_size -
874 874 (SMB_HEADER_ED_LEN + RESP_HEADER_LEN + n_param);
875 875
876 876 tot_data_scnt = 0;
877 877 sent_buf = esi.es_buf;
878 878 first_resp = B_TRUE;
879 879
880 880 while (tot_data_scnt < esi.es_datasize) {
881 881 data_scnt = esi.es_datasize - tot_data_scnt;
882 882 if (data_scnt > pkt_bufsize)
883 883 data_scnt = pkt_bufsize;
884 884 MBC_FLUSH(&xa->rep_data_mb);
885 885
886 886 (void) sprintf(fmt, "%dc", data_scnt);
887 887 (void) smb_mbc_encodef(&xa->rep_data_mb, fmt, sent_buf);
888 888
889 889 sent_buf += data_scnt;
890 890 tot_data_scnt += data_scnt;
891 891
892 892 /* Only the 1st response packet contains parameters */
893 893 param_scnt = (first_resp) ? n_param : 0;
894 894 param_pad = 1; /* always one */
895 895 param_off = SMB_HEADER_ED_LEN + RESP_HEADER_LEN;
896 896 param_disp = (first_resp) ? 0 : n_param;
897 897
898 898 MBC_FLUSH(&xa->rep_param_mb);
899 899
900 900 if (first_resp) {
901 901 first_resp = B_FALSE;
902 902 (void) smb_mbc_encodef(&xa->rep_param_mb, "wwww",
903 903 (esi.es_ntotal > esi.es_nsent)
904 904 ? ERROR_MORE_DATA : 0,
905 905 0, esi.es_nsent, esi.es_ntotal);
906 906 }
907 907
908 908 data_pad = (param_off + n_param) & 1; /* Pad to short */
909 909
910 910 /* data off from hdr start */
911 911 data_off = param_off + param_scnt + data_pad;
912 912 data_disp = tot_data_scnt - data_scnt;
913 913 tot_packet_bytes = param_pad + param_scnt + data_pad +
914 914 data_scnt;
915 915
916 916 pid_hi = sr->smb_pid >> 16;
917 917 pid_lo = (uint16_t)sr->smb_pid;
918 918
919 919 MBC_FLUSH(&reply);
920 920 (void) smb_mbc_encodef(&reply, SMB_HEADER_ED_FMT,
921 921 sr->first_smb_com,
922 922 sr->smb_rcls,
923 923 sr->smb_reh,
924 924 sr->smb_err,
925 925 sr->smb_flg | SMB_FLAGS_REPLY,
926 926 sr->smb_flg2,
927 927 pid_hi,
928 928 sr->smb_sig,
929 929 sr->smb_tid,
930 930 pid_lo,
931 931 sr->smb_uid,
932 932 sr->smb_mid);
933 933
934 934 (void) smb_mbc_encodef(&reply,
935 935 "bww2.wwwwwwb.Cw#.C#.C",
936 936 10 + n_setup, /* wct */
937 937 n_param, /* Total Parameter Bytes */
938 938 esi.es_datasize, /* Total Data Bytes */
939 939 param_scnt, /* Total Parameter Bytes this buffer */
940 940 param_off, /* Param offset from header start */
941 941 param_disp, /* Param displacement */
942 942 data_scnt, /* Total Data Bytes this buffer */
943 943 data_off, /* Data offset from header start */
944 944 data_disp, /* Data displacement */
945 945 n_setup, /* suwcnt */
946 946 &xa->rep_setup_mb, /* setup[] */
947 947 tot_packet_bytes, /* Total data bytes */
948 948 param_pad,
949 949 &xa->rep_param_mb,
950 950 data_pad,
951 951 &xa->rep_data_mb);
952 952
953 953 if (sr->session->signing.flags & SMB_SIGNING_ENABLED)
954 954 smb_sign_reply(sr, &reply);
955 955
956 956 (void) smb_session_send(sr->session, 0, &reply);
957 957
958 958 }
959 959
960 960 m_freem(reply.chain);
961 961
962 962 return (SDRC_NO_REPLY);
963 963 }
964 964
965 965 int
966 966 smb_trans_net_share_getinfo(smb_request_t *sr, struct smb_xa *xa)
967 967 {
968 968 uint16_t level, max_bytes, access;
969 969 struct mbuf_chain str_mb;
970 970 char *share;
971 971 char *password;
972 972 smb_kshare_t *si;
973 973
974 974 if (smb_mbc_decodef(&xa->req_param_mb, "%sww", sr,
975 975 &share, &level, &max_bytes) != 0)
976 976 return (SDRC_NOT_IMPLEMENTED);
977 977
978 978 si = smb_kshare_lookup(sr->sr_server, share);
979 979 if ((si == NULL) || (si->shr_oemname == NULL)) {
980 980 (void) smb_mbc_encodef(&xa->rep_param_mb, "www",
981 981 NERR_NetNameNotFound, 0, 0);
982 982 if (si)
983 983 smb_kshare_release(sr->sr_server, si);
984 984 return (SDRC_SUCCESS);
985 985 }
986 986
987 987 access = SHARE_ACCESS_ALL;
988 988 password = "";
989 989
990 990 MBC_INIT(&str_mb, max_bytes);
991 991
992 992 switch (level) {
993 993 case 0 :
994 994 (void) smb_mbc_encodef(&xa->rep_data_mb, "13c",
995 995 si->shr_oemname);
996 996 break;
997 997
998 998 case 1 :
999 999 smb_encode_SHARE_INFO_1(&xa->rep_data_mb, &str_mb,
1000 1000 si->shr_oemname, si->shr_type, si->shr_cmnt);
1001 1001 break;
1002 1002
1003 1003 case 2 :
1004 1004 smb_encode_SHARE_INFO_2(&xa->rep_data_mb, &str_mb, sr,
1005 1005 si->shr_oemname, si->shr_type, si->shr_cmnt, access,
1006 1006 si->shr_path, password);
1007 1007 break;
1008 1008
1009 1009 default:
1010 1010 smb_kshare_release(sr->sr_server, si);
1011 1011 (void) smb_mbc_encodef(&xa->rep_param_mb, "www",
1012 1012 ERROR_INVALID_LEVEL, 0, 0);
1013 1013 m_freem(str_mb.chain);
1014 1014 return (SDRC_NOT_IMPLEMENTED);
1015 1015 }
1016 1016
1017 1017 smb_kshare_release(sr->sr_server, si);
1018 1018 (void) smb_mbc_encodef(&xa->rep_param_mb, "www", NERR_Success,
1019 1019 -MBC_LENGTH(&xa->rep_data_mb),
1020 1020 MBC_LENGTH(&xa->rep_data_mb) + MBC_LENGTH(&str_mb));
1021 1021 (void) smb_mbc_encodef(&xa->rep_data_mb, "C", &str_mb);
1022 1022 m_freem(str_mb.chain);
1023 1023 return (SDRC_SUCCESS);
1024 1024 }
1025 1025
1026 1026 int
1027 1027 smb_trans_net_workstation_getinfo(struct smb_request *sr, struct smb_xa *xa)
1028 1028 {
1029 1029 uint16_t level, max_bytes;
1030 1030 struct mbuf_chain str_mb;
1031 1031 char *domain;
1032 1032 char *hostname;
1033 1033
1034 1034 if ((smb_mbc_decodef(&xa->req_param_mb, "ww",
1035 1035 &level, &max_bytes) != 0) ||
1036 1036 (level != 10)) {
1037 1037 (void) smb_mbc_encodef(&xa->rep_param_mb, "wwww",
1038 1038 NERR_BadTransactConfig, 0, 0, 0);
1039 1039 return (SDRC_SUCCESS);
1040 1040 }
1041 1041
1042 1042 domain = sr->sr_cfg->skc_nbdomain;
1043 1043 hostname = sr->sr_cfg->skc_hostname;
1044 1044
1045 1045 MBC_INIT(&str_mb, max_bytes);
1046 1046
1047 1047 (void) smb_mbc_encodef(&str_mb, "."); /* Prevent NULL pointers */
1048 1048
1049 1049 (void) smb_mbc_encodef(&xa->rep_data_mb, "l", MBC_LENGTH(&str_mb));
1050 1050 (void) smb_mbc_encodef(&str_mb, "s", hostname);
1051 1051 (void) smb_mbc_encodef(&xa->rep_data_mb, "l", MBC_LENGTH(&str_mb));
1052 1052 (void) smb_mbc_encodef(&str_mb, "s", "nobody");
1053 1053 (void) smb_mbc_encodef(&xa->rep_data_mb, "l", MBC_LENGTH(&str_mb));
1054 1054 (void) smb_mbc_encodef(&str_mb, "s", domain);
1055 1055 (void) smb_mbc_encodef(&xa->rep_data_mb, "bbl",
1056 1056 (uint8_t)sr->sr_cfg->skc_version.sv_major,
1057 1057 (uint8_t)sr->sr_cfg->skc_version.sv_minor,
1058 1058 MBC_LENGTH(&str_mb));
1059 1059 (void) smb_mbc_encodef(&str_mb, "s", domain);
1060 1060 (void) smb_mbc_encodef(&xa->rep_data_mb, "l", MBC_LENGTH(&str_mb));
1061 1061 (void) smb_mbc_encodef(&str_mb, "s", domain);
1062 1062
1063 1063 (void) smb_mbc_encodef(&xa->rep_param_mb, "www", 0,
1064 1064 -MBC_LENGTH(&xa->rep_data_mb),
1065 1065 MBC_LENGTH(&xa->rep_data_mb) + MBC_LENGTH(&str_mb));
1066 1066 (void) smb_mbc_encodef(&xa->rep_data_mb, "C", &str_mb);
1067 1067 m_freem(str_mb.chain);
1068 1068 return (SDRC_SUCCESS);
1069 1069 }
1070 1070
1071 1071 int
1072 1072 smb_trans_net_user_getinfo(struct smb_request *sr, struct smb_xa *xa)
1073 1073 {
1074 1074 uint16_t level, max_bytes;
1075 1075 unsigned char *user;
1076 1076 int rc;
1077 1077
1078 1078 rc = smb_mbc_decodef(&xa->req_param_mb, "%sww", sr,
1079 1079 &user,
1080 1080 &level,
1081 1081 &max_bytes);
1082 1082
1083 1083 if (rc != 0)
1084 1084 return (SDRC_NOT_IMPLEMENTED);
1085 1085
1086 1086 (void) smb_mbc_encodef(&xa->rep_param_mb, "www",
1087 1087 NERR_UserNotFound, 0, 0);
1088 1088 return (SDRC_SUCCESS);
1089 1089 }
1090 1090
1091 1091 smb_sdrc_t
1092 1092 smb_trans_net_server_getinfo(struct smb_request *sr, struct smb_xa *xa)
1093 1093 {
1094 1094 uint16_t level, buf_size;
1095 1095 uint16_t avail_data, max_data;
1096 1096 char server_name[16];
1097 1097 struct mbuf_chain str_mb;
1098 1098
1099 1099 if (smb_mbc_decodef(&xa->req_param_mb, "ww", &level, &buf_size) != 0)
1100 1100 return (SDRC_ERROR);
1101 1101
1102 1102 max_data = MBC_MAXBYTES(&xa->rep_data_mb);
1103 1103
1104 1104 MBC_INIT(&str_mb, buf_size);
1105 1105
1106 1106 bzero(server_name, sizeof (server_name));
1107 1107 (void) strncpy(server_name, sr->sr_cfg->skc_hostname,
1108 1108 sizeof (server_name));
1109 1109
1110 1110 /* valid levels are 0 and 1 */
1111 1111 switch (level) {
1112 1112 case 0:
1113 1113 (void) smb_mbc_encodef(&xa->rep_data_mb, "16c", server_name);
1114 1114 break;
1115 1115
1116 1116 case 1:
1117 1117 (void) smb_mbc_encodef(&str_mb, "s",
1118 1118 sr->sr_cfg->skc_system_comment);
1119 1119 (void) smb_mbc_encodef(&xa->rep_data_mb, "16cbbll", server_name,
1120 1120 (uint8_t)sr->sr_cfg->skc_version.sv_major,
1121 1121 (uint8_t)sr->sr_cfg->skc_version.sv_minor,
1122 1122 MY_SERVER_TYPE, max_data - MBC_LENGTH(&str_mb));
1123 1123 break;
1124 1124
1125 1125 default:
1126 1126 (void) smb_mbc_encodef(&xa->rep_param_mb, "www",
1127 1127 ERROR_INVALID_LEVEL, 0, 0);
1128 1128 m_freem(str_mb.chain);
1129 1129 return (SDRC_SUCCESS);
1130 1130 }
1131 1131
1132 1132 avail_data = MBC_LENGTH(&xa->rep_data_mb) + MBC_LENGTH(&str_mb);
1133 1133 (void) smb_mbc_encodef(&xa->rep_param_mb, "www",
1134 1134 NERR_Success, max_data - avail_data, avail_data);
1135 1135 (void) smb_mbc_encodef(&xa->rep_data_mb, "C", &str_mb);
1136 1136 m_freem(str_mb.chain);
1137 1137 return (SDRC_SUCCESS);
1138 1138 }
1139 1139
1140 1140 /*
1141 1141 * 6.4 The NetServerEnum2 RAP Service
1142 1142 *
1143 1143 * The NetServerEnum2 RAP service lists all computers of the specified type
1144 1144 * or types that are visible in the specified domains. It may also
1145 1145 * enumerate domains.
1146 1146 *
1147 1147 * The following definition uses the notation and terminology defined in
1148 1148 * the CIFS Remote Administration Protocol specification, which is required
1149 1149 * in order to make it well-defined. The definition is:
1150 1150 *
1151 1151 * uint16_t NetServerEnum2 (
1152 1152 * uint16_t sLevel,
1153 1153 * RCVBUF pbBuffer,
1154 1154 * RCVBUFLEN cbBuffer,
1155 1155 * ENTCOUNT pcEntriesRead,
1156 1156 * uint16_t *pcTotalAvail,
1157 1157 * uint32_t fServerType,
1158 1158 * char *pszDomain,
1159 1159 * );
1160 1160 *
1161 1161 * where:
1162 1162 *
1163 1163 * sLevel specifies the level of detail (0 or 1) requested.
1164 1164 *
1165 1165 * pbBuffer points to the buffer to receive the returned data. If the
1166 1166 * function is successful, the buffer contains a sequence of
1167 1167 * server_info_x structures, where x is 0 or 1, depending on the
1168 1168 * level of detail requested.
1169 1169 *
1170 1170 * cbBuffer specifies the size, in bytes, of the buffer pointed to by
1171 1171 * the pbBuffer parameter.
1172 1172 *
1173 1173 * pcEntriesRead points to a 16 bit variable that receives a count of
1174 1174 * the number of servers enumerated in the buffer. This count is
1175 1175 * valid only if NetServerEnum2 returns the NERR_Success or
1176 1176 * ERROR_MORE_DATA values.
1177 1177 *
1178 1178 * pcTotal Avail points to a 16 bit variable that receives a count of
1179 1179 * the total number of available entries. This count is valid only if
1180 1180 * NetServerEnum2 returns the NERR_Success or ERROR_MORE_DATA values.
1181 1181 *
1182 1182 * fServerType specifies the type or types of computers to enumerate.
1183 1183 * Computers that match at least one of the specified types are
1184 1184 * returned in the buffer. Possible values are defined in the request
1185 1185 * parameters section.
1186 1186 *
1187 1187 * pszDomain points to a null-terminated string that contains the
1188 1188 * name of the workgroup in which to enumerate computers of the
1189 1189 * specified type or types. If the pszDomain parameter is a null
1190 1190 * string or a null pointer, servers are enumerated for the current
1191 1191 * domain of the computer.
1192 1192 *
1193 1193 * 6.4.1 Transaction Request Parameters section
1194 1194 *
1195 1195 * The Transaction request parameters section in this instance contains:
1196 1196 * . The 16 bit function number for NetServerEnum2 which is 104.
1197 1197 * . The parameter descriptor string which is "WrLehDz".
1198 1198 * . The data descriptor string for the (returned) data which is "B16" for
1199 1199 * level detail 0 or "B16BBDz" for level detail 1.
1200 1200 * . The actual parameters as described by the parameter descriptor
1201 1201 * string.
1202 1202 *
1203 1203 * The parameters are:
1204 1204 * . A 16 bit integer with a value of 0 or 1 (corresponding to the "W" in
1205 1205 * the parameter descriptor string. This represents the level of detail
1206 1206 * the server is expected to return
1207 1207 * . A 16 bit integer that contains the size of the receive buffer.
1208 1208 * . A 32 bit integer that represents the type of servers the function
1209 1209 * should enumerate. The possible values may be any of the following or
1210 1210 * a combination of the following:
1211 1211 *
1212 1212 * SV_TYPE_WORKSTATION 0x00000001 All workstations
1213 1213 * SV_TYPE_SERVER 0x00000002 All servers
1214 1214 * SV_TYPE_SQLSERVER 0x00000004 Any server running with SQL
1215 1215 * server
1216 1216 * SV_TYPE_DOMAIN_CTRL 0x00000008 Primary domain controller
1217 1217 * SV_TYPE_DOMAIN_BAKCTRL 0x00000010 Backup domain controller
1218 1218 * SV_TYPE_TIME_SOURCE 0x00000020 Server running the timesource
1219 1219 * service
1220 1220 * SV_TYPE_AFP 0x00000040 Apple File Protocol servers
1221 1221 * SV_TYPE_NOVELL 0x00000080 Novell servers
1222 1222 * SV_TYPE_DOMAIN_MEMBER 0x00000100 Domain Member
1223 1223 * SV_TYPE_PRINTQ_SERVER 0x00000200 Server sharing print queue
1224 1224 * SV_TYPE_DIALIN_SERVER 0x00000400 Server running dialin service.
1225 1225 * SV_TYPE_XENIX_SERVER 0x00000800 Xenix server
1226 1226 * SV_TYPE_NT 0x00001000 NT server
1227 1227 * SV_TYPE_WFW 0x00002000 Server running Windows for
1228 1228 * Workgroups
1229 1229 * SV_TYPE_SERVER_NT 0x00008000 Windows NT non DC server
1230 1230 * SV_TYPE_POTENTIAL_BROWSER 0x00010000 Server that can run the browser
1231 1231 * service
1232 1232 * SV_TYPE_BACKUP_BROWSER 0x00020000 Backup browser server
1233 1233 * SV_TYPE_MASTER_BROWSER 0x00040000 Master browser server
1234 1234 * SV_TYPE_DOMAIN_MASTER 0x00080000 Domain Master Browser server
1235 1235 * SV_TYPE_LOCAL_LIST_ONLY 0x40000000 Enumerate only entries marked
1236 1236 * "local"
1237 1237 * SV_TYPE_DOMAIN_ENUM 0x80000000 Enumerate Domains. The pszDomain
1238 1238 * parameter must be NULL.
1239 1239 *
1240 1240 * . A null terminated ASCII string representing the pszDomain parameter
1241 1241 * described above
1242 1242 *
1243 1243 * 6.4.2 Transaction Request Data section
1244 1244 *
1245 1245 * There is no data or auxiliary data to send as part of the request.
1246 1246 *
1247 1247 * 6.4.3 Transaction Response Parameters section
1248 1248 *
1249 1249 * The transaction response parameters section consists of:
1250 1250 * . A 16 bit word indicating the return status. The possible values are:
1251 1251 *
1252 1252 * Code Value Description
1253 1253 * NERR_Success 0 No errors encountered
1254 1254 * ERROR_MORE_DATA 234 Additional data is available
1255 1255 * NERR_ServerNotStarted 2114 The RAP service on the remote computer
1256 1256 * is not running
1257 1257 * NERR_BadTransactConfig 2141 The server is not configured for
1258 1258 * transactions, IPC$ is not shared
1259 1259 *
1260 1260 * . A 16 bit "converter" word.
1261 1261 * . A 16 bit number representing the number of entries returned.
1262 1262 * . A 16 bit number representing the total number of available entries.
1263 1263 * If the supplied buffer is large enough, this will equal the number of
1264 1264 * entries returned.
1265 1265 *
1266 1266 * 6.4.4 Transaction Response Data section
1267 1267 *
1268 1268 * The return data section consists of a number of SERVER_INFO_1 structures.
1269 1269 * The number of such structures present is determined by the third entry
1270 1270 * (described above) in the return parameters section.
1271 1271 *
1272 1272 * At level detail 0, the Transaction response data section contains a
1273 1273 * number of SERVER_INFO_0 data structure. The number of such structures is
1274 1274 * equal to the 16 bit number returned by the server in the third parameter
1275 1275 * in the Transaction response parameter section. The SERVER_INFO_0 data
1276 1276 * structure is defined as:
1277 1277 *
1278 1278 * struct SERVER_INFO_0 {
1279 1279 * char sv0_name[16];
1280 1280 * };
1281 1281 *
1282 1282 * where:
1283 1283 *
1284 1284 * sv0_name is a null-terminated string that specifies the name of a
1285 1285 * computer or domain .
1286 1286 *
1287 1287 * At level detail 1, the Transaction response data section contains a
1288 1288 * number of SERVER_INFO_1 data structure. The number of such structures is
1289 1289 * equal to the 16 bit number returned by the server in the third parameter
1290 1290 * in the Transaction response parameter section. The SERVER_INFO_1 data
1291 1291 * structure is defined as:
1292 1292 *
1293 1293 * struct SERVER_INFO_1 {
1294 1294 * char sv1_name[16];
1295 1295 * char sv1_version_major;
1296 1296 * char sv1_version_minor;
1297 1297 * uint32_t sv1_type;
1298 1298 * char *sv1_comment_or_master_browser;
1299 1299 * };
1300 1300 *
1301 1301 * sv1_name contains a null-terminated string that specifies the name
1302 1302 * of a computer, or a domain name if SV_TYPE_DOMAIN_ENUM is set in
1303 1303 * sv1_type.
1304 1304 *
1305 1305 * sv1_version_major whatever was specified in the HostAnnouncement
1306 1306 * or DomainAnnouncement frame with which the entry was registered.
1307 1307 *
1308 1308 * sv1_version_minor whatever was specified in the HostAnnouncement
1309 1309 * or DomainAnnouncement frame with which the entry was registered.
1310 1310 *
1311 1311 * sv1_type specifies the type of software the computer is running.
1312 1312 * The member can be one or a combination of the values defined above
1313 1313 * in the Transaction request parameters section for fServerType.
1314 1314 *
1315 1315 *
1316 1316 * sv1_comment_or_master_browser points to a null-terminated string. If
1317 1317 * the sv1_type indicates that the entry is for a domain, this
1318 1318 * specifies the name of server running the domain master browser;
1319 1319 * otherwise, it specifies a comment describing the server. The comment
1320 1320 * can be a null string or the pointer may be a null pointer.
1321 1321 *
1322 1322 * In case there are multiple SERVER_INFO_1 data structures to
1323 1323 * return, the server may put all these fixed length structures in
1324 1324 * the return buffer, leave some space and then put all the variable
1325 1325 * length data (the actual value of the sv1_comment strings) at the
1326 1326 * end of the buffer.
1327 1327 *
1328 1328 * There is no auxiliary data to receive.
1329 1329 */
1330 1330
1331 1331 int
1332 1332 smb_trans_net_server_enum2(struct smb_request *sr, struct smb_xa *xa)
1333 1333 {
1334 1334 uint16_t opcode, level, max_bytes;
1335 1335 uint32_t server_type;
1336 1336 unsigned char *domain;
1337 1337 struct mbuf_chain str_mb;
1338 1338 char *hostname, *s;
1339 1339 smb_kmod_cfg_t *si;
1340 1340
1341 1341 if (smb_mbc_decodef(&xa->req_param_mb,
1342 1342 "%wsswwls", sr, &opcode, &s, &s,
1343 1343 &level, &max_bytes, &server_type, &domain) != 0)
1344 1344 return (SDRC_NOT_IMPLEMENTED);
1345 1345
1346 1346 si = sr->sr_cfg;
1347 1347
1348 1348 if (smb_strcasecmp(si->skc_nbdomain, (char *)domain, 0) != 0) {
1349 1349 (void) smb_mbc_encodef(&xa->rep_param_mb, "wwww", 0, 0, 0, 0);
1350 1350 return (SDRC_SUCCESS);
1351 1351 }
1352 1352
1353 1353 if ((server_type & MY_SERVER_TYPE) == 0) {
1354 1354 (void) smb_mbc_encodef(&xa->rep_param_mb, "wwww", 0, 0, 0, 0);
1355 1355 return (SDRC_SUCCESS);
1356 1356 }
1357 1357
1358 1358 MBC_INIT(&str_mb, max_bytes);
1359 1359
1360 1360 hostname = si->skc_hostname;
1361 1361
1362 1362 (void) smb_mbc_encodef(&xa->rep_data_mb, "16c", hostname);
1363 1363 if (level == 1) {
1364 1364 (void) smb_mbc_encodef(&xa->rep_data_mb, "bbll",
1365 1365 (uint8_t)sr->sr_cfg->skc_version.sv_major,
1366 1366 (uint8_t)sr->sr_cfg->skc_version.sv_minor,
1367 1367 MY_SERVER_TYPE, MBC_LENGTH(&str_mb));
1368 1368 (void) smb_mbc_encodef(&str_mb, "s", si->skc_system_comment);
1369 1369 }
1370 1370
1371 1371 (void) smb_mbc_encodef(&xa->rep_param_mb, "wwww", 0,
1372 1372 -MBC_LENGTH(&xa->rep_data_mb), 1, 1);
1373 1373 (void) smb_mbc_encodef(&xa->rep_data_mb, "m", str_mb.chain);
1374 1374 return (SDRC_SUCCESS);
1375 1375 }
1376 1376
1377 1377 static boolean_t
1378 1378 is_supported_mailslot(const char *mailslot)
1379 1379 {
1380 1380 static char *mailslots[] = {
1381 1381 PIPE_LANMAN,
1382 1382 MAILSLOT_LANMAN,
1383 1383 MAILSLOT_BROWSE,
1384 1384 MAILSLOT_MSBROWSE
1385 1385 };
1386 1386
1387 1387 int i;
1388 1388
1389 1389 for (i = 0; i < sizeof (mailslots)/sizeof (mailslots[0]); ++i)
1390 1390 if (smb_strcasecmp(mailslot, mailslots[i], 0) == 0)
1391 1391 return (B_TRUE);
1392 1392
1393 1393 return (B_FALSE);
1394 1394 }
1395 1395
1396 1396 /*
1397 1397 * smb_trans_nmpipe
1398 1398 *
1399 1399 * This is used for RPC bind and request transactions.
1400 1400 *
1401 1401 * If the data available from the pipe is larger than the maximum
1402 1402 * data size requested by the client, return as much as requested.
1403 1403 * The residual data remains in the pipe until the client comes back
1404 1404 * with a read request or closes the pipe.
1405 1405 *
1406 1406 * When we read less than what's available, we MUST return the
1407 1407 * status NT_STATUS_BUFFER_OVERFLOW (or ERRDOS/ERROR_MORE_DATA)
1408 1408 */
1409 1409 static smb_sdrc_t
1410 1410 smb_trans_nmpipe(smb_request_t *sr, smb_xa_t *xa)
1411 1411 {
1412 1412 smb_fsctl_t fsctl;
1413 1413 uint32_t status;
1414 1414
1415 1415 smbsr_lookup_file(sr);
1416 1416 if (sr->fid_ofile == NULL) {
1417 1417 smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
1418 1418 ERRDOS, ERRbadfid);
1419 1419 return (SDRC_ERROR);
1420 1420 }
1421 1421
1422 1422 /*
1423 1423 * A little confusing perhaps, but the fsctl "input" is what we
1424 1424 * write to the pipe (from the transaction "send" data), and the
|
↓ open down ↓ |
760 lines elided |
↑ open up ↑ |
1425 1425 * fsctl "output" is what we read from the pipe (and becomes the
1426 1426 * transaction receive data).
1427 1427 */
1428 1428 fsctl.CtlCode = FSCTL_PIPE_TRANSCEIVE;
1429 1429 fsctl.InputCount = xa->smb_tdscnt; /* write count */
1430 1430 fsctl.OutputCount = 0; /* minimum to read from the pipe */
1431 1431 fsctl.MaxOutputResp = xa->smb_mdrcnt; /* max to read */
1432 1432 fsctl.in_mbc = &xa->req_data_mb; /* write from here */
1433 1433 fsctl.out_mbc = &xa->rep_data_mb; /* read into here */
1434 1434
1435 - status = smb_opipe_fsctl(sr, &fsctl);
1435 + status = smb_opipe_transceive(sr, &fsctl);
1436 1436 if (status) {
1437 1437 smbsr_status(sr, status, 0, 0);
1438 1438 if (NT_SC_SEVERITY(status) == NT_STATUS_SEVERITY_ERROR)
1439 1439 return (SDRC_ERROR);
1440 1440 /* Warnings like NT_STATUS_BUFFER_OVERFLOW are OK */
1441 1441 }
1442 1442
1443 1443 return (SDRC_SUCCESS);
1444 1444 }
1445 1445
1446 1446 static smb_sdrc_t
1447 1447 smb_trans_dispatch(smb_request_t *sr, smb_xa_t *xa)
1448 1448 {
1449 1449 int rc, pos;
1450 1450 int total_bytes, n_setup, n_param, n_data;
1451 1451 int param_off, param_pad, data_off, data_pad;
1452 1452 uint16_t opcode;
1453 1453 uint16_t devstate;
1454 1454 char *req_fmt;
1455 1455 char *rep_fmt;
1456 1456
1457 1457 if (xa->smb_suwcnt > 0) {
1458 1458 rc = smb_mbc_decodef(&xa->req_setup_mb, "ww", &opcode,
1459 1459 &sr->smb_fid);
1460 1460 if (rc != 0)
1461 1461 goto trans_err_not_supported;
1462 1462 switch (opcode) {
1463 1463 case TRANS_SET_NMPIPE_STATE:
1464 1464 if ((rc = smb_mbc_decodef(&xa->req_param_mb, "w",
1465 1465 &devstate)) != 0)
1466 1466 goto trans_err_not_supported;
1467 1467
1468 1468 rc = SDRC_SUCCESS;
1469 1469 break;
1470 1470
1471 1471 case TRANS_TRANSACT_NMPIPE:
1472 1472 rc = smb_trans_nmpipe(sr, xa);
1473 1473 break;
1474 1474
1475 1475 case TRANS_WAIT_NMPIPE:
1476 1476 delay(SEC_TO_TICK(1));
1477 1477 rc = SDRC_SUCCESS;
1478 1478 break;
1479 1479
1480 1480 default:
1481 1481 goto trans_err_not_supported;
1482 1482 }
1483 1483 } else {
1484 1484 if (!is_supported_mailslot(xa->xa_pipe_name))
1485 1485 goto trans_err_not_supported;
1486 1486
1487 1487 if ((rc = smb_mbc_decodef(&xa->req_param_mb, "%wss", sr,
1488 1488 &opcode, &req_fmt, &rep_fmt)) != 0)
1489 1489 goto trans_err_not_supported;
1490 1490
1491 1491 switch (opcode) {
1492 1492 case API_WshareEnum:
1493 1493 rc = smb_trans_net_share_enum(sr, xa);
1494 1494 break;
1495 1495
1496 1496 case API_WshareGetInfo:
1497 1497 rc = smb_trans_net_share_getinfo(sr, xa);
1498 1498 break;
1499 1499
1500 1500 case API_WserverGetInfo:
1501 1501 rc = smb_trans_net_server_getinfo(sr, xa);
1502 1502 break;
1503 1503
1504 1504 case API_WUserGetInfo:
1505 1505 rc = smb_trans_net_user_getinfo(sr, xa);
1506 1506 break;
1507 1507
1508 1508 case API_WWkstaGetInfo:
1509 1509 rc = smb_trans_net_workstation_getinfo(sr, xa);
1510 1510 break;
1511 1511
1512 1512 case API_NetServerEnum2:
1513 1513 rc = smb_trans_net_server_enum2(sr, xa);
1514 1514 break;
1515 1515
1516 1516 default:
1517 1517 goto trans_err_not_supported;
1518 1518 }
1519 1519 }
1520 1520
1521 1521 switch (rc) {
1522 1522 case SDRC_SUCCESS:
1523 1523 break;
1524 1524
1525 1525 case SDRC_DROP_VC:
1526 1526 case SDRC_NO_REPLY:
1527 1527 case SDRC_ERROR:
1528 1528 return (rc);
1529 1529
1530 1530 case SDRC_NOT_IMPLEMENTED:
1531 1531 goto trans_err_not_supported;
1532 1532
1533 1533 default:
1534 1534 break;
1535 1535 }
1536 1536
1537 1537 n_setup = MBC_LENGTH(&xa->rep_setup_mb);
1538 1538 n_param = MBC_LENGTH(&xa->rep_param_mb);
1539 1539 n_data = MBC_LENGTH(&xa->rep_data_mb);
1540 1540
1541 1541 if (xa->smb_msrcnt < n_setup ||
1542 1542 xa->smb_mprcnt < n_param ||
1543 1543 xa->smb_mdrcnt < n_data) {
1544 1544 goto trans_err_too_small;
1545 1545 }
1546 1546
1547 1547 /* neato, blast it over there */
1548 1548
1549 1549 n_setup = (n_setup + 1) / 2; /* Convert to setup words */
1550 1550 param_pad = 1; /* always one */
1551 1551 param_off = param_pad + 32 + 21 + (n_setup << 1) + 2;
1552 1552 data_pad = (param_off + n_param) & 1; /* Pad to short */
1553 1553 /* Param off from hdr start */
1554 1554 data_off = param_off + n_param + data_pad;
1555 1555 total_bytes = param_pad + n_param + data_pad + n_data;
1556 1556
1557 1557 rc = smbsr_encode_result(sr, 10+n_setup, total_bytes,
1558 1558 "bww2.wwwwwwb.Cw#.C#.C",
1559 1559 10 + n_setup, /* wct */
1560 1560 n_param, /* Total Parameter Bytes */
1561 1561 n_data, /* Total Data Bytes */
1562 1562 n_param, /* Total Parameter Bytes this buffer */
1563 1563 param_off, /* Param offset from header start */
1564 1564 0, /* Param displacement */
1565 1565 n_data, /* Total Data Bytes this buffer */
1566 1566 data_off, /* Data offset from header start */
1567 1567 0, /* Data displacement */
1568 1568 n_setup, /* suwcnt */
1569 1569 &xa->rep_setup_mb, /* setup[] */
1570 1570 total_bytes, /* Total data bytes */
1571 1571 param_pad,
1572 1572 &xa->rep_param_mb,
1573 1573 data_pad,
1574 1574 &xa->rep_data_mb);
1575 1575 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
1576 1576
1577 1577 trans_err_too_small:
1578 1578 rc = NERR_BufTooSmall;
1579 1579 goto trans_err;
1580 1580
1581 1581 trans_err_not_supported:
1582 1582 rc = ERROR_NOT_SUPPORTED;
1583 1583 goto trans_err;
1584 1584
1585 1585 trans_err:
1586 1586 pos = MBC_LENGTH(&sr->reply) + 23;
1587 1587 rc = smbsr_encode_result(sr, 10, 4, "bww2.wwwwwwb.www",
1588 1588 10, /* wct */
1589 1589 4, 0, /* tpscnt tdscnt */
1590 1590 4, pos, 0, /* pscnt psoff psdisp */
1591 1591 0, 0, 0, /* dscnt dsoff dsdisp */
1592 1592 0, /* suwcnt */
1593 1593 4, /* bcc */
1594 1594 rc,
1595 1595 0); /* converter word? */
1596 1596 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
1597 1597 }
1598 1598
1599 1599 static smb_sdrc_t
1600 1600 smb_trans2_dispatch(smb_request_t *sr, smb_xa_t *xa)
1601 1601 {
1602 1602 int rc, pos;
1603 1603 int total_bytes, n_setup, n_param, n_data;
1604 1604 int param_off, param_pad, data_off;
1605 1605 uint16_t data_pad;
1606 1606 uint16_t opcode;
1607 1607 uint16_t nt_unknown_secret = 0x0100;
1608 1608 char *fmt;
1609 1609
1610 1610 n_data = xa->smb_mdrcnt;
1611 1611
1612 1612 if (smb_mbc_decodef(&xa->req_setup_mb, "w", &opcode) != 0)
1613 1613 goto trans_err_not_supported;
1614 1614
1615 1615 /*
1616 1616 * Save this for /proc to read later.
1617 1617 */
1618 1618 xa->smb_func = opcode;
1619 1619
1620 1620 /* for now, only respond to the */
1621 1621 switch (opcode) {
1622 1622 case TRANS2_OPEN2:
1623 1623 rc = smb_com_trans2_open2(sr, xa);
1624 1624 break;
1625 1625
1626 1626 case TRANS2_CREATE_DIRECTORY:
1627 1627 rc = smb_com_trans2_create_directory(sr, xa);
1628 1628 break;
1629 1629
1630 1630 case TRANS2_FIND_FIRST2:
1631 1631 /*
1632 1632 * Should have enough room to send the response
1633 1633 * data back to client.
1634 1634 */
1635 1635 if (n_data == 0) {
1636 1636 smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
1637 1637 ERRDOS, ERROR_BAD_LENGTH);
1638 1638 return (SDRC_ERROR);
1639 1639 }
1640 1640 rc = smb_com_trans2_find_first2(sr, xa);
1641 1641 break;
1642 1642
1643 1643 case TRANS2_FIND_NEXT2:
1644 1644 /*
1645 1645 * Should have enough room to send the response
1646 1646 * data back to client.
1647 1647 */
1648 1648 if (n_data == 0) {
1649 1649 smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
1650 1650 ERRDOS, ERROR_BAD_LENGTH);
1651 1651 return (SDRC_ERROR);
1652 1652 }
1653 1653 rc = smb_com_trans2_find_next2(sr, xa);
1654 1654 break;
1655 1655
1656 1656 case TRANS2_QUERY_FS_INFORMATION:
1657 1657 /*
1658 1658 * Should have enough room to send the response
1659 1659 * data back to client.
1660 1660 */
1661 1661 if (n_data == 0) {
1662 1662 smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
1663 1663 ERRDOS, ERROR_BAD_LENGTH);
1664 1664 return (SDRC_ERROR);
1665 1665 }
1666 1666 rc = smb_com_trans2_query_fs_information(sr, xa);
1667 1667 break;
1668 1668
1669 1669 case TRANS2_SET_FS_INFORMATION:
1670 1670 rc = smb_com_trans2_set_fs_information(sr, xa);
1671 1671 break;
1672 1672
1673 1673 case TRANS2_QUERY_PATH_INFORMATION:
1674 1674 /*
1675 1675 * Should have enough room to send the response
1676 1676 * data back to client.
1677 1677 */
1678 1678 if (n_data == 0) {
1679 1679 smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
1680 1680 ERRDOS, ERROR_BAD_LENGTH);
1681 1681 return (SDRC_ERROR);
1682 1682 }
1683 1683 rc = smb_com_trans2_query_path_information(sr, xa);
1684 1684 break;
1685 1685
1686 1686 case TRANS2_QUERY_FILE_INFORMATION:
1687 1687 /*
1688 1688 * Should have enough room to send the response
1689 1689 * data back to client.
1690 1690 */
1691 1691 if (n_data == 0) {
1692 1692 smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
1693 1693 ERRDOS, ERROR_BAD_LENGTH);
1694 1694 return (SDRC_ERROR);
1695 1695 }
1696 1696 rc = smb_com_trans2_query_file_information(sr, xa);
1697 1697 break;
1698 1698
1699 1699 case TRANS2_SET_PATH_INFORMATION:
1700 1700 rc = smb_com_trans2_set_path_information(sr, xa);
1701 1701 break;
1702 1702
1703 1703 case TRANS2_SET_FILE_INFORMATION:
1704 1704 rc = smb_com_trans2_set_file_information(sr, xa);
1705 1705 break;
1706 1706
1707 1707 case TRANS2_GET_DFS_REFERRAL:
1708 1708 rc = smb_com_trans2_get_dfs_referral(sr, xa);
1709 1709 break;
1710 1710
1711 1711 default:
1712 1712 (void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0);
1713 1713 goto trans_err_not_supported;
1714 1714 }
1715 1715
1716 1716 switch (rc) {
1717 1717 case SDRC_SUCCESS:
1718 1718 break;
1719 1719
1720 1720 case SDRC_DROP_VC:
1721 1721 case SDRC_NO_REPLY:
1722 1722 case SDRC_ERROR:
1723 1723 return (rc);
1724 1724
1725 1725 case SDRC_NOT_IMPLEMENTED:
1726 1726 goto trans_err_not_supported;
1727 1727
1728 1728 default:
1729 1729 break;
1730 1730 }
1731 1731
1732 1732 n_setup = MBC_LENGTH(&xa->rep_setup_mb);
1733 1733 n_param = MBC_LENGTH(&xa->rep_param_mb);
1734 1734 n_data = MBC_LENGTH(&xa->rep_data_mb);
1735 1735
1736 1736 if (xa->smb_msrcnt < n_setup ||
1737 1737 xa->smb_mprcnt < n_param ||
1738 1738 xa->smb_mdrcnt < n_data) {
1739 1739 goto trans_err_too_small;
1740 1740 }
1741 1741
1742 1742 /* neato, blast it over there */
1743 1743
1744 1744 n_setup = (n_setup + 1) / 2; /* Conver to setup words */
1745 1745 param_pad = 1; /* must be one */
1746 1746 param_off = param_pad + 32 + 21 + (n_setup << 1) + 2;
1747 1747
1748 1748 /*
1749 1749 * Including the nt_unknown_secret value persuades netmon to
1750 1750 * display the correct data format for QueryPathInfo and
1751 1751 * QueryFileInfo.
1752 1752 */
1753 1753 if (opcode == TRANS2_QUERY_FILE_INFORMATION ||
1754 1754 opcode == TRANS2_QUERY_PATH_INFORMATION) {
1755 1755 data_pad = sizeof (uint16_t);
|
↓ open down ↓ |
310 lines elided |
↑ open up ↑ |
1756 1756 data_off = param_off + n_param + data_pad;
1757 1757 fmt = "bww2.wwwwwwb.Cw#.CwC";
1758 1758 nt_unknown_secret = 0x0100;
1759 1759 }
1760 1760 else
1761 1761 {
1762 1762 data_pad = (param_off + n_param) & 1; /* Pad to short */
1763 1763 /* Param off from hdr start */
1764 1764 data_off = param_off + n_param + data_pad;
1765 1765 fmt = "bww2.wwwwwwb.Cw#.C#.C";
1766 - nt_unknown_secret = data_pad;
1766 + nt_unknown_secret = (uint16_t)data_pad;
1767 1767 }
1768 1768
1769 1769 total_bytes = param_pad + n_param + data_pad + n_data;
1770 1770
1771 1771 rc = smbsr_encode_result(sr, 10+n_setup, total_bytes,
1772 1772 fmt,
1773 1773 10 + n_setup, /* wct */
1774 1774 n_param, /* Total Parameter Bytes */
1775 1775 n_data /* + data_pad */, /* Total Data Bytes */
1776 1776 n_param, /* Total Parameter Bytes this buffer */
1777 1777 param_off, /* Param offset from header start */
1778 1778 0, /* Param displacement */
1779 1779 n_data /* + data_pad */, /* Total Data Bytes this buffer */
1780 1780 data_off, /* Data offset from header start */
1781 1781 0, /* Data displacement */
1782 1782 n_setup, /* suwcnt */
1783 1783 &xa->rep_setup_mb, /* setup[] */
1784 1784 total_bytes, /* Total data bytes */
1785 1785 param_pad,
1786 1786 &xa->rep_param_mb,
1787 1787 nt_unknown_secret,
1788 1788 &xa->rep_data_mb);
1789 1789 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
1790 1790
1791 1791 trans_err_too_small:
1792 1792 rc = NERR_BufTooSmall;
1793 1793 goto trans_err;
1794 1794
1795 1795 trans_err_not_supported:
1796 1796 rc = ERROR_NOT_SUPPORTED;
1797 1797 goto trans_err;
1798 1798
1799 1799 trans_err:
1800 1800 pos = MBC_LENGTH(&sr->reply) + 23;
1801 1801 rc = smbsr_encode_result(sr, 10, 4, "bww2.wwwwwwb.www",
1802 1802 10, /* wct */
1803 1803 4, 0, /* tpscnt tdscnt */
1804 1804 4, pos, 0, /* pscnt psoff psdisp */
1805 1805 0, 0, 0, /* dscnt dsoff dsdisp */
1806 1806 0, /* suwcnt */
1807 1807 4, /* bcc */
1808 1808 rc,
1809 1809 0); /* converter word? */
1810 1810 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
1811 1811 }
1812 1812
1813 1813 static uint32_t smb_xa_max_setup_count = 200;
1814 1814 static uint32_t smb_xa_max_param_count = 32 * 1024;
1815 1815 static uint32_t smb_xa_max_data_count = 64 * 1024;
1816 1816
1817 1817 smb_xa_t *
1818 1818 smb_xa_create(
1819 1819 smb_session_t *session,
1820 1820 smb_request_t *sr,
1821 1821 uint32_t total_parameter_count,
1822 1822 uint32_t total_data_count,
1823 1823 uint32_t max_parameter_count,
1824 1824 uint32_t max_data_count,
1825 1825 uint32_t max_setup_count,
1826 1826 uint32_t setup_word_count)
1827 1827 {
1828 1828 smb_xa_t *xa, *nxa;
1829 1829 smb_llist_t *xlist;
1830 1830
1831 1831 /*
1832 1832 * Sanity check what the client says it will send.
1833 1833 * Caller handles NULL return as ERRnoroom.
1834 1834 */
1835 1835 if (setup_word_count > smb_xa_max_setup_count)
1836 1836 return (NULL);
1837 1837 if (total_parameter_count > smb_xa_max_param_count)
1838 1838 return (NULL);
1839 1839 if (total_data_count > smb_xa_max_data_count)
1840 1840 return (NULL);
1841 1841
1842 1842 /*
1843 1843 * Limit what the client asks us to allocate for
1844 1844 * returned setup, params, data.
1845 1845 */
1846 1846 if (max_setup_count > smb_xa_max_setup_count)
1847 1847 max_setup_count = smb_xa_max_setup_count;
1848 1848 if (max_parameter_count > smb_xa_max_param_count)
1849 1849 max_parameter_count = smb_xa_max_param_count;
1850 1850 if (max_data_count > smb_xa_max_data_count)
1851 1851 max_data_count = smb_xa_max_data_count;
1852 1852
1853 1853 xa = kmem_zalloc(sizeof (smb_xa_t), KM_SLEEP);
1854 1854 xa->xa_refcnt = 1;
1855 1855 xa->smb_com = sr->smb_com;
1856 1856 xa->smb_flg = sr->smb_flg;
1857 1857 xa->smb_flg2 = sr->smb_flg2;
1858 1858 xa->smb_tid = sr->smb_tid;
1859 1859 xa->smb_pid = sr->smb_pid;
1860 1860 xa->smb_uid = sr->smb_uid;
1861 1861 xa->xa_smb_mid = sr->smb_mid;
1862 1862 xa->xa_smb_fid = 0xFFFF;
1863 1863 xa->reply_seqnum = sr->reply_seqnum;
1864 1864 xa->smb_tpscnt = total_parameter_count;
1865 1865 xa->smb_tdscnt = total_data_count;
1866 1866 xa->smb_mprcnt = max_parameter_count;
1867 1867 xa->smb_mdrcnt = max_data_count;
1868 1868 xa->smb_msrcnt = max_setup_count;
1869 1869 xa->smb_suwcnt = setup_word_count;
1870 1870 xa->xa_session = session;
1871 1871 xa->xa_magic = SMB_XA_MAGIC;
1872 1872
1873 1873 /* request parts */
1874 1874 xa->req_setup_mb.max_bytes = setup_word_count * 2;
1875 1875 xa->req_param_mb.max_bytes = total_parameter_count;
1876 1876 xa->req_data_mb.max_bytes = total_data_count;
1877 1877
1878 1878 /* reply parts */
1879 1879 xa->rep_setup_mb.max_bytes = max_setup_count * 2;
1880 1880 xa->rep_param_mb.max_bytes = max_parameter_count;
1881 1881 xa->rep_data_mb.max_bytes = max_data_count;
1882 1882
1883 1883 /*
1884 1884 * The new xa structure is checked against the current list to see
1885 1885 * if it exists already.
1886 1886 */
1887 1887 xlist = &session->s_xa_list;
1888 1888 smb_llist_enter(xlist, RW_WRITER);
1889 1889 nxa = smb_llist_head(xlist);
1890 1890 while (nxa) {
1891 1891 ASSERT(nxa->xa_magic == SMB_XA_MAGIC);
1892 1892 if (nxa->xa_smb_mid == xa->xa_smb_mid &&
1893 1893 nxa->smb_pid == xa->smb_pid &&
1894 1894 !SMB_XA_CLOSED(nxa) &&
1895 1895 !(nxa->xa_flags & SMB_XA_FLAG_COMPLETE)) {
1896 1896 smb_llist_exit(xlist);
1897 1897 kmem_free(xa, sizeof (smb_xa_t));
1898 1898 return (NULL);
1899 1899 }
1900 1900 nxa = smb_llist_next(xlist, nxa);
1901 1901 }
1902 1902 smb_llist_insert_tail(xlist, xa);
1903 1903 smb_llist_exit(xlist);
1904 1904 return (xa);
1905 1905 }
1906 1906
1907 1907 void
1908 1908 smb_xa_delete(smb_xa_t *xa)
1909 1909 {
1910 1910 ASSERT(xa->xa_refcnt == 0);
1911 1911 ASSERT(SMB_XA_CLOSED(xa));
1912 1912
1913 1913 if (xa->xa_pipe_name)
1914 1914 smb_mem_free(xa->xa_pipe_name);
1915 1915
1916 1916 /* request parts */
1917 1917 if (xa->req_setup_mb.chain != NULL)
1918 1918 m_freem(xa->req_setup_mb.chain);
1919 1919 if (xa->req_param_mb.chain != NULL)
1920 1920 m_freem(xa->req_param_mb.chain);
1921 1921 if (xa->req_data_mb.chain != NULL)
1922 1922 m_freem(xa->req_data_mb.chain);
1923 1923
1924 1924 /* reply parts */
1925 1925 if (xa->rep_setup_mb.chain != NULL)
1926 1926 m_freem(xa->rep_setup_mb.chain);
1927 1927 if (xa->rep_param_mb.chain != NULL)
1928 1928 m_freem(xa->rep_param_mb.chain);
1929 1929 if (xa->rep_data_mb.chain != NULL)
1930 1930 m_freem(xa->rep_data_mb.chain);
1931 1931
1932 1932 xa->xa_magic = (uint32_t)~SMB_XA_MAGIC;
1933 1933 kmem_free(xa, sizeof (smb_xa_t));
1934 1934 }
1935 1935
1936 1936 smb_xa_t *
1937 1937 smb_xa_hold(smb_xa_t *xa)
1938 1938 {
1939 1939 mutex_enter(&xa->xa_mutex);
1940 1940 xa->xa_refcnt++;
1941 1941 ASSERT(xa->xa_refcnt);
1942 1942 mutex_exit(&xa->xa_mutex);
1943 1943 return (xa);
1944 1944 }
1945 1945
1946 1946 void
1947 1947 smb_xa_rele(smb_session_t *session, smb_xa_t *xa)
1948 1948 {
1949 1949 mutex_enter(&xa->xa_mutex);
1950 1950 ASSERT(xa->xa_refcnt);
1951 1951 xa->xa_refcnt--;
1952 1952 if (SMB_XA_CLOSED(xa) && (xa->xa_refcnt == 0)) {
1953 1953 mutex_exit(&xa->xa_mutex);
1954 1954 smb_llist_enter(&session->s_xa_list, RW_WRITER);
1955 1955 smb_llist_remove(&session->s_xa_list, xa);
1956 1956 smb_llist_exit(&session->s_xa_list);
1957 1957 smb_xa_delete(xa);
1958 1958 return;
1959 1959 }
1960 1960 mutex_exit(&xa->xa_mutex);
1961 1961 }
1962 1962
1963 1963 int
1964 1964 smb_xa_open(smb_xa_t *xa)
1965 1965 {
1966 1966 int rc;
1967 1967
1968 1968 mutex_enter(&xa->xa_mutex);
1969 1969
1970 1970 ASSERT((xa->xa_flags & SMB_XA_FLAG_OPEN) == 0);
1971 1971
1972 1972 if ((xa->xa_flags & SMB_XA_FLAG_CLOSE) == 0) {
1973 1973 xa->xa_flags |= SMB_XA_FLAG_OPEN;
1974 1974 rc = 0;
1975 1975 } else {
1976 1976 rc = ERROR_INVALID_HANDLE;
1977 1977 }
1978 1978
1979 1979 mutex_exit(&xa->xa_mutex);
1980 1980
1981 1981 return (rc);
1982 1982 }
1983 1983
1984 1984 void
1985 1985 smb_xa_close(smb_xa_t *xa)
1986 1986 {
1987 1987 mutex_enter(&xa->xa_mutex);
1988 1988 xa->xa_flags |= SMB_XA_FLAG_CLOSE;
1989 1989 xa->xa_flags &= ~SMB_XA_FLAG_OPEN;
1990 1990
1991 1991 if (xa->xa_refcnt == 0) {
1992 1992 mutex_exit(&xa->xa_mutex);
1993 1993 smb_llist_enter(&xa->xa_session->s_xa_list, RW_WRITER);
1994 1994 smb_llist_remove(&xa->xa_session->s_xa_list, xa);
1995 1995 smb_llist_exit(&xa->xa_session->s_xa_list);
1996 1996 smb_xa_delete(xa);
1997 1997 return;
1998 1998 }
1999 1999
2000 2000 mutex_exit(&xa->xa_mutex);
2001 2001 }
2002 2002
2003 2003 int
2004 2004 smb_xa_complete(smb_xa_t *xa)
2005 2005 {
2006 2006 int rc;
2007 2007
2008 2008 mutex_enter(&xa->xa_mutex);
2009 2009 if (xa->xa_flags & (SMB_XA_FLAG_COMPLETE | SMB_XA_FLAG_CLOSE)) {
2010 2010 rc = 0; /* error ("not complete") */
2011 2011 } else {
2012 2012 rc = 1; /* Yes, "complete" */
2013 2013 xa->xa_flags |= SMB_XA_FLAG_COMPLETE;
2014 2014
2015 2015 /*
2016 2016 * During trans & trans-secondary processing,
2017 2017 * we copied the request data into these.
2018 2018 * Now we want to parse them, so we need to
2019 2019 * move the "finger" back to the beginning.
2020 2020 */
2021 2021 xa->req_setup_mb.chain_offset = 0;
2022 2022 xa->req_param_mb.chain_offset = 0;
2023 2023 xa->req_data_mb.chain_offset = 0;
2024 2024 }
2025 2025
2026 2026 mutex_exit(&xa->xa_mutex);
2027 2027 return (rc);
2028 2028 }
2029 2029
2030 2030 smb_xa_t *
2031 2031 smb_xa_find(
2032 2032 smb_session_t *session,
2033 2033 uint32_t pid,
2034 2034 uint16_t mid)
2035 2035 {
2036 2036 smb_xa_t *xa;
2037 2037 smb_llist_t *xlist;
2038 2038
2039 2039 xlist = &session->s_xa_list;
2040 2040 smb_llist_enter(xlist, RW_READER);
2041 2041 xa = smb_llist_head(xlist);
2042 2042 while (xa) {
2043 2043 mutex_enter(&xa->xa_mutex);
2044 2044 if (xa->xa_smb_mid == mid &&
2045 2045 xa->smb_pid == pid &&
2046 2046 !SMB_XA_CLOSED(xa) &&
2047 2047 !(xa->xa_flags & SMB_XA_FLAG_COMPLETE)) {
2048 2048 xa->xa_refcnt++;
2049 2049 ASSERT(xa->xa_refcnt);
2050 2050 mutex_exit(&xa->xa_mutex);
2051 2051 break;
2052 2052 }
2053 2053 mutex_exit(&xa->xa_mutex);
2054 2054 xa = smb_llist_next(xlist, xa);
2055 2055 }
2056 2056 smb_llist_exit(xlist);
2057 2057 return (xa);
2058 2058 }
|
↓ open down ↓ |
282 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX