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,
 
 |