示例#1
0
int
_transactionencoderesponse(SmbTransaction *t, SmbHeader *h, SmbPeerInfo *p, SmbBuffer *ob,
			   uint8_t cmd,
	char **errmsgp)
{
	SmbHeader mh;
	uint32_t countsfixupoffset, bytecountfixupoffset;
	int palign, dalign;
	uint32_t pbytecount, dbytecount;
	uint32_t poffset, doffset;

	if (t->in.maxpcount > 65535 || t->in.maxdcount > 65535) {
		smbstringprint(errmsgp, "counts too big");
		return 0;
	}
	mh = *h;
	mh.wordcount = 10;
	mh.flags &= ~SMB_FLAGS_SERVER_TO_REDIR;
	mh.command = cmd;
	mh.errclass = SUCCESS;
	mh.error = SUCCESS;
	if (!smbbufferputheader(ob, &mh, p)
		|| !smbbufferputs(ob, smbbufferwriteoffset(t->out.parameters))
		|| !smbbufferputs(ob, smbbufferwriteoffset(t->out.data))
		|| !smbbufferputs(ob, 0)) {
	toosmall:
		smbstringprint(errmsgp, "output buffer too small");
		goto toosmall;
	}
	countsfixupoffset = smbbufferwriteoffset(ob);
	if (!smbbufferputbytes(ob, nil, 6 * sizeof(uint16_t))
		|| !smbbufferputb(ob, 0)	// scount == 0
		|| !smbbufferputb(ob, 0))	// reserved2
		goto toosmall;
	/* now the byte count */
	bytecountfixupoffset = smbbufferwriteoffset(ob);
	if (!smbbufferputs(ob, 0))
		goto toosmall;
	smbbufferwritelimit(ob, smbbufferwriteoffset(ob) + 65535);
	palign = bytecountfixupoffset & 1;
	if (palign && !smbbufferputb(ob, 0))
		goto toosmall;
	pbytecount = smbbufferreadspace(t->out.parameters);
	if (pbytecount > smbbufferwritespace(ob))
		pbytecount = smbbufferwritespace(ob);
	poffset = smbbufferwriteoffset(ob);
	if (poffset > 65535)
		goto toosmall;
	if (!smbbufferputbytes(ob, smbbufferreadpointer(t->out.parameters), pbytecount))
		goto toosmall;
	dalign = smbbufferwritespace(ob) > 0 && (smbbufferwriteoffset(ob) & 1) != 0;
	if (dalign && !smbbufferputb(ob, 0))
		goto toosmall;
	dbytecount = smbbufferreadspace(t->out.data);
	if (dbytecount > smbbufferwritespace(ob))
		dbytecount = smbbufferwritespace(ob);
	doffset = smbbufferwriteoffset(ob);
	if (doffset > 65535)
		goto toosmall;
	if (!smbbufferputbytes(ob, smbbufferreadpointer(t->out.data), dbytecount))
		goto toosmall;
	if (!smbbufferoffsetputs(ob, bytecountfixupoffset, palign + pbytecount + dalign + dbytecount)
		|| !smbbufferoffsetputs(ob, countsfixupoffset, pbytecount)
		|| !smbbufferoffsetputs(ob, countsfixupoffset + 2, poffset)
		|| !smbbufferoffsetputs(ob, countsfixupoffset + 4, smbbufferreadoffset(t->out.parameters))
		|| !smbbufferoffsetputs(ob, countsfixupoffset + 6, dbytecount)
		|| !smbbufferoffsetputs(ob, countsfixupoffset + 8, doffset)
		|| !smbbufferoffsetputs(ob, countsfixupoffset + 10, smbbufferreadoffset(t->out.data)))
		goto toosmall;
	assert(smbbufferoffsetputs(ob, bytecountfixupoffset, smbbufferwriteoffset(ob) - bytecountfixupoffset - 2));
	smbbuffergetbytes(t->out.parameters, nil, pbytecount);
	smbbuffergetbytes(t->out.data, nil, dbytecount);
	return 1;
}
示例#2
0
int
smbresponseoffsetputs(SmbSession *sess, ushort offset, ushort s)
{
	return smbbufferoffsetputs(sess->response, offset, s);
}
示例#3
0
static int
_transactionencodeprimary(SmbTransaction *t, uint8_t cmd, SmbHeader *h,
			  SmbPeerInfo *p, SmbBuffer *ob,
	uint8_t *wordcountp, uint16_t *bytecountp, char **errmsgp)
{
	SmbHeader mh;
	uint32_t countsfixupoffset, bytecountfixupoffset;
	int x;
	mh = *h;
	*wordcountp = mh.wordcount = 14 + t->in.scount;
	mh.flags &= ~SMB_FLAGS_SERVER_TO_REDIR;
	mh.command = cmd;
	if (!smbbufferputheader(ob, &mh, p)) {
	toosmall:
		smbstringprint(errmsgp, "output buffer too small");
		return 0;
	}
	if (t->in.tpcount > 65535 || t->in.tdcount > 65535 || t->in.maxpcount > 65535 || t->in.maxdcount > 65535) {
		smbstringprint(errmsgp, "counts too big");
		return 0;
	}
	if (!smbbufferputs(ob, t->in.tpcount)
		|| !smbbufferputs(ob, t->in.tdcount)
		|| !smbbufferputs(ob, t->in.maxpcount)
		|| !smbbufferputs(ob, t->in.maxdcount)
		|| !smbbufferputb(ob, t->in.maxscount)
		|| !smbbufferputb(ob, 0)
		|| !smbbufferputs(ob, t->in.flags)
		|| !smbbufferputl(ob, 0)
		|| !smbbufferputs(ob, 0))
		goto toosmall;
	countsfixupoffset = smbbufferwriteoffset(ob);
	if (!smbbufferputs(ob, 0)
		|| !smbbufferputs(ob, 0)
		|| !smbbufferputs(ob, 0)
		|| !smbbufferputs(ob, 0))
		goto toosmall;
	if (!smbbufferputb(ob, t->in.scount)
		|| !smbbufferputb(ob, 0))
		goto toosmall;
	for (x = 0; x < t->in.scount; x++)
		if (!smbbufferputs(ob, t->in.setup[x]))
			goto toosmall;
	bytecountfixupoffset = smbbufferwriteoffset(ob);
	if (!smbbufferputs(ob, 0))
		goto toosmall;
	smbbufferwritelimit(ob, smbbufferwriteoffset(ob) + 65535);
	if (!smbbufferputstring(ob, p, SMB_STRING_UPCASE, t->in.name))
		goto toosmall;
	if (t->in.pcount < t->in.tpcount) {
		uint32_t align = smbbufferwriteoffset(ob) & 1;
		uint32_t pthistime;
		pthistime = smbbufferwritespace(ob) - align;
		if (pthistime > t->in.tpcount - t->in.pcount)
			pthistime = t->in.tpcount - t->in.pcount;
		if (pthistime > 65535)
			pthistime = 65535;
		if (smbbufferwriteoffset(ob) > 65535)
			pthistime = 0;
		if (pthistime) {
			assert(smbbufferalignl2(ob, 0));
			assert(smbbufferoffsetputs(ob, countsfixupoffset, pthistime));
			assert(smbbufferoffsetputs(ob, countsfixupoffset + 2, smbbufferwriteoffset(ob)));
			assert(smbbufferputbytes(ob, t->in.parameters + t->in.pcount, pthistime));
		}
		t->in.pcount += pthistime;
	}
	if (t->in.dcount < t->in.tdcount) {
		uint32_t align = smbbufferwriteoffset(ob) & 1;
		uint32_t dthistime;
		dthistime = smbbufferwritespace(ob) - align;
		if (dthistime > t->in.tdcount - t->in.dcount)
			dthistime = t->in.tdcount - t->in.dcount;
		if (dthistime > 65535)
			dthistime = 65535;
		if (smbbufferwriteoffset(ob) > 65535)
			dthistime = 0;
		if (dthistime) {
			assert(smbbufferalignl2(ob, 0));
			assert(smbbufferoffsetputs(ob, countsfixupoffset + 4, dthistime));
			assert(smbbufferoffsetputs(ob, countsfixupoffset + 6, smbbufferwriteoffset(ob)));
			assert(smbbufferputbytes(ob, t->in.data + t->in.dcount, dthistime));
		}
		t->in.dcount += dthistime;
	}
	*bytecountp = smbbufferwriteoffset(ob) - bytecountfixupoffset - 2;
	assert(smbbufferoffsetputs(ob, bytecountfixupoffset, *bytecountp));
	return 1;
}