Exemplo n.º 1
0
SmbProcessResult
smbcomwriteandx(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
{
	uchar andxcommand;
	ushort andxoffset;
	ulong andxoffsetfixup;
	SmbTree *t;
	SmbFile *f;
	ushort dataoff, fid, count;
	vlong offset;
	long nb;

	if (h->wordcount != 12 && h->wordcount != 14)
		return SmbProcessResultFormat;

	andxcommand = *pdata++;				// andx command
	pdata++;					// reserved 
	andxoffset = smbnhgets(pdata); pdata += 2;	// andx offset
	fid = smbnhgets(pdata); pdata += 2;		// fid
	offset = smbnhgetl(pdata); pdata += 4;		// offset in file
	pdata += 4;					// timeout
	pdata += 2;					// write mode
	pdata += 2;					// (Remaining) bytes waiting to be written
	pdata += 2;					// Reserved
	count = smbnhgets(pdata); pdata += 2;		// LSBs of length
	dataoff = smbnhgets(pdata); pdata += 2;		// offset to data in packet
	if (dataoff + count > smbbufferwriteoffset(b))
		return SmbProcessResultFormat;
	if(h->wordcount == 14)
		offset |= (vlong)smbnhgetl(pdata)<<32;

	smblogprint(SMB_COM_WRITE_ANDX, "smbcomwriteandx: fid 0x%.4ux count 0x%.4ux offset 0x%.llux\n",
		fid, count, offset);


	t = smbidmapfind(s->tidmap, h->tid);
	if (t == nil) {
		smbseterror(s, ERRSRV, ERRinvtid);
		return SmbProcessResultError;
	}
	f = smbidmapfind(s->fidmap, fid);
	if (f == nil) {
		smbseterror(s, ERRDOS, ERRbadfid);
		return SmbProcessResultError;
	}

	if (!f->ioallowed) {
		smbseterror(s, ERRDOS, ERRbadaccess);
		return SmbProcessResultError;
	}

	seek(f->fd, offset, 0);
	nb = write(f->fd, smbbufferpointer(b, dataoff), count);
	if (nb < 0) {
		smbseterror(s, ERRDOS, ERRnoaccess);
		return SmbProcessResultError;
	}

	h->wordcount = 6;
	if (!smbbufferputandxheader(s->response, h, &s->peerinfo, andxcommand, &andxoffsetfixup))
		return SmbProcessResultMisc;

	if (!smbbufferputs(s->response, nb)			// Count
		|| !smbbufferputs(s->response, 0)		// Available
		|| !smbbufferputl(s->response, 0)		// Reserved
		|| !smbbufferputs(s->response, 0))		// byte count in reply
		return SmbProcessResultMisc;

	if (andxcommand != SMB_COM_NO_ANDX_COMMAND)
		return smbchaincommand(s, h, andxoffsetfixup, andxcommand, andxoffset, b);

	return SmbProcessResultReply;
}
Exemplo n.º 2
0
int
_smbtransactiondecodeprimary(SmbTransaction *t, SmbHeader *h, uint8_t *pdata,
			     SmbBuffer *b, int hasname, char **errmsgp)
{
	uint16_t poffset, doffset;

	if (h->wordcount < 14) {
		smbstringprint(errmsgp, "word count less than 14");
		return -1;
	}
	t->in.scount = pdata[13 * 2];
	if (h->wordcount != 14 + t->in.scount) {
		smbstringprint(errmsgp, "smbcomtransaction: word count invalid\n");
		return -1;
	}
	t->in.tpcount = smbnhgets(pdata); pdata += 2;
	t->in.tdcount = smbnhgets(pdata); pdata += 2;
	t->in.maxpcount = smbnhgets(pdata); pdata += 2;
	t->in.maxdcount = smbnhgets(pdata); pdata += 2;
	t->in.maxscount = *pdata++;
	pdata++;
	t->in.flags = smbnhgets(pdata); pdata += 2;
	pdata += 4; /* timeout */
	pdata += 2;
	t->in.pcount = smbnhgets(pdata); pdata += 2;
	poffset = smbnhgets(pdata); pdata += 2;
	t->in.dcount = smbnhgets(pdata); pdata += 2;
	doffset = smbnhgets(pdata); pdata += 2;
	pdata++; /* scount */
	pdata++; /* reserved */
	smbfree(&t->in.setup);
	if (t->in.scount) {
		int x;
		t->in.setup = smbemalloc(t->in.scount * sizeof(uint16_t));
		for (x = 0; x < t->in.scount; x++) {
			t->in.setup[x] = smbnhgets(pdata);
			pdata += 2;
		}
	}
	smbfree(&t->in.name);
	if (hasname && !smbbuffergetstring(b, h, SMB_STRING_PATH, &t->in.name)) {
		smbstringprint(errmsgp, "not enough bdata for name");
		return -1;
	}
	if (poffset + t->in.pcount > smbbufferwriteoffset(b)) {
		smbstringprint(errmsgp, "not enough bdata for parameters");
		return -1;
	}
	if (t->in.pcount > t->in.tpcount) {
		smbstringprint(errmsgp, "too many parameters");
		return -1;
	}
	smbfree(&t->in.parameters);
	t->in.parameters = smbemalloc(t->in.tpcount);
	memcpy(t->in.parameters, smbbufferpointer(b, poffset), t->in.pcount);
	if (doffset + t->in.dcount > smbbufferwriteoffset(b)) {
		smbstringprint(errmsgp, "not enough bdata for data");
		return -1;
	}
	if (t->in.dcount > t->in.tdcount) {
		smbstringprint(errmsgp, "too much data");
		return -1;
	}
	smbfree(&t->in.data);
	t->in.data = smbemalloc(t->in.tdcount);
	memcpy(t->in.data, smbbufferpointer(b, doffset), t->in.dcount);
	if (t->in.dcount < t->in.tdcount || t->in.pcount < t->in.tpcount)
		return 0;
	return 1;
}