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