4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 #include <smbsrv/smb_kproto.h>
28 #include <smbsrv/smb_fsops.h>
29 #include <smbsrv/smb_share.h>
30 #include <smbsrv/string.h>
31 #include <smbsrv/nmpipes.h>
32 #include <smbsrv/mailslot.h>
33 #include <smbsrv/winioctl.h>
34
35 /*
36 * count of bytes in server response packet
37 * except parameters and data. Note that setup
38 * word count is zero.
39 */
40 #define RESP_HEADER_LEN 24
41
42 /*
43 * We started by using common functions for transaction/transaction2
44 * and transaction_secondary/transaction2_secondary because they
45 * are respectively so similar. However, it turned out to be a bad
46 * idea because of quirky differences. Be sure if you modify one
47 * of these four functions to check and see if the modification should
48 * be applied to its peer.
49 */
50
51 static int smb_trans_ready(smb_xa_t *);
52 static smb_sdrc_t smb_trans_dispatch(smb_request_t *, smb_xa_t *);
53 static smb_sdrc_t smb_trans2_dispatch(smb_request_t *, smb_xa_t *);
54
55 smb_sdrc_t
56 smb_pre_transaction(smb_request_t *sr)
57 {
58 DTRACE_SMB_1(op__Transaction__start, smb_request_t *, sr);
59 return (SDRC_SUCCESS);
60 }
61
62 void
63 smb_post_transaction(smb_request_t *sr)
64 {
65 DTRACE_SMB_1(op__Transaction__done, smb_request_t *, sr);
66 }
67
68 smb_sdrc_t
69 smb_com_transaction(smb_request_t *sr)
70 {
71 int rc;
72 unsigned char msrcnt, suwcnt;
73 uint16_t tpscnt, tdscnt, mprcnt, mdrcnt, flags;
74 uint16_t pscnt, psoff, dscnt, dsoff;
75 uint32_t timeo;
76 struct smb_xa *xa;
77 char *stn;
78 int ready;
79
80 if (!STYPE_ISIPC(sr->tid_tree->t_res_type)) {
81 smbsr_error(sr, 0, ERRDOS, ERRnoaccess);
82 return (SDRC_ERROR);
83 }
84
85 rc = smbsr_decode_vwv(sr, SMB_TRANSHDR_ED_FMT,
139 }
140 sr->r_xa = xa;
141
142 if (!ready) {
143 rc = smbsr_encode_empty_result(sr);
144 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
145 }
146
147 if (!smb_xa_complete(xa)) {
148 smb_xa_close(xa);
149 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
150 return (SDRC_ERROR);
151 }
152
153 return (smb_trans_dispatch(sr, xa));
154 }
155
156 smb_sdrc_t
157 smb_pre_transaction_secondary(smb_request_t *sr)
158 {
159 DTRACE_SMB_1(op__TransactionSecondary__start, smb_request_t *, sr);
160 return (SDRC_SUCCESS);
161 }
162
163 void
164 smb_post_transaction_secondary(smb_request_t *sr)
165 {
166 DTRACE_SMB_1(op__TransactionSecondary__done, smb_request_t *, sr);
167 }
168
169 smb_sdrc_t
170 smb_com_transaction_secondary(smb_request_t *sr)
171 {
172 uint16_t tpscnt, tdscnt, pscnt, psdisp;
173 uint16_t dscnt, dsoff, dsdisp, psoff;
174 smb_xa_t *xa;
175 int rc;
176
177 if ((xa = smbsr_lookup_xa(sr)) == 0) {
178 smbsr_error(sr, 0, ERRSRV, ERRsrverror);
179 return (SDRC_ERROR);
180 }
181
182 if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
183 if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
184 smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
185 ERRDOS, ERRnoaccess);
186 return (SDRC_ERROR);
237 if (smb_mbc_copy(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
238 mutex_exit(&xa->xa_mutex);
239 smb_xa_close(xa);
240 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
241 return (SDRC_ERROR);
242 }
243 mutex_exit(&xa->xa_mutex);
244
245 if (!smb_trans_ready(xa))
246 return (SDRC_NO_REPLY);
247
248 if (!smb_xa_complete(xa))
249 return (SDRC_NO_REPLY);
250
251 return (smb_trans_dispatch(sr, xa));
252 }
253
254 smb_sdrc_t
255 smb_pre_ioctl(smb_request_t *sr)
256 {
257 DTRACE_SMB_1(op__Ioctl__start, smb_request_t *, sr);
258 return (SDRC_SUCCESS);
259 }
260
261 void
262 smb_post_ioctl(smb_request_t *sr)
263 {
264 DTRACE_SMB_1(op__Ioctl__done, smb_request_t *, sr);
265 }
266
267 smb_sdrc_t
268 smb_com_ioctl(smb_request_t *sr)
269 {
270 uint16_t fid, category, function, tpscnt, tdscnt, mprcnt;
271 uint16_t mdrcnt, pscnt, pdoff, dscnt, dsoff;
272 uint32_t timeout;
273 int rc;
274
275 rc = smbsr_decode_vwv(sr, "wwwwwwwl2.wwww", &fid, &category, &function,
276 &tpscnt, &tdscnt, &mprcnt, &mdrcnt, &timeout, &pscnt,
277 &pdoff, &dscnt, &dsoff);
278
279 if (rc != 0)
280 return (SDRC_ERROR);
281
282 return (SDRC_NOT_IMPLEMENTED);
283 }
284
285 smb_sdrc_t
286 smb_pre_transaction2(smb_request_t *sr)
287 {
288 DTRACE_SMB_1(op__Transaction2__start, smb_request_t *, sr);
289 return (SDRC_SUCCESS);
290 }
291
292 void
293 smb_post_transaction2(smb_request_t *sr)
294 {
295 DTRACE_SMB_1(op__Transaction2__done, smb_request_t *, sr);
296 }
297
298 smb_sdrc_t
299 smb_com_transaction2(struct smb_request *sr)
300 {
301 unsigned char msrcnt, suwcnt;
302 uint16_t tpscnt, tdscnt, mprcnt, mdrcnt, flags;
303 uint16_t pscnt, psoff, dscnt, dsoff;
304 uint32_t timeo;
305 smb_xa_t *xa;
306 int ready;
307 int rc;
308
309 rc = smbsr_decode_vwv(sr, SMB_TRANSHDR_ED_FMT, &tpscnt, &tdscnt,
310 &mprcnt, &mdrcnt, &msrcnt, &flags, &timeo, &pscnt, &psoff, &dscnt,
311 &dsoff, &suwcnt);
312
313 if (rc != 0)
314 return (SDRC_ERROR);
315
351 }
352 sr->r_xa = xa;
353
354 if (!ready) {
355 rc = smbsr_encode_empty_result(sr);
356 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
357 }
358
359 if (!smb_xa_complete(xa)) {
360 smb_xa_close(xa);
361 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
362 return (SDRC_ERROR);
363 }
364
365 return (smb_trans2_dispatch(sr, xa));
366 }
367
368 smb_sdrc_t
369 smb_pre_transaction2_secondary(smb_request_t *sr)
370 {
371 DTRACE_SMB_1(op__Transaction2Secondary__start, smb_request_t *, sr);
372 return (SDRC_SUCCESS);
373 }
374
375 void
376 smb_post_transaction2_secondary(smb_request_t *sr)
377 {
378 DTRACE_SMB_1(op__Transaction2Secondary__done, smb_request_t *, sr);
379 }
380
381 smb_sdrc_t
382 smb_com_transaction2_secondary(smb_request_t *sr)
383 {
384 uint16_t tpscnt, tdscnt, fid;
385 uint16_t pscnt, psoff, psdisp, dscnt, dsoff, dsdisp;
386 smb_xa_t *xa;
387 int rc;
388
389 if ((xa = smbsr_lookup_xa(sr)) == 0) {
390 smbsr_error(sr, 0, ERRSRV, ERRsrverror);
391 return (SDRC_ERROR);
392 }
393
394 if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
395 if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
396 smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
397 ERRDOS, ERRnoaccess);
398 return (SDRC_ERROR);
541 n_data, /* Total Data Bytes */
542 n_param, /* Total Parameter Bytes this buffer */
543 param_off, /* Param offset from header start */
544 0, /* Param displacement */
545 n_data, /* Total Data Bytes this buffer */
546 data_off, /* Data offset from header start */
547 0, /* Data displacement */
548 n_setup, /* suwcnt */
549 &xa->rep_setup_mb, /* setup[] */
550 total_bytes, /* Total data bytes */
551 param_pad,
552 &xa->rep_param_mb,
553 data_pad,
554 &xa->rep_data_mb);
555 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
556 }
557
558 smb_sdrc_t
559 smb_pre_nt_transact(smb_request_t *sr)
560 {
561 DTRACE_SMB_1(op__NtTransact__start, smb_request_t *, sr);
562 return (SDRC_SUCCESS);
563 }
564
565 void
566 smb_post_nt_transact(smb_request_t *sr)
567 {
568 DTRACE_SMB_1(op__NtTransact__done, smb_request_t *, sr);
569 }
570
571 smb_sdrc_t
572 smb_com_nt_transact(struct smb_request *sr)
573 {
574 uint16_t Function;
575 unsigned char MaxSetupCount, SetupCount;
576 uint32_t TotalParameterCount, TotalDataCount;
577 uint32_t MaxParameterCount, MaxDataCount, pscnt;
578 uint32_t psoff, dscnt, dsoff;
579 smb_xa_t *xa;
580 int ready;
581 int rc;
582
583 rc = smbsr_decode_vwv(sr, SMB_NT_TRANSHDR_ED_FMT, &MaxSetupCount,
584 &TotalParameterCount, &TotalDataCount, &MaxParameterCount,
585 &MaxDataCount, &pscnt, &psoff, &dscnt,
586 &dsoff, &SetupCount, &Function);
587
588 if (rc != 0)
627 }
628 sr->r_xa = xa;
629
630 if (!ready) {
631 rc = smbsr_encode_empty_result(sr);
632 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
633 }
634
635 if (!smb_xa_complete(xa)) {
636 smb_xa_close(xa);
637 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
638 return (SDRC_ERROR);
639 }
640
641 return (smb_nt_trans_dispatch(sr, xa));
642 }
643
644 smb_sdrc_t
645 smb_pre_nt_transact_secondary(smb_request_t *sr)
646 {
647 DTRACE_SMB_1(op__NtTransactSecondary__start, smb_request_t *, sr);
648 return (SDRC_SUCCESS);
649 }
650
651 void
652 smb_post_nt_transact_secondary(smb_request_t *sr)
653 {
654 DTRACE_SMB_1(op__NtTransactSecondary__done, smb_request_t *, sr);
655 }
656
657 smb_sdrc_t
658 smb_com_nt_transact_secondary(struct smb_request *sr)
659 {
660 uint16_t tpscnt, tdscnt, fid;
661 uint16_t pscnt, psoff, psdisp, dscnt, dsoff, dsdisp;
662 smb_xa_t *xa;
663 int rc;
664
665 if ((xa = smbsr_lookup_xa(sr)) == 0) {
666 smbsr_error(sr, 0, ERRSRV, ERRsrverror);
667 return (SDRC_ERROR);
668 }
669
670 if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
671 if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
672 smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
673 ERRDOS, ERRnoaccess);
674 return (SDRC_ERROR);
1415 smbsr_lookup_file(sr);
1416 if (sr->fid_ofile == NULL) {
1417 smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
1418 ERRDOS, ERRbadfid);
1419 return (SDRC_ERROR);
1420 }
1421
1422 /*
1423 * A little confusing perhaps, but the fsctl "input" is what we
1424 * write to the pipe (from the transaction "send" data), and the
1425 * fsctl "output" is what we read from the pipe (and becomes the
1426 * transaction receive data).
1427 */
1428 fsctl.CtlCode = FSCTL_PIPE_TRANSCEIVE;
1429 fsctl.InputCount = xa->smb_tdscnt; /* write count */
1430 fsctl.OutputCount = 0; /* minimum to read from the pipe */
1431 fsctl.MaxOutputResp = xa->smb_mdrcnt; /* max to read */
1432 fsctl.in_mbc = &xa->req_data_mb; /* write from here */
1433 fsctl.out_mbc = &xa->rep_data_mb; /* read into here */
1434
1435 status = smb_opipe_fsctl(sr, &fsctl);
1436 if (status) {
1437 smbsr_status(sr, status, 0, 0);
1438 if (NT_SC_SEVERITY(status) == NT_STATUS_SEVERITY_ERROR)
1439 return (SDRC_ERROR);
1440 /* Warnings like NT_STATUS_BUFFER_OVERFLOW are OK */
1441 }
1442
1443 return (SDRC_SUCCESS);
1444 }
1445
1446 static smb_sdrc_t
1447 smb_trans_dispatch(smb_request_t *sr, smb_xa_t *xa)
1448 {
1449 int rc, pos;
1450 int total_bytes, n_setup, n_param, n_data;
1451 int param_off, param_pad, data_off, data_pad;
1452 uint16_t opcode;
1453 uint16_t devstate;
1454 char *req_fmt;
1455 char *rep_fmt;
1746 param_off = param_pad + 32 + 21 + (n_setup << 1) + 2;
1747
1748 /*
1749 * Including the nt_unknown_secret value persuades netmon to
1750 * display the correct data format for QueryPathInfo and
1751 * QueryFileInfo.
1752 */
1753 if (opcode == TRANS2_QUERY_FILE_INFORMATION ||
1754 opcode == TRANS2_QUERY_PATH_INFORMATION) {
1755 data_pad = sizeof (uint16_t);
1756 data_off = param_off + n_param + data_pad;
1757 fmt = "bww2.wwwwwwb.Cw#.CwC";
1758 nt_unknown_secret = 0x0100;
1759 }
1760 else
1761 {
1762 data_pad = (param_off + n_param) & 1; /* Pad to short */
1763 /* Param off from hdr start */
1764 data_off = param_off + n_param + data_pad;
1765 fmt = "bww2.wwwwwwb.Cw#.C#.C";
1766 nt_unknown_secret = data_pad;
1767 }
1768
1769 total_bytes = param_pad + n_param + data_pad + n_data;
1770
1771 rc = smbsr_encode_result(sr, 10+n_setup, total_bytes,
1772 fmt,
1773 10 + n_setup, /* wct */
1774 n_param, /* Total Parameter Bytes */
1775 n_data /* + data_pad */, /* Total Data Bytes */
1776 n_param, /* Total Parameter Bytes this buffer */
1777 param_off, /* Param offset from header start */
1778 0, /* Param displacement */
1779 n_data /* + data_pad */, /* Total Data Bytes this buffer */
1780 data_off, /* Data offset from header start */
1781 0, /* Data displacement */
1782 n_setup, /* suwcnt */
1783 &xa->rep_setup_mb, /* setup[] */
1784 total_bytes, /* Total data bytes */
1785 param_pad,
1786 &xa->rep_param_mb,
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 #include <smbsrv/smb_kproto.h>
28 #include <smbsrv/smb_fsops.h>
29 #include <smbsrv/smb_share.h>
30 #include <smbsrv/string.h>
31 #include <smbsrv/nmpipes.h>
32 #include <smbsrv/mailslot.h>
33 #include <smb/winioctl.h>
34
35 /*
36 * count of bytes in server response packet
37 * except parameters and data. Note that setup
38 * word count is zero.
39 */
40 #define RESP_HEADER_LEN 24
41
42 /*
43 * We started by using common functions for transaction/transaction2
44 * and transaction_secondary/transaction2_secondary because they
45 * are respectively so similar. However, it turned out to be a bad
46 * idea because of quirky differences. Be sure if you modify one
47 * of these four functions to check and see if the modification should
48 * be applied to its peer.
49 */
50
51 static int smb_trans_ready(smb_xa_t *);
52 static smb_sdrc_t smb_trans_dispatch(smb_request_t *, smb_xa_t *);
53 static smb_sdrc_t smb_trans2_dispatch(smb_request_t *, smb_xa_t *);
54
55 smb_sdrc_t
56 smb_pre_transaction(smb_request_t *sr)
57 {
58 DTRACE_SMB_START(op__Transaction, smb_request_t *, sr);
59 return (SDRC_SUCCESS);
60 }
61
62 void
63 smb_post_transaction(smb_request_t *sr)
64 {
65 DTRACE_SMB_DONE(op__Transaction, smb_request_t *, sr);
66 }
67
68 smb_sdrc_t
69 smb_com_transaction(smb_request_t *sr)
70 {
71 int rc;
72 unsigned char msrcnt, suwcnt;
73 uint16_t tpscnt, tdscnt, mprcnt, mdrcnt, flags;
74 uint16_t pscnt, psoff, dscnt, dsoff;
75 uint32_t timeo;
76 struct smb_xa *xa;
77 char *stn;
78 int ready;
79
80 if (!STYPE_ISIPC(sr->tid_tree->t_res_type)) {
81 smbsr_error(sr, 0, ERRDOS, ERRnoaccess);
82 return (SDRC_ERROR);
83 }
84
85 rc = smbsr_decode_vwv(sr, SMB_TRANSHDR_ED_FMT,
139 }
140 sr->r_xa = xa;
141
142 if (!ready) {
143 rc = smbsr_encode_empty_result(sr);
144 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
145 }
146
147 if (!smb_xa_complete(xa)) {
148 smb_xa_close(xa);
149 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
150 return (SDRC_ERROR);
151 }
152
153 return (smb_trans_dispatch(sr, xa));
154 }
155
156 smb_sdrc_t
157 smb_pre_transaction_secondary(smb_request_t *sr)
158 {
159 DTRACE_SMB_START(op__TransactionSecondary, smb_request_t *, sr);
160 return (SDRC_SUCCESS);
161 }
162
163 void
164 smb_post_transaction_secondary(smb_request_t *sr)
165 {
166 DTRACE_SMB_DONE(op__TransactionSecondary, smb_request_t *, sr);
167 }
168
169 smb_sdrc_t
170 smb_com_transaction_secondary(smb_request_t *sr)
171 {
172 uint16_t tpscnt, tdscnt, pscnt, psdisp;
173 uint16_t dscnt, dsoff, dsdisp, psoff;
174 smb_xa_t *xa;
175 int rc;
176
177 if ((xa = smbsr_lookup_xa(sr)) == 0) {
178 smbsr_error(sr, 0, ERRSRV, ERRsrverror);
179 return (SDRC_ERROR);
180 }
181
182 if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
183 if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
184 smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
185 ERRDOS, ERRnoaccess);
186 return (SDRC_ERROR);
237 if (smb_mbc_copy(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
238 mutex_exit(&xa->xa_mutex);
239 smb_xa_close(xa);
240 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
241 return (SDRC_ERROR);
242 }
243 mutex_exit(&xa->xa_mutex);
244
245 if (!smb_trans_ready(xa))
246 return (SDRC_NO_REPLY);
247
248 if (!smb_xa_complete(xa))
249 return (SDRC_NO_REPLY);
250
251 return (smb_trans_dispatch(sr, xa));
252 }
253
254 smb_sdrc_t
255 smb_pre_ioctl(smb_request_t *sr)
256 {
257 DTRACE_SMB_START(op__Ioctl, smb_request_t *, sr);
258 return (SDRC_SUCCESS);
259 }
260
261 void
262 smb_post_ioctl(smb_request_t *sr)
263 {
264 DTRACE_SMB_DONE(op__Ioctl, smb_request_t *, sr);
265 }
266
267 smb_sdrc_t
268 smb_com_ioctl(smb_request_t *sr)
269 {
270 uint16_t fid, category, function, tpscnt, tdscnt, mprcnt;
271 uint16_t mdrcnt, pscnt, pdoff, dscnt, dsoff;
272 uint32_t timeout;
273 int rc;
274
275 rc = smbsr_decode_vwv(sr, "wwwwwwwl2.wwww", &fid, &category, &function,
276 &tpscnt, &tdscnt, &mprcnt, &mdrcnt, &timeout, &pscnt,
277 &pdoff, &dscnt, &dsoff);
278
279 if (rc != 0)
280 return (SDRC_ERROR);
281
282 return (SDRC_NOT_IMPLEMENTED);
283 }
284
285 smb_sdrc_t
286 smb_pre_transaction2(smb_request_t *sr)
287 {
288 DTRACE_SMB_START(op__Transaction2, smb_request_t *, sr);
289 return (SDRC_SUCCESS);
290 }
291
292 void
293 smb_post_transaction2(smb_request_t *sr)
294 {
295 DTRACE_SMB_DONE(op__Transaction2, smb_request_t *, sr);
296 }
297
298 smb_sdrc_t
299 smb_com_transaction2(struct smb_request *sr)
300 {
301 unsigned char msrcnt, suwcnt;
302 uint16_t tpscnt, tdscnt, mprcnt, mdrcnt, flags;
303 uint16_t pscnt, psoff, dscnt, dsoff;
304 uint32_t timeo;
305 smb_xa_t *xa;
306 int ready;
307 int rc;
308
309 rc = smbsr_decode_vwv(sr, SMB_TRANSHDR_ED_FMT, &tpscnt, &tdscnt,
310 &mprcnt, &mdrcnt, &msrcnt, &flags, &timeo, &pscnt, &psoff, &dscnt,
311 &dsoff, &suwcnt);
312
313 if (rc != 0)
314 return (SDRC_ERROR);
315
351 }
352 sr->r_xa = xa;
353
354 if (!ready) {
355 rc = smbsr_encode_empty_result(sr);
356 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
357 }
358
359 if (!smb_xa_complete(xa)) {
360 smb_xa_close(xa);
361 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
362 return (SDRC_ERROR);
363 }
364
365 return (smb_trans2_dispatch(sr, xa));
366 }
367
368 smb_sdrc_t
369 smb_pre_transaction2_secondary(smb_request_t *sr)
370 {
371 DTRACE_SMB_START(op__Transaction2Secondary, smb_request_t *, sr);
372 return (SDRC_SUCCESS);
373 }
374
375 void
376 smb_post_transaction2_secondary(smb_request_t *sr)
377 {
378 DTRACE_SMB_DONE(op__Transaction2Secondary, smb_request_t *, sr);
379 }
380
381 smb_sdrc_t
382 smb_com_transaction2_secondary(smb_request_t *sr)
383 {
384 uint16_t tpscnt, tdscnt, fid;
385 uint16_t pscnt, psoff, psdisp, dscnt, dsoff, dsdisp;
386 smb_xa_t *xa;
387 int rc;
388
389 if ((xa = smbsr_lookup_xa(sr)) == 0) {
390 smbsr_error(sr, 0, ERRSRV, ERRsrverror);
391 return (SDRC_ERROR);
392 }
393
394 if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
395 if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
396 smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
397 ERRDOS, ERRnoaccess);
398 return (SDRC_ERROR);
541 n_data, /* Total Data Bytes */
542 n_param, /* Total Parameter Bytes this buffer */
543 param_off, /* Param offset from header start */
544 0, /* Param displacement */
545 n_data, /* Total Data Bytes this buffer */
546 data_off, /* Data offset from header start */
547 0, /* Data displacement */
548 n_setup, /* suwcnt */
549 &xa->rep_setup_mb, /* setup[] */
550 total_bytes, /* Total data bytes */
551 param_pad,
552 &xa->rep_param_mb,
553 data_pad,
554 &xa->rep_data_mb);
555 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
556 }
557
558 smb_sdrc_t
559 smb_pre_nt_transact(smb_request_t *sr)
560 {
561 DTRACE_SMB_START(op__NtTransact, smb_request_t *, sr);
562 return (SDRC_SUCCESS);
563 }
564
565 void
566 smb_post_nt_transact(smb_request_t *sr)
567 {
568 DTRACE_SMB_DONE(op__NtTransact, smb_request_t *, sr);
569 }
570
571 smb_sdrc_t
572 smb_com_nt_transact(struct smb_request *sr)
573 {
574 uint16_t Function;
575 unsigned char MaxSetupCount, SetupCount;
576 uint32_t TotalParameterCount, TotalDataCount;
577 uint32_t MaxParameterCount, MaxDataCount, pscnt;
578 uint32_t psoff, dscnt, dsoff;
579 smb_xa_t *xa;
580 int ready;
581 int rc;
582
583 rc = smbsr_decode_vwv(sr, SMB_NT_TRANSHDR_ED_FMT, &MaxSetupCount,
584 &TotalParameterCount, &TotalDataCount, &MaxParameterCount,
585 &MaxDataCount, &pscnt, &psoff, &dscnt,
586 &dsoff, &SetupCount, &Function);
587
588 if (rc != 0)
627 }
628 sr->r_xa = xa;
629
630 if (!ready) {
631 rc = smbsr_encode_empty_result(sr);
632 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
633 }
634
635 if (!smb_xa_complete(xa)) {
636 smb_xa_close(xa);
637 smbsr_error(sr, 0, ERRDOS, ERRbadformat);
638 return (SDRC_ERROR);
639 }
640
641 return (smb_nt_trans_dispatch(sr, xa));
642 }
643
644 smb_sdrc_t
645 smb_pre_nt_transact_secondary(smb_request_t *sr)
646 {
647 DTRACE_SMB_START(op__NtTransactSecondary, smb_request_t *, sr);
648 return (SDRC_SUCCESS);
649 }
650
651 void
652 smb_post_nt_transact_secondary(smb_request_t *sr)
653 {
654 DTRACE_SMB_DONE(op__NtTransactSecondary, smb_request_t *, sr);
655 }
656
657 smb_sdrc_t
658 smb_com_nt_transact_secondary(struct smb_request *sr)
659 {
660 uint16_t tpscnt, tdscnt, fid;
661 uint16_t pscnt, psoff, psdisp, dscnt, dsoff, dsdisp;
662 smb_xa_t *xa;
663 int rc;
664
665 if ((xa = smbsr_lookup_xa(sr)) == 0) {
666 smbsr_error(sr, 0, ERRSRV, ERRsrverror);
667 return (SDRC_ERROR);
668 }
669
670 if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
671 if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
672 smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
673 ERRDOS, ERRnoaccess);
674 return (SDRC_ERROR);
1415 smbsr_lookup_file(sr);
1416 if (sr->fid_ofile == NULL) {
1417 smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
1418 ERRDOS, ERRbadfid);
1419 return (SDRC_ERROR);
1420 }
1421
1422 /*
1423 * A little confusing perhaps, but the fsctl "input" is what we
1424 * write to the pipe (from the transaction "send" data), and the
1425 * fsctl "output" is what we read from the pipe (and becomes the
1426 * transaction receive data).
1427 */
1428 fsctl.CtlCode = FSCTL_PIPE_TRANSCEIVE;
1429 fsctl.InputCount = xa->smb_tdscnt; /* write count */
1430 fsctl.OutputCount = 0; /* minimum to read from the pipe */
1431 fsctl.MaxOutputResp = xa->smb_mdrcnt; /* max to read */
1432 fsctl.in_mbc = &xa->req_data_mb; /* write from here */
1433 fsctl.out_mbc = &xa->rep_data_mb; /* read into here */
1434
1435 status = smb_opipe_transceive(sr, &fsctl);
1436 if (status) {
1437 smbsr_status(sr, status, 0, 0);
1438 if (NT_SC_SEVERITY(status) == NT_STATUS_SEVERITY_ERROR)
1439 return (SDRC_ERROR);
1440 /* Warnings like NT_STATUS_BUFFER_OVERFLOW are OK */
1441 }
1442
1443 return (SDRC_SUCCESS);
1444 }
1445
1446 static smb_sdrc_t
1447 smb_trans_dispatch(smb_request_t *sr, smb_xa_t *xa)
1448 {
1449 int rc, pos;
1450 int total_bytes, n_setup, n_param, n_data;
1451 int param_off, param_pad, data_off, data_pad;
1452 uint16_t opcode;
1453 uint16_t devstate;
1454 char *req_fmt;
1455 char *rep_fmt;
1746 param_off = param_pad + 32 + 21 + (n_setup << 1) + 2;
1747
1748 /*
1749 * Including the nt_unknown_secret value persuades netmon to
1750 * display the correct data format for QueryPathInfo and
1751 * QueryFileInfo.
1752 */
1753 if (opcode == TRANS2_QUERY_FILE_INFORMATION ||
1754 opcode == TRANS2_QUERY_PATH_INFORMATION) {
1755 data_pad = sizeof (uint16_t);
1756 data_off = param_off + n_param + data_pad;
1757 fmt = "bww2.wwwwwwb.Cw#.CwC";
1758 nt_unknown_secret = 0x0100;
1759 }
1760 else
1761 {
1762 data_pad = (param_off + n_param) & 1; /* Pad to short */
1763 /* Param off from hdr start */
1764 data_off = param_off + n_param + data_pad;
1765 fmt = "bww2.wwwwwwb.Cw#.C#.C";
1766 nt_unknown_secret = (uint16_t)data_pad;
1767 }
1768
1769 total_bytes = param_pad + n_param + data_pad + n_data;
1770
1771 rc = smbsr_encode_result(sr, 10+n_setup, total_bytes,
1772 fmt,
1773 10 + n_setup, /* wct */
1774 n_param, /* Total Parameter Bytes */
1775 n_data /* + data_pad */, /* Total Data Bytes */
1776 n_param, /* Total Parameter Bytes this buffer */
1777 param_off, /* Param offset from header start */
1778 0, /* Param displacement */
1779 n_data /* + data_pad */, /* Total Data Bytes this buffer */
1780 data_off, /* Data offset from header start */
1781 0, /* Data displacement */
1782 n_setup, /* suwcnt */
1783 &xa->rep_setup_mb, /* setup[] */
1784 total_bytes, /* Total data bytes */
1785 param_pad,
1786 &xa->rep_param_mb,
|