1 /* 2 * Copyright (c) 2000-2001, Boris Popov 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Boris Popov. 16 * 4. Neither the name of the author nor the names of any co-contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * $Id: smb_rq.c,v 1.29 2005/02/11 01:44:17 lindak Exp $ 33 */ 34 35 /* 36 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 37 * Portions Copyright (C) 2001 - 2013 Apple Inc. All rights reserved. 38 * Copyright 2018 Nexenta Systems, Inc. All rights reserved. 39 */ 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/time.h> 44 #include <sys/kmem.h> 45 #include <sys/proc.h> 46 #include <sys/lock.h> 47 #include <sys/socket.h> 48 #include <sys/mount.h> 49 #include <sys/sunddi.h> 50 #include <sys/cmn_err.h> 51 #include <sys/sdt.h> 52 53 #include <netsmb/smb_osdep.h> 54 55 #include <netsmb/smb.h> 56 #include <netsmb/smb2.h> 57 #include <netsmb/smb_conn.h> 58 #include <netsmb/smb_subr.h> 59 #include <netsmb/smb_tran.h> 60 #include <netsmb/smb_rq.h> 61 #include <netsmb/smb2_rq.h> 62 63 /* 64 * How long to wait before restarting a request (after reconnect) 65 */ 66 #define SMB_RCNDELAY 2 /* seconds */ 67 68 /* 69 * leave this zero - we can't ssecond guess server side effects of 70 * duplicate ops, this isn't nfs! 71 */ 72 #define SMBMAXRESTARTS 0 73 74 75 static int smb_rq_reply(struct smb_rq *rqp); 76 static int smb_rq_parsehdr(struct smb_rq *rqp); 77 static int smb_rq_enqueue(struct smb_rq *rqp); 78 static int smb_rq_new(struct smb_rq *rqp, uchar_t cmd); 79 static int smb_t2_reply(struct smb_t2rq *t2p); 80 static int smb_nt_reply(struct smb_ntrq *ntp); 81 82 83 /* 84 * Done with a request object. Free its contents. 85 * If it was allocated (SMBR_ALLOCED) free it too. 86 * Some of these are stack locals, not allocated. 87 * 88 * No locks here - this is the last ref. 89 */ 90 void 91 smb_rq_done(struct smb_rq *rqp) 92 { 93 94 /* 95 * No smb_vc_rele() here - see smb_rq_init() 96 */ 97 mb_done(&rqp->sr_rq); 98 md_done(&rqp->sr_rp); 99 mutex_destroy(&rqp->sr_lock); 100 cv_destroy(&rqp->sr_cond); 101 if (rqp->sr_flags & SMBR_ALLOCED) 102 kmem_free(rqp, sizeof (*rqp)); 103 } 104 105 int 106 smb_rq_alloc(struct smb_connobj *layer, uchar_t cmd, struct smb_cred *scred, 107 struct smb_rq **rqpp) 108 { 109 struct smb_rq *rqp; 110 int error; 111 112 rqp = (struct smb_rq *)kmem_alloc(sizeof (struct smb_rq), KM_SLEEP); 113 if (rqp == NULL) 114 return (ENOMEM); 115 error = smb_rq_init(rqp, layer, cmd, scred); 116 if (error) { 117 smb_rq_done(rqp); 118 return (error); 119 } 120 rqp->sr_flags |= SMBR_ALLOCED; 121 *rqpp = rqp; 122 return (0); 123 } 124 125 int 126 smb_rq_init(struct smb_rq *rqp, struct smb_connobj *co, uchar_t cmd, 127 struct smb_cred *scred) 128 { 129 int error; 130 131 bzero(rqp, sizeof (*rqp)); 132 mutex_init(&rqp->sr_lock, NULL, MUTEX_DRIVER, NULL); 133 cv_init(&rqp->sr_cond, NULL, CV_DEFAULT, NULL); 134 135 error = smb_rq_getenv(co, &rqp->sr_vc, &rqp->sr_share); 136 if (error) 137 return (error); 138 139 /* 140 * We copied a VC pointer (vcp) into rqp->sr_vc, 141 * but we do NOT do a smb_vc_hold here. Instead, 142 * the caller is responsible for the hold on the 143 * share or the VC as needed. For smbfs callers, 144 * the hold is on the share, via the smbfs mount. 145 * For nsmb ioctl callers, the hold is done when 146 * the driver handle gets VC or share references. 147 * This design avoids frequent hold/rele activity 148 * when creating and completing requests. 149 */ 150 151 rqp->sr_rexmit = SMBMAXRESTARTS; 152 rqp->sr_cred = scred; /* Note: ref hold done by caller. */ 153 error = smb_rq_new(rqp, cmd); 154 155 return (error); 156 } 157 158 static int 159 smb_rq_new(struct smb_rq *rqp, uchar_t cmd) 160 { 161 struct mbchain *mbp = &rqp->sr_rq; 162 struct smb_vc *vcp = rqp->sr_vc; 163 int error; 164 165 ASSERT(rqp != NULL); 166 167 rqp->sr_sendcnt = 0; 168 169 mb_done(mbp); 170 md_done(&rqp->sr_rp); 171 error = mb_init(mbp); 172 if (error) 173 return (error); 174 175 if (vcp->vc_flags & SMBV_SMB2) { 176 /* 177 * SMB2 request initialization 178 */ 179 rqp->sr2_command = cmd; 180 rqp->sr2_creditcharge = 1; 181 rqp->sr2_creditsrequested = 1; 182 rqp->sr_pid = 0xFEFF; /* Made up, just like Windows */ 183 rqp->sr2_rqflags = 0; 184 if ((vcp->vc_flags & SMBV_SIGNING) != 0 && 185 vcp->vc_mackey != NULL) { 186 rqp->sr2_rqflags |= SMB2_FLAGS_SIGNED; 187 } 188 189 /* 190 * The SMB2 header is filled in later by 191 * smb2_rq_fillhdr (see smb2_rq.c) 192 * Just reserve space here. 193 */ 194 mb_put_mem(mbp, NULL, SMB2_HDRLEN, MB_MZERO); 195 } else { 196 /* 197 * SMB1 request initialization 198 */ 199 rqp->sr_cmd = cmd; 200 rqp->sr_pid = (uint32_t)ddi_get_pid(); 201 rqp->sr_rqflags = vcp->vc_hflags; 202 rqp->sr_rqflags2 = vcp->vc_hflags2; 203 204 /* 205 * The SMB header is filled in later by 206 * smb_rq_fillhdr (see below) 207 * Just reserve space here. 208 */ 209 mb_put_mem(mbp, NULL, SMB_HDRLEN, MB_MZERO); 210 } 211 212 return (0); 213 } 214 215 /* 216 * Given a request with it's body already composed, 217 * rewind to the start and fill in the SMB header. 218 * This is called when the request is enqueued, 219 * so we have the final MID, seq num. etc. 220 */ 221 void 222 smb_rq_fillhdr(struct smb_rq *rqp) 223 { 224 struct mbchain mbtmp, *mbp = &mbtmp; 225 mblk_t *m; 226 227 /* 228 * Fill in the SMB header using a dup of the first mblk, 229 * which points at the same data but has its own wptr, 230 * so we can rewind without trashing the message. 231 */ 232 m = dupb(rqp->sr_rq.mb_top); 233 m->b_wptr = m->b_rptr; /* rewind */ 234 mb_initm(mbp, m); 235 236 mb_put_mem(mbp, SMB_SIGNATURE, 4, MB_MSYSTEM); 237 mb_put_uint8(mbp, rqp->sr_cmd); 238 mb_put_uint32le(mbp, 0); /* status */ 239 mb_put_uint8(mbp, rqp->sr_rqflags); 240 mb_put_uint16le(mbp, rqp->sr_rqflags2); 241 mb_put_uint16le(mbp, 0); /* pid-high */ 242 mb_put_mem(mbp, NULL, 8, MB_MZERO); /* MAC sig. (later) */ 243 mb_put_uint16le(mbp, 0); /* reserved */ 244 mb_put_uint16le(mbp, rqp->sr_rqtid); 245 mb_put_uint16le(mbp, (uint16_t)rqp->sr_pid); 246 mb_put_uint16le(mbp, rqp->sr_rquid); 247 mb_put_uint16le(mbp, rqp->sr_mid); 248 249 /* This will free the mblk from dupb. */ 250 mb_done(mbp); 251 } 252 253 int 254 smb_rq_simple(struct smb_rq *rqp) 255 { 256 return (smb_rq_simple_timed(rqp, smb_timo_default)); 257 } 258 259 /* 260 * Simple request-reply exchange 261 */ 262 int 263 smb_rq_simple_timed(struct smb_rq *rqp, int timeout) 264 { 265 int error = EINVAL; 266 267 for (; ; ) { 268 /* 269 * Don't send any new requests if force unmount is underway. 270 * This check was moved into smb_rq_enqueue. 271 */ 272 rqp->sr_flags &= ~SMBR_RESTART; 273 rqp->sr_timo = timeout; /* in seconds */ 274 rqp->sr_state = SMBRQ_NOTSENT; 275 error = smb_rq_enqueue(rqp); 276 if (error) { 277 break; 278 } 279 error = smb_rq_reply(rqp); 280 if (!error) 281 break; 282 if ((rqp->sr_flags & (SMBR_RESTART | SMBR_NORESTART)) != 283 SMBR_RESTART) 284 break; 285 if (rqp->sr_rexmit <= 0) 286 break; 287 SMBRQ_LOCK(rqp); 288 if (rqp->sr_share) { 289 (void) cv_reltimedwait(&rqp->sr_cond, &(rqp)->sr_lock, 290 SEC_TO_TICK(SMB_RCNDELAY), TR_CLOCK_TICK); 291 292 } else { 293 delay(SEC_TO_TICK(SMB_RCNDELAY)); 294 } 295 SMBRQ_UNLOCK(rqp); 296 rqp->sr_rexmit--; 297 } 298 return (error); 299 } 300 301 302 static int 303 smb_rq_enqueue(struct smb_rq *rqp) 304 { 305 struct smb_vc *vcp = rqp->sr_vc; 306 struct smb_share *ssp = rqp->sr_share; 307 int error = 0; 308 309 ASSERT((vcp->vc_flags & SMBV_SMB2) == 0); 310 311 /* 312 * Normal requests may initiate a reconnect, 313 * and/or wait for state changes to finish. 314 * Some requests set the NORECONNECT flag 315 * to avoid all that (i.e. tree discon) 316 */ 317 if (rqp->sr_flags & SMBR_NORECONNECT) { 318 if (vcp->vc_state != SMBIOD_ST_VCACTIVE) { 319 SMBSDEBUG("bad vc_state=%d\n", vcp->vc_state); 320 return (ENOTCONN); 321 } 322 if (ssp != NULL && 323 ((ssp->ss_flags & SMBS_CONNECTED) == 0)) 324 return (ENOTCONN); 325 goto ok_out; 326 } 327 328 /* 329 * If we're not connected, initiate a reconnect 330 * and/or wait for an existing one to finish. 331 */ 332 if (vcp->vc_state != SMBIOD_ST_VCACTIVE) { 333 error = smb_iod_reconnect(vcp); 334 if (error != 0) 335 return (error); 336 } 337 338 /* 339 * If this request has a "share" object 340 * that needs a tree connect, do it now. 341 */ 342 if (ssp != NULL && (ssp->ss_flags & SMBS_CONNECTED) == 0) { 343 error = smb_share_tcon(ssp, rqp->sr_cred); 344 if (error) 345 return (error); 346 } 347 348 /* 349 * We now know what UID + TID to use. 350 * Store them in the request. 351 */ 352 ok_out: 353 rqp->sr_rquid = vcp->vc_smbuid; 354 rqp->sr_rqtid = ssp ? ssp->ss_tid : SMB_TID_UNKNOWN; 355 error = smb1_iod_addrq(rqp); 356 357 return (error); 358 } 359 360 /* 361 * Used by the IOD thread during connection setup, 362 * and for smb_echo after network timeouts. Note that 363 * unlike smb_rq_simple, callers must check sr_error. 364 */ 365 int 366 smb_rq_internal(struct smb_rq *rqp, int timeout) 367 { 368 struct smb_vc *vcp = rqp->sr_vc; 369 int error; 370 371 ASSERT((vcp->vc_flags & SMBV_SMB2) == 0); 372 373 rqp->sr_flags &= ~SMBR_RESTART; 374 rqp->sr_timo = timeout; /* in seconds */ 375 rqp->sr_state = SMBRQ_NOTSENT; 376 377 /* 378 * In-line smb_rq_enqueue(rqp) here, as we don't want it 379 * trying to reconnect etc. for an internal request. 380 */ 381 rqp->sr_rquid = vcp->vc_smbuid; 382 rqp->sr_rqtid = SMB_TID_UNKNOWN; 383 rqp->sr_flags |= SMBR_INTERNAL; 384 error = smb1_iod_addrq(rqp); 385 if (error != 0) 386 return (error); 387 388 /* 389 * In-line a variant of smb_rq_reply(rqp) here as we may 390 * need to do custom parsing for SMB1-to-SMB2 negotiate. 391 */ 392 if (rqp->sr_timo == SMBNOREPLYWAIT) { 393 smb_iod_removerq(rqp); 394 return (0); 395 } 396 397 error = smb_iod_waitrq_int(rqp); 398 if (error) 399 return (error); 400 401 /* 402 * If the request was signed, validate the 403 * signature on the response. 404 */ 405 if (rqp->sr_rqflags2 & SMB_FLAGS2_SECURITY_SIGNATURE) { 406 error = smb_rq_verify(rqp); 407 if (error) 408 return (error); 409 } 410 411 /* 412 * Parse the SMB header. 413 */ 414 error = smb_rq_parsehdr(rqp); 415 416 /* 417 * Skip the error translation smb_rq_reply does. 418 * Callers of this expect "raw" NT status. 419 */ 420 421 return (error); 422 } 423 424 /* 425 * Mark location of the word count, which is filled in later by 426 * smb_rw_wend(). Also initialize the counter that it uses 427 * to figure out what value to fill in. 428 * 429 * Note that the word count happens to be 8-bit. 430 */ 431 void 432 smb_rq_wstart(struct smb_rq *rqp) 433 { 434 rqp->sr_wcount = mb_reserve(&rqp->sr_rq, sizeof (uint8_t)); 435 rqp->sr_rq.mb_count = 0; 436 } 437 438 void 439 smb_rq_wend(struct smb_rq *rqp) 440 { 441 uint_t wcnt; 442 443 if (rqp->sr_wcount == NULL) { 444 SMBSDEBUG("no wcount\n"); 445 return; 446 } 447 wcnt = rqp->sr_rq.mb_count; 448 if (wcnt > 0x1ff) 449 SMBSDEBUG("word count too large (%d)\n", wcnt); 450 if (wcnt & 1) 451 SMBSDEBUG("odd word count\n"); 452 /* Fill in the word count (8-bits) */ 453 *rqp->sr_wcount = (wcnt >> 1); 454 } 455 456 /* 457 * Mark location of the byte count, which is filled in later by 458 * smb_rw_bend(). Also initialize the counter that it uses 459 * to figure out what value to fill in. 460 * 461 * Note that the byte count happens to be 16-bit. 462 */ 463 void 464 smb_rq_bstart(struct smb_rq *rqp) 465 { 466 rqp->sr_bcount = mb_reserve(&rqp->sr_rq, sizeof (uint16_t)); 467 rqp->sr_rq.mb_count = 0; 468 } 469 470 void 471 smb_rq_bend(struct smb_rq *rqp) 472 { 473 uint_t bcnt; 474 475 if (rqp->sr_bcount == NULL) { 476 SMBSDEBUG("no bcount\n"); 477 return; 478 } 479 bcnt = rqp->sr_rq.mb_count; 480 if (bcnt > 0xffff) 481 SMBSDEBUG("byte count too large (%d)\n", bcnt); 482 /* 483 * Fill in the byte count (16-bits) 484 * The pointer is char * type due to 485 * typical off-by-one alignment. 486 */ 487 rqp->sr_bcount[0] = bcnt & 0xFF; 488 rqp->sr_bcount[1] = (bcnt >> 8); 489 } 490 491 int 492 smb_rq_getenv(struct smb_connobj *co, 493 struct smb_vc **vcpp, struct smb_share **sspp) 494 { 495 struct smb_vc *vcp = NULL; 496 struct smb_share *ssp = NULL; 497 int error = EINVAL; 498 499 if (co->co_flags & SMBO_GONE) { 500 SMBSDEBUG("zombie CO\n"); 501 error = EINVAL; 502 goto out; 503 } 504 505 switch (co->co_level) { 506 case SMBL_SHARE: 507 ssp = CPTOSS(co); 508 if ((co->co_flags & SMBO_GONE) || 509 co->co_parent == NULL) { 510 SMBSDEBUG("zombie share %s\n", ssp->ss_name); 511 break; 512 } 513 /* instead of recursion... */ 514 co = co->co_parent; 515 /* FALLTHROUGH */ 516 case SMBL_VC: 517 vcp = CPTOVC(co); 518 if ((co->co_flags & SMBO_GONE) || 519 co->co_parent == NULL) { 520 SMBSDEBUG("zombie VC %s\n", vcp->vc_srvname); 521 break; 522 } 523 error = 0; 524 break; 525 526 default: 527 SMBSDEBUG("invalid level %d passed\n", co->co_level); 528 } 529 530 out: 531 if (!error) { 532 if (vcpp) 533 *vcpp = vcp; 534 if (sspp) 535 *sspp = ssp; 536 } 537 538 return (error); 539 } 540 541 /* 542 * Wait for a reply to this request, then parse it. 543 */ 544 static int 545 smb_rq_reply(struct smb_rq *rqp) 546 { 547 int error; 548 549 if (rqp->sr_timo == SMBNOREPLYWAIT) { 550 smb_iod_removerq(rqp); 551 return (0); 552 } 553 554 error = smb_iod_waitrq(rqp); 555 if (error) 556 return (error); 557 558 /* 559 * If the request was signed, validate the 560 * signature on the response. 561 */ 562 if (rqp->sr_rqflags2 & SMB_FLAGS2_SECURITY_SIGNATURE) { 563 error = smb_rq_verify(rqp); 564 if (error) 565 return (error); 566 } 567 568 /* 569 * Parse the SMB header 570 */ 571 error = smb_rq_parsehdr(rqp); 572 if (error != 0) 573 return (error); 574 575 if (rqp->sr_error != 0) { 576 if (rqp->sr_rpflags2 & SMB_FLAGS2_ERR_STATUS) { 577 error = smb_maperr32(rqp->sr_error); 578 } else { 579 uint8_t errClass = rqp->sr_error & 0xff; 580 uint16_t errCode = rqp->sr_error >> 16; 581 /* Convert to NT status */ 582 rqp->sr_error = smb_doserr2status(errClass, errCode); 583 error = smb_maperror(errClass, errCode); 584 } 585 } 586 587 if (error != 0) { 588 /* 589 * Do a special check for STATUS_BUFFER_OVERFLOW; 590 * it's not an error. 591 */ 592 if (rqp->sr_error == NT_STATUS_BUFFER_OVERFLOW) { 593 /* 594 * Don't report it as an error to our caller; 595 * they can look at rqp->sr_error if they 596 * need to know whether we got a 597 * STATUS_BUFFER_OVERFLOW. 598 */ 599 rqp->sr_flags |= SMBR_MOREDATA; 600 error = 0; 601 } 602 } else { 603 rqp->sr_flags &= ~SMBR_MOREDATA; 604 } 605 606 return (error); 607 } 608 609 /* 610 * Parse the SMB header 611 */ 612 static int 613 smb_rq_parsehdr(struct smb_rq *rqp) 614 { 615 struct mdchain mdp_save; 616 struct mdchain *mdp = &rqp->sr_rp; 617 u_int8_t tb, sig[4]; 618 int error; 619 620 /* 621 * Parse the signature. The reader already checked that 622 * the signature is valid. Here we just have to check 623 * for SMB1-to-SMB2 negotiate. Caller handles an EPROTO 624 * as a signal that we got an SMB2 reply. If we return 625 * EPROTO, rewind the mdchain back where it was. 626 */ 627 mdp_save = *mdp; 628 error = md_get_mem(mdp, sig, 4, MB_MSYSTEM); 629 if (error) 630 return (error); 631 if (sig[0] != SMB_HDR_V1) { 632 if (rqp->sr_cmd == SMB_COM_NEGOTIATE) { 633 *mdp = mdp_save; 634 return (EPROTO); 635 } 636 return (EBADRPC); 637 } 638 639 /* Check cmd */ 640 error = md_get_uint8(mdp, &tb); 641 if (tb != rqp->sr_cmd) 642 return (EBADRPC); 643 644 md_get_uint32le(mdp, &rqp->sr_error); 645 md_get_uint8(mdp, &rqp->sr_rpflags); 646 md_get_uint16le(mdp, &rqp->sr_rpflags2); 647 648 /* Skip: pid-high(2), MAC sig(8), reserved(2) */ 649 md_get_mem(mdp, NULL, 12, MB_MSYSTEM); 650 651 md_get_uint16le(mdp, &rqp->sr_rptid); 652 md_get_uint16le(mdp, &rqp->sr_rppid); 653 md_get_uint16le(mdp, &rqp->sr_rpuid); 654 error = md_get_uint16le(mdp, &rqp->sr_rpmid); 655 656 return (error); 657 } 658 659 660 #define ALIGN4(a) (((a) + 3) & ~3) 661 662 /* 663 * TRANS2 request implementation 664 * TRANS implementation is in the "t2" routines 665 * NT_TRANSACTION implementation is the separate "nt" stuff 666 */ 667 int 668 smb_t2_alloc(struct smb_connobj *layer, ushort_t setup, struct smb_cred *scred, 669 struct smb_t2rq **t2pp) 670 { 671 struct smb_t2rq *t2p; 672 int error; 673 674 t2p = (struct smb_t2rq *)kmem_alloc(sizeof (*t2p), KM_SLEEP); 675 if (t2p == NULL) 676 return (ENOMEM); 677 error = smb_t2_init(t2p, layer, &setup, 1, scred); 678 t2p->t2_flags |= SMBT2_ALLOCED; 679 if (error) { 680 smb_t2_done(t2p); 681 return (error); 682 } 683 *t2pp = t2p; 684 return (0); 685 } 686 687 int 688 smb_nt_alloc(struct smb_connobj *layer, ushort_t fn, struct smb_cred *scred, 689 struct smb_ntrq **ntpp) 690 { 691 struct smb_ntrq *ntp; 692 int error; 693 694 ntp = (struct smb_ntrq *)kmem_alloc(sizeof (*ntp), KM_SLEEP); 695 if (ntp == NULL) 696 return (ENOMEM); 697 error = smb_nt_init(ntp, layer, fn, scred); 698 mutex_init(&ntp->nt_lock, NULL, MUTEX_DRIVER, NULL); 699 cv_init(&ntp->nt_cond, NULL, CV_DEFAULT, NULL); 700 ntp->nt_flags |= SMBT2_ALLOCED; 701 if (error) { 702 smb_nt_done(ntp); 703 return (error); 704 } 705 *ntpp = ntp; 706 return (0); 707 } 708 709 int 710 smb_t2_init(struct smb_t2rq *t2p, struct smb_connobj *source, ushort_t *setup, 711 int setupcnt, struct smb_cred *scred) 712 { 713 int i; 714 int error; 715 716 bzero(t2p, sizeof (*t2p)); 717 mutex_init(&t2p->t2_lock, NULL, MUTEX_DRIVER, NULL); 718 cv_init(&t2p->t2_cond, NULL, CV_DEFAULT, NULL); 719 720 t2p->t2_source = source; 721 t2p->t2_setupcount = (u_int16_t)setupcnt; 722 t2p->t2_setupdata = t2p->t2_setup; 723 for (i = 0; i < setupcnt; i++) 724 t2p->t2_setup[i] = setup[i]; 725 t2p->t2_fid = 0xffff; 726 t2p->t2_cred = scred; 727 t2p->t2_share = (source->co_level == SMBL_SHARE ? 728 CPTOSS(source) : NULL); /* for smb up/down */ 729 error = smb_rq_getenv(source, &t2p->t2_vc, NULL); 730 if (error) 731 return (error); 732 return (0); 733 } 734 735 int 736 smb_nt_init(struct smb_ntrq *ntp, struct smb_connobj *source, ushort_t fn, 737 struct smb_cred *scred) 738 { 739 int error; 740 741 bzero(ntp, sizeof (*ntp)); 742 ntp->nt_source = source; 743 ntp->nt_function = fn; 744 ntp->nt_cred = scred; 745 ntp->nt_share = (source->co_level == SMBL_SHARE ? 746 CPTOSS(source) : NULL); /* for smb up/down */ 747 error = smb_rq_getenv(source, &ntp->nt_vc, NULL); 748 if (error) 749 return (error); 750 return (0); 751 } 752 753 void 754 smb_t2_done(struct smb_t2rq *t2p) 755 { 756 mb_done(&t2p->t2_tparam); 757 mb_done(&t2p->t2_tdata); 758 md_done(&t2p->t2_rparam); 759 md_done(&t2p->t2_rdata); 760 mutex_destroy(&t2p->t2_lock); 761 cv_destroy(&t2p->t2_cond); 762 if (t2p->t2_flags & SMBT2_ALLOCED) 763 kmem_free(t2p, sizeof (*t2p)); 764 } 765 766 void 767 smb_nt_done(struct smb_ntrq *ntp) 768 { 769 mb_done(&ntp->nt_tsetup); 770 mb_done(&ntp->nt_tparam); 771 mb_done(&ntp->nt_tdata); 772 md_done(&ntp->nt_rparam); 773 md_done(&ntp->nt_rdata); 774 cv_destroy(&ntp->nt_cond); 775 mutex_destroy(&ntp->nt_lock); 776 if (ntp->nt_flags & SMBT2_ALLOCED) 777 kmem_free(ntp, sizeof (*ntp)); 778 } 779 780 /* 781 * Extract data [offset,count] from mtop and add to mdp. 782 */ 783 static int 784 smb_t2_placedata(mblk_t *mtop, u_int16_t offset, u_int16_t count, 785 struct mdchain *mdp) 786 { 787 mblk_t *n; 788 789 n = m_copym(mtop, offset, count, M_WAITOK); 790 if (n == NULL) 791 return (EBADRPC); 792 793 if (mdp->md_top == NULL) { 794 md_initm(mdp, n); 795 } else 796 m_cat(mdp->md_top, n); 797 798 return (0); 799 } 800 801 static int 802 smb_t2_reply(struct smb_t2rq *t2p) 803 { 804 struct mdchain *mdp; 805 struct smb_rq *rqp = t2p->t2_rq; 806 int error, error2, totpgot, totdgot; 807 u_int16_t totpcount, totdcount, pcount, poff, doff, pdisp, ddisp; 808 u_int16_t tmp, bc, dcount; 809 u_int8_t wc; 810 811 t2p->t2_flags &= ~SMBT2_MOREDATA; 812 813 error = smb_rq_reply(rqp); 814 if (rqp->sr_flags & SMBR_MOREDATA) 815 t2p->t2_flags |= SMBT2_MOREDATA; 816 t2p->t2_sr_errclass = rqp->sr_errclass; 817 t2p->t2_sr_serror = rqp->sr_serror; 818 t2p->t2_sr_error = rqp->sr_error; 819 t2p->t2_sr_rpflags2 = rqp->sr_rpflags2; 820 if (error && !(rqp->sr_flags & SMBR_MOREDATA)) 821 return (error); 822 /* 823 * Now we have to get all subseqent responses, if any. 824 * The CIFS specification says that they can be misordered, 825 * which is weird. 826 * TODO: timo 827 */ 828 totpgot = totdgot = 0; 829 totpcount = totdcount = 0xffff; 830 mdp = &rqp->sr_rp; 831 for (;;) { 832 DTRACE_PROBE2(smb_trans_reply, 833 (smb_rq_t *), rqp, (mblk_t *), mdp->md_top); 834 m_dumpm(mdp->md_top); 835 836 if ((error2 = md_get_uint8(mdp, &wc)) != 0) 837 break; 838 if (wc < 10) { 839 error2 = ENOENT; 840 break; 841 } 842 if ((error2 = md_get_uint16le(mdp, &tmp)) != 0) 843 break; 844 if (totpcount > tmp) 845 totpcount = tmp; 846 if ((error2 = md_get_uint16le(mdp, &tmp)) != 0) 847 break; 848 if (totdcount > tmp) 849 totdcount = tmp; 850 if ((error2 = md_get_uint16le(mdp, &tmp)) != 0 || /* reserved */ 851 (error2 = md_get_uint16le(mdp, &pcount)) != 0 || 852 (error2 = md_get_uint16le(mdp, &poff)) != 0 || 853 (error2 = md_get_uint16le(mdp, &pdisp)) != 0) 854 break; 855 if (pcount != 0 && pdisp != totpgot) { 856 SMBSDEBUG("Can't handle misordered parameters %d:%d\n", 857 pdisp, totpgot); 858 error2 = EINVAL; 859 break; 860 } 861 if ((error2 = md_get_uint16le(mdp, &dcount)) != 0 || 862 (error2 = md_get_uint16le(mdp, &doff)) != 0 || 863 (error2 = md_get_uint16le(mdp, &ddisp)) != 0) 864 break; 865 if (dcount != 0 && ddisp != totdgot) { 866 SMBSDEBUG("Can't handle misordered data: dcount %d\n", 867 dcount); 868 error2 = EINVAL; 869 break; 870 } 871 872 /* XXX: Skip setup words? We don't save them? */ 873 md_get_uint8(mdp, &wc); /* SetupCount */ 874 md_get_uint8(mdp, NULL); /* Reserved2 */ 875 tmp = wc; 876 while (tmp--) 877 md_get_uint16le(mdp, NULL); 878 879 if ((error2 = md_get_uint16le(mdp, &bc)) != 0) 880 break; 881 882 /* 883 * There are pad bytes here, and the poff value 884 * indicates where the next data are found. 885 * No need to guess at the padding size. 886 */ 887 if (pcount) { 888 error2 = smb_t2_placedata(mdp->md_top, poff, 889 pcount, &t2p->t2_rparam); 890 if (error2) 891 break; 892 } 893 totpgot += pcount; 894 895 if (dcount) { 896 error2 = smb_t2_placedata(mdp->md_top, doff, 897 dcount, &t2p->t2_rdata); 898 if (error2) 899 break; 900 } 901 totdgot += dcount; 902 903 if (totpgot >= totpcount && totdgot >= totdcount) { 904 error2 = 0; 905 t2p->t2_flags |= SMBT2_ALLRECV; 906 break; 907 } 908 /* 909 * We're done with this reply, look for the next one. 910 */ 911 SMBRQ_LOCK(rqp); 912 md_next_record(&rqp->sr_rp); 913 SMBRQ_UNLOCK(rqp); 914 error2 = smb_rq_reply(rqp); 915 if (rqp->sr_flags & SMBR_MOREDATA) 916 t2p->t2_flags |= SMBT2_MOREDATA; 917 if (!error2) 918 continue; 919 t2p->t2_sr_errclass = rqp->sr_errclass; 920 t2p->t2_sr_serror = rqp->sr_serror; 921 t2p->t2_sr_error = rqp->sr_error; 922 t2p->t2_sr_rpflags2 = rqp->sr_rpflags2; 923 error = error2; 924 if (!(rqp->sr_flags & SMBR_MOREDATA)) 925 break; 926 } 927 return (error ? error : error2); 928 } 929 930 static int 931 smb_nt_reply(struct smb_ntrq *ntp) 932 { 933 struct mdchain *mdp; 934 struct smb_rq *rqp = ntp->nt_rq; 935 int error, error2; 936 u_int32_t totpcount, totdcount, pcount, poff, doff, pdisp, ddisp; 937 u_int32_t tmp, dcount, totpgot, totdgot; 938 u_int16_t bc; 939 u_int8_t wc; 940 941 ntp->nt_flags &= ~SMBT2_MOREDATA; 942 943 error = smb_rq_reply(rqp); 944 if (rqp->sr_flags & SMBR_MOREDATA) 945 ntp->nt_flags |= SMBT2_MOREDATA; 946 ntp->nt_sr_error = rqp->sr_error; 947 ntp->nt_sr_rpflags2 = rqp->sr_rpflags2; 948 if (error && !(rqp->sr_flags & SMBR_MOREDATA)) 949 return (error); 950 /* 951 * Now we have to get all subseqent responses. The CIFS specification 952 * says that they can be misordered which is weird. 953 * TODO: timo 954 */ 955 totpgot = totdgot = 0; 956 totpcount = totdcount = 0xffffffff; 957 mdp = &rqp->sr_rp; 958 for (;;) { 959 DTRACE_PROBE2(smb_trans_reply, 960 (smb_rq_t *), rqp, (mblk_t *), mdp->md_top); 961 m_dumpm(mdp->md_top); 962 963 if ((error2 = md_get_uint8(mdp, &wc)) != 0) 964 break; 965 if (wc < 18) { 966 error2 = ENOENT; 967 break; 968 } 969 md_get_mem(mdp, NULL, 3, MB_MSYSTEM); /* reserved */ 970 if ((error2 = md_get_uint32le(mdp, &tmp)) != 0) 971 break; 972 if (totpcount > tmp) 973 totpcount = tmp; 974 if ((error2 = md_get_uint32le(mdp, &tmp)) != 0) 975 break; 976 if (totdcount > tmp) 977 totdcount = tmp; 978 if ((error2 = md_get_uint32le(mdp, &pcount)) != 0 || 979 (error2 = md_get_uint32le(mdp, &poff)) != 0 || 980 (error2 = md_get_uint32le(mdp, &pdisp)) != 0) 981 break; 982 if (pcount != 0 && pdisp != totpgot) { 983 SMBSDEBUG("Can't handle misordered parameters %d:%d\n", 984 pdisp, totpgot); 985 error2 = EINVAL; 986 break; 987 } 988 if ((error2 = md_get_uint32le(mdp, &dcount)) != 0 || 989 (error2 = md_get_uint32le(mdp, &doff)) != 0 || 990 (error2 = md_get_uint32le(mdp, &ddisp)) != 0) 991 break; 992 if (dcount != 0 && ddisp != totdgot) { 993 SMBSDEBUG("Can't handle misordered data: dcount %d\n", 994 dcount); 995 error2 = EINVAL; 996 break; 997 } 998 999 /* XXX: Skip setup words? We don't save them? */ 1000 md_get_uint8(mdp, &wc); /* SetupCount */ 1001 tmp = wc; 1002 while (tmp--) 1003 md_get_uint16le(mdp, NULL); 1004 1005 if ((error2 = md_get_uint16le(mdp, &bc)) != 0) 1006 break; 1007 1008 /* 1009 * There are pad bytes here, and the poff value 1010 * indicates where the next data are found. 1011 * No need to guess at the padding size. 1012 */ 1013 if (pcount) { 1014 error2 = smb_t2_placedata(mdp->md_top, poff, pcount, 1015 &ntp->nt_rparam); 1016 if (error2) 1017 break; 1018 } 1019 totpgot += pcount; 1020 1021 if (dcount) { 1022 error2 = smb_t2_placedata(mdp->md_top, doff, dcount, 1023 &ntp->nt_rdata); 1024 if (error2) 1025 break; 1026 } 1027 totdgot += dcount; 1028 1029 if (totpgot >= totpcount && totdgot >= totdcount) { 1030 error2 = 0; 1031 ntp->nt_flags |= SMBT2_ALLRECV; 1032 break; 1033 } 1034 /* 1035 * We're done with this reply, look for the next one. 1036 */ 1037 SMBRQ_LOCK(rqp); 1038 md_next_record(&rqp->sr_rp); 1039 SMBRQ_UNLOCK(rqp); 1040 error2 = smb_rq_reply(rqp); 1041 if (rqp->sr_flags & SMBR_MOREDATA) 1042 ntp->nt_flags |= SMBT2_MOREDATA; 1043 if (!error2) 1044 continue; 1045 ntp->nt_sr_error = rqp->sr_error; 1046 ntp->nt_sr_rpflags2 = rqp->sr_rpflags2; 1047 error = error2; 1048 if (!(rqp->sr_flags & SMBR_MOREDATA)) 1049 break; 1050 } 1051 return (error ? error : error2); 1052 } 1053 1054 /* 1055 * Perform a full round of TRANS2 request 1056 */ 1057 static int 1058 smb_t2_request_int(struct smb_t2rq *t2p) 1059 { 1060 struct smb_vc *vcp = t2p->t2_vc; 1061 struct smb_cred *scred = t2p->t2_cred; 1062 struct mbchain *mbp; 1063 struct mdchain *mdp, mbparam, mbdata; 1064 mblk_t *m; 1065 struct smb_rq *rqp; 1066 int totpcount, leftpcount, totdcount, leftdcount, len, txmax, i; 1067 int error, doff, poff, txdcount, txpcount, nmlen, nmsize; 1068 1069 m = t2p->t2_tparam.mb_top; 1070 if (m) { 1071 md_initm(&mbparam, m); /* do not free it! */ 1072 totpcount = m_fixhdr(m); 1073 if (totpcount > 0xffff) /* maxvalue for ushort_t */ 1074 return (EINVAL); 1075 } else 1076 totpcount = 0; 1077 m = t2p->t2_tdata.mb_top; 1078 if (m) { 1079 md_initm(&mbdata, m); /* do not free it! */ 1080 totdcount = m_fixhdr(m); 1081 if (totdcount > 0xffff) 1082 return (EINVAL); 1083 } else 1084 totdcount = 0; 1085 leftdcount = totdcount; 1086 leftpcount = totpcount; 1087 txmax = vcp->vc_txmax; 1088 error = smb_rq_alloc(t2p->t2_source, t2p->t_name ? 1089 SMB_COM_TRANSACTION : SMB_COM_TRANSACTION2, scred, &rqp); 1090 if (error) 1091 return (error); 1092 rqp->sr_timo = smb_timo_default; 1093 rqp->sr_flags |= SMBR_MULTIPACKET; 1094 t2p->t2_rq = rqp; 1095 mbp = &rqp->sr_rq; 1096 smb_rq_wstart(rqp); 1097 mb_put_uint16le(mbp, totpcount); 1098 mb_put_uint16le(mbp, totdcount); 1099 mb_put_uint16le(mbp, t2p->t2_maxpcount); 1100 mb_put_uint16le(mbp, t2p->t2_maxdcount); 1101 mb_put_uint8(mbp, t2p->t2_maxscount); 1102 mb_put_uint8(mbp, 0); /* reserved */ 1103 mb_put_uint16le(mbp, 0); /* flags */ 1104 mb_put_uint32le(mbp, 0); /* Timeout */ 1105 mb_put_uint16le(mbp, 0); /* reserved 2 */ 1106 len = mb_fixhdr(mbp); 1107 1108 /* 1109 * Now we know the size of the trans overhead stuff: 1110 * ALIGN4(len + 5 * 2 + setupcount * 2 + 2 + nmsize), 1111 * where nmsize is the OTW size of the name, including 1112 * the unicode null terminator and any alignment. 1113 * Use this to decide which parts (and how much) 1114 * can go into this request: params, data 1115 */ 1116 nmlen = t2p->t_name ? t2p->t_name_len : 0; 1117 nmsize = nmlen + 1; /* null term. */ 1118 if (SMB_UNICODE_STRINGS(vcp)) { 1119 nmsize *= 2; 1120 /* we know put_dmem will need to align */ 1121 nmsize += 1; 1122 } 1123 len = ALIGN4(len + 5 * 2 + t2p->t2_setupcount * 2 + 2 + nmsize); 1124 if (len + leftpcount > txmax) { 1125 txpcount = min(leftpcount, txmax - len); 1126 poff = len; 1127 txdcount = 0; 1128 doff = 0; 1129 } else { 1130 txpcount = leftpcount; 1131 poff = txpcount ? len : 0; 1132 /* 1133 * Other client traffic seems to "ALIGN2" here. The extra 1134 * 2 byte pad we use has no observed downside and may be 1135 * required for some old servers(?) 1136 */ 1137 len = ALIGN4(len + txpcount); 1138 txdcount = min(leftdcount, txmax - len); 1139 doff = txdcount ? len : 0; 1140 } 1141 leftpcount -= txpcount; 1142 leftdcount -= txdcount; 1143 mb_put_uint16le(mbp, txpcount); 1144 mb_put_uint16le(mbp, poff); 1145 mb_put_uint16le(mbp, txdcount); 1146 mb_put_uint16le(mbp, doff); 1147 mb_put_uint8(mbp, t2p->t2_setupcount); 1148 mb_put_uint8(mbp, 0); 1149 for (i = 0; i < t2p->t2_setupcount; i++) { 1150 mb_put_uint16le(mbp, t2p->t2_setupdata[i]); 1151 } 1152 smb_rq_wend(rqp); 1153 smb_rq_bstart(rqp); 1154 if (t2p->t_name) { 1155 /* Put the string and terminating null. */ 1156 error = smb_put_dmem(mbp, vcp, t2p->t_name, nmlen + 1, 1157 SMB_CS_NONE, NULL); 1158 } else { 1159 /* nmsize accounts for padding, char size. */ 1160 error = mb_put_mem(mbp, NULL, nmsize, MB_MZERO); 1161 } 1162 if (error) 1163 goto freerq; 1164 len = mb_fixhdr(mbp); 1165 if (txpcount) { 1166 mb_put_mem(mbp, NULL, ALIGN4(len) - len, MB_MZERO); 1167 error = md_get_mbuf(&mbparam, txpcount, &m); 1168 SMBSDEBUG("%d:%d:%d\n", error, txpcount, txmax); 1169 if (error) 1170 goto freerq; 1171 mb_put_mbuf(mbp, m); 1172 } 1173 len = mb_fixhdr(mbp); 1174 if (txdcount) { 1175 mb_put_mem(mbp, NULL, ALIGN4(len) - len, MB_MZERO); 1176 error = md_get_mbuf(&mbdata, txdcount, &m); 1177 if (error) 1178 goto freerq; 1179 mb_put_mbuf(mbp, m); 1180 } 1181 smb_rq_bend(rqp); /* incredible, but thats it... */ 1182 error = smb_rq_enqueue(rqp); 1183 if (error) 1184 goto freerq; 1185 if (leftpcount || leftdcount) { 1186 error = smb_rq_reply(rqp); 1187 if (error) 1188 goto bad; 1189 /* 1190 * this is an interim response, ignore it. 1191 */ 1192 SMBRQ_LOCK(rqp); 1193 md_next_record(&rqp->sr_rp); 1194 SMBRQ_UNLOCK(rqp); 1195 } 1196 while (leftpcount || leftdcount) { 1197 error = smb_rq_new(rqp, t2p->t_name ? 1198 SMB_COM_TRANSACTION_SECONDARY : 1199 SMB_COM_TRANSACTION2_SECONDARY); 1200 if (error) 1201 goto bad; 1202 mbp = &rqp->sr_rq; 1203 smb_rq_wstart(rqp); 1204 mb_put_uint16le(mbp, totpcount); 1205 mb_put_uint16le(mbp, totdcount); 1206 len = mb_fixhdr(mbp); 1207 /* 1208 * now we have known packet size as 1209 * ALIGN4(len + 7 * 2 + 2) for T2 request, and -2 for T one, 1210 * and need to decide which parts should go into request 1211 */ 1212 len = ALIGN4(len + 6 * 2 + 2); 1213 if (t2p->t_name == NULL) 1214 len += 2; 1215 if (len + leftpcount > txmax) { 1216 txpcount = min(leftpcount, txmax - len); 1217 poff = len; 1218 txdcount = 0; 1219 doff = 0; 1220 } else { 1221 txpcount = leftpcount; 1222 poff = txpcount ? len : 0; 1223 len = ALIGN4(len + txpcount); 1224 txdcount = min(leftdcount, txmax - len); 1225 doff = txdcount ? len : 0; 1226 } 1227 mb_put_uint16le(mbp, txpcount); 1228 mb_put_uint16le(mbp, poff); 1229 mb_put_uint16le(mbp, totpcount - leftpcount); 1230 mb_put_uint16le(mbp, txdcount); 1231 mb_put_uint16le(mbp, doff); 1232 mb_put_uint16le(mbp, totdcount - leftdcount); 1233 leftpcount -= txpcount; 1234 leftdcount -= txdcount; 1235 if (t2p->t_name == NULL) 1236 mb_put_uint16le(mbp, t2p->t2_fid); 1237 smb_rq_wend(rqp); 1238 smb_rq_bstart(rqp); 1239 mb_put_uint8(mbp, 0); /* name */ 1240 len = mb_fixhdr(mbp); 1241 if (txpcount) { 1242 mb_put_mem(mbp, NULL, ALIGN4(len) - len, MB_MZERO); 1243 error = md_get_mbuf(&mbparam, txpcount, &m); 1244 if (error) 1245 goto bad; 1246 mb_put_mbuf(mbp, m); 1247 } 1248 len = mb_fixhdr(mbp); 1249 if (txdcount) { 1250 mb_put_mem(mbp, NULL, ALIGN4(len) - len, MB_MZERO); 1251 error = md_get_mbuf(&mbdata, txdcount, &m); 1252 if (error) 1253 goto bad; 1254 mb_put_mbuf(mbp, m); 1255 } 1256 smb_rq_bend(rqp); 1257 error = smb1_iod_multirq(rqp); 1258 if (error) 1259 goto bad; 1260 } /* while left params or data */ 1261 error = smb_t2_reply(t2p); 1262 if (error && !(t2p->t2_flags & SMBT2_MOREDATA)) 1263 goto bad; 1264 mdp = &t2p->t2_rdata; 1265 if (mdp->md_top) { 1266 md_initm(mdp, mdp->md_top); 1267 } 1268 mdp = &t2p->t2_rparam; 1269 if (mdp->md_top) { 1270 md_initm(mdp, mdp->md_top); 1271 } 1272 bad: 1273 smb_iod_removerq(rqp); 1274 freerq: 1275 if (error && !(t2p->t2_flags & SMBT2_MOREDATA)) { 1276 if (rqp->sr_flags & SMBR_RESTART) 1277 t2p->t2_flags |= SMBT2_RESTART; 1278 md_done(&t2p->t2_rparam); 1279 md_done(&t2p->t2_rdata); 1280 } 1281 smb_rq_done(rqp); 1282 return (error); 1283 } 1284 1285 1286 /* 1287 * Perform a full round of NT_TRANSACTION request 1288 */ 1289 static int 1290 smb_nt_request_int(struct smb_ntrq *ntp) 1291 { 1292 struct smb_vc *vcp = ntp->nt_vc; 1293 struct smb_cred *scred = ntp->nt_cred; 1294 struct mbchain *mbp; 1295 struct mdchain *mdp, mbsetup, mbparam, mbdata; 1296 mblk_t *m; 1297 struct smb_rq *rqp; 1298 int totpcount, leftpcount, totdcount, leftdcount, len, txmax; 1299 int error, doff, poff, txdcount, txpcount; 1300 int totscount; 1301 1302 m = ntp->nt_tsetup.mb_top; 1303 if (m) { 1304 md_initm(&mbsetup, m); /* do not free it! */ 1305 totscount = m_fixhdr(m); 1306 if (totscount > 2 * 0xff) 1307 return (EINVAL); 1308 } else 1309 totscount = 0; 1310 m = ntp->nt_tparam.mb_top; 1311 if (m) { 1312 md_initm(&mbparam, m); /* do not free it! */ 1313 totpcount = m_fixhdr(m); 1314 if (totpcount > 0x7fffffff) 1315 return (EINVAL); 1316 } else 1317 totpcount = 0; 1318 m = ntp->nt_tdata.mb_top; 1319 if (m) { 1320 md_initm(&mbdata, m); /* do not free it! */ 1321 totdcount = m_fixhdr(m); 1322 if (totdcount > 0x7fffffff) 1323 return (EINVAL); 1324 } else 1325 totdcount = 0; 1326 leftdcount = totdcount; 1327 leftpcount = totpcount; 1328 txmax = vcp->vc_txmax; 1329 error = smb_rq_alloc(ntp->nt_source, SMB_COM_NT_TRANSACT, scred, &rqp); 1330 if (error) 1331 return (error); 1332 rqp->sr_timo = smb_timo_default; 1333 rqp->sr_flags |= SMBR_MULTIPACKET; 1334 ntp->nt_rq = rqp; 1335 mbp = &rqp->sr_rq; 1336 smb_rq_wstart(rqp); 1337 mb_put_uint8(mbp, ntp->nt_maxscount); 1338 mb_put_uint16le(mbp, 0); /* reserved (flags?) */ 1339 mb_put_uint32le(mbp, totpcount); 1340 mb_put_uint32le(mbp, totdcount); 1341 mb_put_uint32le(mbp, ntp->nt_maxpcount); 1342 mb_put_uint32le(mbp, ntp->nt_maxdcount); 1343 len = mb_fixhdr(mbp); 1344 /* 1345 * now we have known packet size as 1346 * ALIGN4(len + 4 * 4 + 1 + 2 + ((totscount+1)&~1) + 2), 1347 * and need to decide which parts should go into the first request 1348 */ 1349 len = ALIGN4(len + 4 * 4 + 1 + 2 + ((totscount+1)&~1) + 2); 1350 if (len + leftpcount > txmax) { 1351 txpcount = min(leftpcount, txmax - len); 1352 poff = len; 1353 txdcount = 0; 1354 doff = 0; 1355 } else { 1356 txpcount = leftpcount; 1357 poff = txpcount ? len : 0; 1358 len = ALIGN4(len + txpcount); 1359 txdcount = min(leftdcount, txmax - len); 1360 doff = txdcount ? len : 0; 1361 } 1362 leftpcount -= txpcount; 1363 leftdcount -= txdcount; 1364 mb_put_uint32le(mbp, txpcount); 1365 mb_put_uint32le(mbp, poff); 1366 mb_put_uint32le(mbp, txdcount); 1367 mb_put_uint32le(mbp, doff); 1368 mb_put_uint8(mbp, (totscount+1)/2); 1369 mb_put_uint16le(mbp, ntp->nt_function); 1370 if (totscount) { 1371 error = md_get_mbuf(&mbsetup, totscount, &m); 1372 SMBSDEBUG("%d:%d:%d\n", error, totscount, txmax); 1373 if (error) 1374 goto freerq; 1375 mb_put_mbuf(mbp, m); 1376 if (totscount & 1) 1377 mb_put_uint8(mbp, 0); /* setup is in words */ 1378 } 1379 smb_rq_wend(rqp); 1380 smb_rq_bstart(rqp); 1381 len = mb_fixhdr(mbp); 1382 if (txpcount) { 1383 mb_put_mem(mbp, NULL, ALIGN4(len) - len, MB_MZERO); 1384 error = md_get_mbuf(&mbparam, txpcount, &m); 1385 SMBSDEBUG("%d:%d:%d\n", error, txpcount, txmax); 1386 if (error) 1387 goto freerq; 1388 mb_put_mbuf(mbp, m); 1389 } 1390 len = mb_fixhdr(mbp); 1391 if (txdcount) { 1392 mb_put_mem(mbp, NULL, ALIGN4(len) - len, MB_MZERO); 1393 error = md_get_mbuf(&mbdata, txdcount, &m); 1394 if (error) 1395 goto freerq; 1396 mb_put_mbuf(mbp, m); 1397 } 1398 smb_rq_bend(rqp); /* incredible, but thats it... */ 1399 error = smb_rq_enqueue(rqp); 1400 if (error) 1401 goto freerq; 1402 if (leftpcount || leftdcount) { 1403 error = smb_rq_reply(rqp); 1404 if (error) 1405 goto bad; 1406 /* 1407 * this is an interim response, ignore it. 1408 */ 1409 SMBRQ_LOCK(rqp); 1410 md_next_record(&rqp->sr_rp); 1411 SMBRQ_UNLOCK(rqp); 1412 } 1413 while (leftpcount || leftdcount) { 1414 error = smb_rq_new(rqp, SMB_COM_NT_TRANSACT_SECONDARY); 1415 if (error) 1416 goto bad; 1417 mbp = &rqp->sr_rq; 1418 smb_rq_wstart(rqp); 1419 mb_put_mem(mbp, NULL, 3, MB_MZERO); 1420 mb_put_uint32le(mbp, totpcount); 1421 mb_put_uint32le(mbp, totdcount); 1422 len = mb_fixhdr(mbp); 1423 /* 1424 * now we have known packet size as 1425 * ALIGN4(len + 6 * 4 + 2) 1426 * and need to decide which parts should go into request 1427 */ 1428 len = ALIGN4(len + 6 * 4 + 2); 1429 if (len + leftpcount > txmax) { 1430 txpcount = min(leftpcount, txmax - len); 1431 poff = len; 1432 txdcount = 0; 1433 doff = 0; 1434 } else { 1435 txpcount = leftpcount; 1436 poff = txpcount ? len : 0; 1437 len = ALIGN4(len + txpcount); 1438 txdcount = min(leftdcount, txmax - len); 1439 doff = txdcount ? len : 0; 1440 } 1441 mb_put_uint32le(mbp, txpcount); 1442 mb_put_uint32le(mbp, poff); 1443 mb_put_uint32le(mbp, totpcount - leftpcount); 1444 mb_put_uint32le(mbp, txdcount); 1445 mb_put_uint32le(mbp, doff); 1446 mb_put_uint32le(mbp, totdcount - leftdcount); 1447 leftpcount -= txpcount; 1448 leftdcount -= txdcount; 1449 smb_rq_wend(rqp); 1450 smb_rq_bstart(rqp); 1451 len = mb_fixhdr(mbp); 1452 if (txpcount) { 1453 mb_put_mem(mbp, NULL, ALIGN4(len) - len, MB_MZERO); 1454 error = md_get_mbuf(&mbparam, txpcount, &m); 1455 if (error) 1456 goto bad; 1457 mb_put_mbuf(mbp, m); 1458 } 1459 len = mb_fixhdr(mbp); 1460 if (txdcount) { 1461 mb_put_mem(mbp, NULL, ALIGN4(len) - len, MB_MZERO); 1462 error = md_get_mbuf(&mbdata, txdcount, &m); 1463 if (error) 1464 goto bad; 1465 mb_put_mbuf(mbp, m); 1466 } 1467 smb_rq_bend(rqp); 1468 error = smb1_iod_multirq(rqp); 1469 if (error) 1470 goto bad; 1471 } /* while left params or data */ 1472 error = smb_nt_reply(ntp); 1473 if (error && !(ntp->nt_flags & SMBT2_MOREDATA)) 1474 goto bad; 1475 mdp = &ntp->nt_rdata; 1476 if (mdp->md_top) { 1477 md_initm(mdp, mdp->md_top); 1478 } 1479 mdp = &ntp->nt_rparam; 1480 if (mdp->md_top) { 1481 md_initm(mdp, mdp->md_top); 1482 } 1483 bad: 1484 smb_iod_removerq(rqp); 1485 freerq: 1486 if (error && !(ntp->nt_flags & SMBT2_MOREDATA)) { 1487 if (rqp->sr_flags & SMBR_RESTART) 1488 ntp->nt_flags |= SMBT2_RESTART; 1489 md_done(&ntp->nt_rparam); 1490 md_done(&ntp->nt_rdata); 1491 } 1492 smb_rq_done(rqp); 1493 return (error); 1494 } 1495 1496 int 1497 smb_t2_request(struct smb_t2rq *t2p) 1498 { 1499 int error = EINVAL, i; 1500 1501 for (i = 0; ; ) { 1502 /* 1503 * Don't send any new requests if force unmount is underway. 1504 * This check was moved into smb_rq_enqueue, called by 1505 * smb_t2_request_int() 1506 */ 1507 t2p->t2_flags &= ~SMBT2_RESTART; 1508 error = smb_t2_request_int(t2p); 1509 if (!error) 1510 break; 1511 if ((t2p->t2_flags & (SMBT2_RESTART | SMBT2_NORESTART)) != 1512 SMBT2_RESTART) 1513 break; 1514 if (++i > SMBMAXRESTARTS) 1515 break; 1516 mutex_enter(&(t2p)->t2_lock); 1517 if (t2p->t2_share) { 1518 (void) cv_reltimedwait(&t2p->t2_cond, &(t2p)->t2_lock, 1519 SEC_TO_TICK(SMB_RCNDELAY), TR_CLOCK_TICK); 1520 } else { 1521 delay(SEC_TO_TICK(SMB_RCNDELAY)); 1522 } 1523 mutex_exit(&(t2p)->t2_lock); 1524 } 1525 return (error); 1526 } 1527 1528 1529 int 1530 smb_nt_request(struct smb_ntrq *ntp) 1531 { 1532 int error = EINVAL, i; 1533 1534 for (i = 0; ; ) { 1535 /* 1536 * Don't send any new requests if force unmount is underway. 1537 * This check was moved into smb_rq_enqueue, called by 1538 * smb_nt_request_int() 1539 */ 1540 ntp->nt_flags &= ~SMBT2_RESTART; 1541 error = smb_nt_request_int(ntp); 1542 if (!error) 1543 break; 1544 if ((ntp->nt_flags & (SMBT2_RESTART | SMBT2_NORESTART)) != 1545 SMBT2_RESTART) 1546 break; 1547 if (++i > SMBMAXRESTARTS) 1548 break; 1549 mutex_enter(&(ntp)->nt_lock); 1550 if (ntp->nt_share) { 1551 (void) cv_reltimedwait(&ntp->nt_cond, &(ntp)->nt_lock, 1552 SEC_TO_TICK(SMB_RCNDELAY), TR_CLOCK_TICK); 1553 1554 } else { 1555 delay(SEC_TO_TICK(SMB_RCNDELAY)); 1556 } 1557 mutex_exit(&(ntp)->nt_lock); 1558 } 1559 return (error); 1560 } 1561 1562 /* 1563 * Run an SMB transact named pipe. 1564 * Note: send_mb is consumed. 1565 */ 1566 int 1567 smb_t2_xnp(struct smb_share *ssp, uint16_t fid, 1568 struct mbchain *send_mb, struct mdchain *recv_md, 1569 uint32_t *data_out_sz, /* max / returned */ 1570 uint32_t *more, struct smb_cred *scrp) 1571 { 1572 struct smb_t2rq *t2p = NULL; 1573 mblk_t *m; 1574 uint16_t setup[2]; 1575 int err; 1576 1577 setup[0] = TRANS_TRANSACT_NAMED_PIPE; 1578 setup[1] = fid; 1579 1580 t2p = kmem_alloc(sizeof (*t2p), KM_SLEEP); 1581 err = smb_t2_init(t2p, SSTOCP(ssp), setup, 2, scrp); 1582 if (err) { 1583 *data_out_sz = 0; 1584 goto out; 1585 } 1586 1587 t2p->t2_setupcount = 2; 1588 t2p->t2_setupdata = setup; 1589 1590 t2p->t_name = "\\PIPE\\"; 1591 t2p->t_name_len = 6; 1592 1593 t2p->t2_maxscount = 0; 1594 t2p->t2_maxpcount = 0; 1595 t2p->t2_maxdcount = (uint16_t)*data_out_sz; 1596 1597 /* Transmit parameters (none) */ 1598 1599 /* 1600 * Transmit data 1601 * 1602 * Copy the mb, and clear the source so we 1603 * don't end up with a double free. 1604 */ 1605 t2p->t2_tdata = *send_mb; 1606 bzero(send_mb, sizeof (*send_mb)); 1607 1608 /* 1609 * Run the request 1610 */ 1611 err = smb_t2_request(t2p); 1612 1613 /* No returned parameters. */ 1614 1615 if (err == 0 && (m = t2p->t2_rdata.md_top) != NULL) { 1616 /* 1617 * Received data 1618 * 1619 * Copy the mdchain, and clear the source so we 1620 * don't end up with a double free. 1621 */ 1622 *data_out_sz = msgdsize(m); 1623 md_initm(recv_md, m); 1624 t2p->t2_rdata.md_top = NULL; 1625 } else { 1626 *data_out_sz = 0; 1627 } 1628 1629 if (t2p->t2_sr_error == NT_STATUS_BUFFER_OVERFLOW) 1630 *more = 1; 1631 1632 out: 1633 if (t2p != NULL) { 1634 /* Note: t2p->t_name no longer allocated */ 1635 smb_t2_done(t2p); 1636 kmem_free(t2p, sizeof (*t2p)); 1637 } 1638 1639 return (err); 1640 } 1641