コード例 #1
0
ファイル: smbresponse.c プロジェクト: 99years/plan9
SmbProcessResult
smbresponsesend(SmbSession *s)
{
	uchar cmd;
	SmbProcessResult pr;

	assert(smbbufferoffsetgetb(s->response, 4, &cmd));
smbloglock();
smblogprint(cmd, "sending:\n");
smblogdata(cmd, smblogprint, smbbufferreadpointer(s->response), smbbufferreadspace(s->response), 256);
smblogunlock();
	if (s->nbss) {
		NbScatterGather a[2];
		a[0].p = smbbufferreadpointer(s->response);
		a[0].l = smbbufferreadspace(s->response);
		a[1].p = nil;
		nbssgatherwrite(s->nbss, a);
		pr = SmbProcessResultOk;
	}
	else if (s->cifss) {
		ulong l = smbbufferreadspace(s->response);
		uchar nl[4];
		hnputl(nl, l);
		write(s->cifss->fd, nl, 4);
		write(s->cifss->fd, smbbufferreadpointer(s->response), l);
		pr = SmbProcessResultOk;
	}
	else
		pr = SmbProcessResultDie;
	smbbufferreset(s->response);
	return pr;
}
コード例 #2
0
ファイル: smbcommon.c プロジェクト: bhanug/harvey
int
smbbufferputheader(SmbBuffer *b, SmbHeader *h, SmbPeerInfo *p)
{
	SmbRawHeader *rh;
	if (offsetof(SmbRawHeader, parameterwords[0]) > smbbufferwritespace(b))
		return 0;
	if (smbbufferwriteoffset(b) == 0) {
		rh = (SmbRawHeader *)smbbufferwritepointer(b);
		rh->protocol[0] = 0xff;
		memcpy(rh->protocol + 1, "SMB", 3);
		rh->flags = SMB_FLAGS_SERVER_TO_REDIR | SmbHeaderFlagCaseless;
		rh->command = h->command;
		smbhnputs(rh->flags2, BASE_FLAGS | (smbsendunicode(p) ? SMB_FLAGS2_UNICODE : 0));
		memset(rh->extra, 0, sizeof(rh->extra));
		if (!smbbufferputbytes(b, nil, offsetof(SmbRawHeader, parameterwords[0])))
			return 0;
		rh->wordcount = h->wordcount;
	}
	else {
		rh = (SmbRawHeader *)smbbufferreadpointer(b);
		smbbufferputb(b, h->wordcount);
	}
	rh->status[0] = h->errclass;
	rh->status[1] = 0;
	smbhnputs(rh->status + 2, h->error);
	smbhnputs(rh->tid, h->tid);
	smbhnputs(rh->pid, h->pid);
	smbhnputs(rh->uid, h->uid);
	smbhnputs(rh->mid, h->mid);
	return 1;
}
コード例 #3
0
ファイル: smbcommon.c プロジェクト: bhanug/harvey
int
smbbuffergetheader(SmbBuffer *b, SmbHeader *h, uint8_t **parametersp,
		   uint16_t *bytecountp)
{
	SmbOpTableEntry *ote;
	SmbRawHeader *rh;
	rh = (SmbRawHeader *)smbbufferreadpointer(b);
	if (!smbbuffergetbytes(b, nil, (int32_t)offsetof(SmbRawHeader, parameterwords[0]))) {
		smblogprint(-1, "smbgetheader: short packet\n");
		return 0;
	}
	if (rh->protocol[0] != 0xff || memcmp(rh->protocol + 1, "SMB", 3) != 0) {
		smblogprint(-1, "smbgetheader: invalid protocol\n");
		return 0;
	}
	h->command = rh->command;
	ote = smboptable + h->command;
	if (ote->name == nil) {
		smblogprint(-1, "smbgetheader: illegal opcode 0x%.2ux\n", h->command);
		return 0;
	}
	h->errclass = rh->status[0];
	h->error = smbnhgets(rh->status + 2);
	h->flags = rh->flags;
	h->flags2 = smbnhgets(rh->flags2);
	if (h->flags & ~(SmbHeaderFlagCaseless | SMB_FLAGS_SERVER_TO_REDIR | SmbHeaderFlagReserved | SmbHeaderFlagServerIgnore))
		smblogprint(-1, "smbgetheader: warning: unexpected flags 0x%.2ux\n", h->flags);
	h->wordcount = rh->wordcount;
	if (parametersp)
		*parametersp = smbbufferreadpointer(b);
	if (!smbbuffergetbytes(b, nil, h->wordcount * 2)) {
		smblogprint(-1, "smbgetheader: not enough data for parameter words\n");
		return 0;
	}
	h->tid = smbnhgets(rh->tid);
	h->pid = smbnhgets(rh->pid);
	h->uid = smbnhgets(rh->uid);
	h->mid = smbnhgets(rh->mid);
	if (!smbbuffergets(b, bytecountp))
		*bytecountp = 0;
	if (!smbbufferpushreadlimit(b, smbbufferreadoffset(b) + *bytecountp))
		return 0;

smblogprint(h->command, "%s %s: tid 0x%.4ux pid 0x%.4ux uid 0x%.4ux mid 0x%.4ux\n", ote->name,
	(h->flags & SMB_FLAGS_SERVER_TO_REDIR) ? "response" : "request", h->tid, h->pid, h->uid, h->mid);
	return 1;
}
コード例 #4
0
ファイル: smbbuffer.c プロジェクト: AustenConrad/plan-9
int
smbbuffercopy(SmbBuffer *to, SmbBuffer *from, ulong amount)
{
	if (smbbufferreadspace(from) < amount)
		return 0;
	if (smbbufferputbytes(to, smbbufferreadpointer(from), amount)) {
		assert(smbbuffergetbytes(from, nil, amount));
		return 1;
	}
	return 0;
}
コード例 #5
0
ファイル: smbtransaction.c プロジェクト: Requaos/harvey
int
smbtransactionnbdgramsend(void *magic, SmbBuffer *ob, char **errmsgp)
{
	NbDgramSendParameters *p = magic;
//print("sending to %B\n", p->to);
//nbdumpdata(smbbufferreadpointer(ob), smbbufferreadspace(ob));
	if (!nbdgramsend(p, smbbufferreadpointer(ob), smbbufferreadspace(ob))) {
		smbstringprint(errmsgp, "dgram send failed");
		return 0;
	}
	return 1;
}
コード例 #6
0
ファイル: smbclientopen.c プロジェクト: dancrossnyc/harvey
int
smbclientopen(SmbClient *c, uint16_t mode, char *name, uint8_t *errclassp,
	      uint16_t *errorp,
	uint16_t *fidp, uint16_t *attrp, uint32_t *mtimep, uint32_t *sizep,
	      uint16_t *accessallowedp, char **errmsgp)
{
	SmbBuffer *b;
	SmbHeader h;
	uint32_t bytecountfixup;
	int32_t n;
	uint8_t *pdata;
	uint16_t bytecount;

	b = smbbuffernew(65535);
	h = c->protoh;
	h.tid = c->sharetid;
	h.command = SMB_COM_OPEN;
	h.wordcount = 2;
	smbbufferputheader(b, &h, &c->peerinfo);
	smbbufferputs(b, mode);
	smbbufferputs(b, 0);
	bytecountfixup = smbbufferwriteoffset(b);
	smbbufferputs(b, 0);
	smbbufferputb(b, 4);
	smbbufferputstring(b, &c->peerinfo, SMB_STRING_REVPATH, name);
	smbbufferfixuprelatives(b, bytecountfixup);
	nbsswrite(c->nbss, smbbufferreadpointer(b), smbbufferwriteoffset(b));
	smbbufferreset(b);
	n = nbssread(c->nbss, smbbufferwritepointer(b), smbbufferwritespace(b));
	if (n < 0) {
		smbstringprint(errmsgp, "read error: %r");
		smbbufferfree(&b);
		return 0;
	}
	smbbuffersetreadlen(b, n);
	if (!smbbuffergetandcheckheader(b, &h, h.command, 7, &pdata, &bytecount, errmsgp)) {
		smbbufferfree(&b);
		return 0;
	}
	if (h.errclass) {
		*errclassp = h.errclass;
		*errorp = h.error;
		smbbufferfree(&b);
		return 0;
	}
	*fidp = smbnhgets(pdata); pdata += 2;
	*attrp = smbnhgets(pdata); pdata += 2;
	*mtimep = smbnhgetl(pdata); pdata += 4;
	*sizep = smbnhgets(pdata); pdata += 4;
	*accessallowedp = smbnhgets(pdata);
	return 1;
}
コード例 #7
0
ファイル: smbtrans2client.c プロジェクト: AustenConrad/plan-9
int
smbclienttrans2(SmbClient *c, uchar scount, ushort *setup, SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata, SmbHeader *rh, char **errmsgp)
{
	SmbTransaction transaction;
	SmbHeader h;
	memset(&transaction, 0, sizeof(transaction));
	transaction.in.scount = scount;
	transaction.in.setup = setup;
	transaction.in.parameters = smbbufferreadpointer(inparam);
	transaction.in.tpcount = smbbufferreadspace(inparam);
	transaction.in.maxpcount = smbbufferwritespace(outparam);
	transaction.in.maxdcount = smbbufferwritespace(outdata);
	transaction.out.parameters = outparam;
	transaction.out.data = outdata;
	h = c->protoh;
	h.tid = c->sharetid;
	h.mid = 0;
	return smbtransactionexecute(&transaction, &h, &c->peerinfo, c->b, &method, c, rh, errmsgp);
}
コード例 #8
0
ファイル: smbrap2client.c プロジェクト: Requaos/harvey
int
smbclientrap(SmbClient *c, SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata,
	     char **errmsgp)
{
	SmbTransaction transaction;
	SmbHeader h;
	memset(&transaction, 0, sizeof(transaction));
	transaction.in.name = smbglobals.pipelanman;
	transaction.in.parameters = smbbufferreadpointer(inparam);
	transaction.in.tpcount = smbbufferreadspace(inparam);
	transaction.in.maxpcount = smbbufferwritespace(outparam);
	transaction.in.maxdcount = smbbufferwritespace(outdata);
	transaction.out.parameters = outparam;
	transaction.out.data = outdata;
	h = c->protoh;
	h.tid = c->ipctid;
	h.mid = 0;
	return smbtransactionexecute(&transaction, &h, &c->peerinfo, c->b, &smbtransactionmethodrap, c, nil, errmsgp);
}
コード例 #9
0
ファイル: smbcommon.c プロジェクト: bhanug/harvey
SmbProcessResult
smbchaincommand(SmbSession *s, SmbHeader *h, uint32_t andxoffsetfixup,
		uint8_t cmd, uint16_t offset, SmbBuffer *b)
{
	SmbOpTableEntry *ote;
	uint8_t *pdata;
	uint16_t bytecount;

	h->command = cmd;
	ote = smboptable + cmd;
	if (ote->process == nil) {
		smblogprint(-1, "smbchaincommand: %s (0x%.2ux) not implemented\n", ote->name, cmd);
		return SmbProcessResultUnimp;
	}
	if (!smbresponsealignl2(s, 2)
		|| !smbresponseoffsetputs(s, andxoffsetfixup, smbresponseoffset(s))
		|| !smbbufferpopreadlimit(b))
		return SmbProcessResultMisc;
	if (!smbbufferreadskipto(b, offset)) {
		smblogprint(-1, "smbchaincommand: illegal offset\n");
		return SmbProcessResultFormat;
	}
	if (!smbbuffergetb(b, &h->wordcount)) {
		smblogprint(-1, "smbchaincommand: not enough space for wordcount\n");
		return SmbProcessResultFormat;
	}
	pdata = smbbufferreadpointer(b);
	if (!smbbuffergetbytes(b, nil, h->wordcount * 2)) {
		smblogprint(-1, "smbchaincommand: not enough space for parameters\n");
		return SmbProcessResultFormat;
	}
	if (!smbbuffergets(b, &bytecount)) {
		smblogprint(-1, "smbchaincommand: not enough space for bytecount\n");
		return SmbProcessResultFormat;
	}
	if (!smbbufferpushreadlimit(b, smbbufferreadoffset(b) + bytecount)) {
		smblogprint(-1, "smbchaincommand: not enough space for bytes\n");
		return SmbProcessResultFormat;
	}
smblogprint(cmd, "chaining to %s\n", ote->name);
	return (*ote->process)(s, h, pdata, b);
}
コード例 #10
0
ファイル: smbcomecho.c プロジェクト: AustenConrad/plan-9
SmbProcessResult
smbcomecho(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
{
	ushort echocount, e;
	if (!smbcheckwordcount("comecho", h, 1))
		return SmbProcessResultFormat;
	echocount = smbnhgets(pdata);
	for (e = 0; e < echocount; e++) {
		ulong bytecountfixupoffset;
		SmbProcessResult pr;
		if (!smbbufferputheader(s->response, h, &s->peerinfo)
			|| !smbbufferputs(s->response, e))
			return SmbProcessResultMisc;
		bytecountfixupoffset = smbbufferwriteoffset(s->response);
		if (!smbbufferputbytes(s->response, smbbufferreadpointer(b), smbbufferreadspace(b))
			|| !smbbufferfixuprelatives(s->response, bytecountfixupoffset))
			return SmbProcessResultMisc;
		pr = smbresponsesend(s);
		if (pr != SmbProcessResultOk)
			return SmbProcessResultDie;
	}
	return SmbProcessResultOk;
}
コード例 #11
0
ファイル: smbtrans2client.c プロジェクト: AustenConrad/plan-9
int
smbclienttrans2findfirst2(SmbClient *c, ushort searchcount, char *filename,
	ushort *sidp, ushort *searchcountp, ushort *endofsearchp,SmbFindFileBothDirectoryInfo *ip, char **errmsgp)
{
	int rv;
	ushort setup;
	SmbBuffer *inparam;
	SmbBuffer *outparam;
	SmbBuffer *outdata;
	SmbHeader rh;
	setup = SMB_TRANS2_FIND_FIRST2;
	inparam = smbbuffernew(512);
	smbbufferputs(inparam, 0x16);
	smbbufferputs(inparam, searchcount);
	smbbufferputs(inparam, 7);
	smbbufferputs(inparam, SMB_FIND_FILE_BOTH_DIRECTORY_INFO);
	smbbufferputl(inparam, 0);
	smbbufferputstring(inparam, &c->peerinfo, 0, filename);
	outparam = smbbuffernew(10);
	outdata = smbbuffernew(65535);
	rv = smbclienttrans2(c, 1, &setup, inparam, outparam, outdata, &rh, errmsgp);
	smbbufferfree(&inparam);
	if (rv) {
		ushort eaerroroffset, lastnameoffset;
		ulong nextentry;
		int i;

		if (!smbbuffergets(outparam, sidp)
			|| !smbbuffergets(outparam, searchcountp)
			|| !smbbuffergets(outparam, endofsearchp)
			|| !smbbuffergets(outparam, &eaerroroffset)
			|| !smbbuffergets(outparam, &lastnameoffset)) {
			smbstringprint(errmsgp, "smbclienttrans2findfirst2: not enough parameters returned");
			rv = 0;
			goto done;
		}
		nextentry = 0;
smblogprint(-1, "returned data:\n");
smblogdata(-1, smblogprint, smbbufferreadpointer(outdata), smbbufferreadspace(outdata), 256);
		for (i = 0; i < *searchcountp; i++) {
			SmbFindFileBothDirectoryInfo *info = ip + i;
			ulong neo, filenamelength, easize;
			uchar shortnamelength;
			if (i && !smbbufferreadskipto(outdata, nextentry)) {
			underflow:
				smbstringprint(errmsgp, "smbclientrans2findfirst2: not enough data returned");
				rv = 0;
				goto done;
			}
			if (!smbbuffergetl(outdata, &neo))
				goto underflow;
			nextentry = smbbufferreadoffset(outdata) + neo - 4;
print("neo 0x%.8lux\n", neo);
			if (!smbbuffergetl(outdata, &info->fileindex)
				|| !smbbuffergetv(outdata, &info->creationtime)
				|| !smbbuffergetv(outdata, &info->lastaccesstime)
				|| !smbbuffergetv(outdata, &info->lastwritetime)
				|| !smbbuffergetv(outdata, &info->changetime)
				|| !smbbuffergetv(outdata, &info->endoffile)
				|| !smbbuffergetv(outdata, &info->allocationsize))
				goto underflow;
print("got here\n");
			if (!smbbuffergetl(outdata, &info->extfileattributes)
				|| !smbbuffergetl(outdata, &filenamelength)
				|| !smbbuffergetl(outdata, &easize)
				|| !smbbuffergetb(outdata, &shortnamelength)
				|| !smbbuffergetbytes(outdata, nil, 1)
				|| !smbbuffergetbytes(outdata, nil, 24)
				|| !smbbuffergetstring(outdata, &rh, SMB_STRING_REVPATH, &info->filename))
				goto underflow;
print("got here as well\n");
		}
	}
done:
	smbbufferfree(&outparam);
	smbbufferfree(&outdata);
	return rv;
}
コード例 #12
0
SmbProcessResult
smbcomsessionsetupandx(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
{
	uchar andxcommand;
	ushort andxoffset;
	ulong andxfixupoffset;
	ushort vcnumber;
	ulong sessionkey;
	ushort caseinsensitivepasswordlength;
	ushort casesensitivepasswordlength;
	ushort bytecountfixup, offset;
	uchar *mschapreply;
	AuthInfo *ai;
	char *sp;
	SmbProcessResult pr;
	char *accountname = nil;
	char *primarydomain = nil;
	char *nativeos = nil;
	char *nativelanman = nil;

	if (!smbcheckwordcount("comsessionsetupandx", h, 13)) {
	fmtfail:
		pr = SmbProcessResultFormat;
		goto done;
	}

	andxcommand = *pdata++;
	switch (andxcommand) {
	case SMB_COM_TREE_CONNECT_ANDX:
	case SMB_COM_OPEN_ANDX:
	case SMB_COM_CREATE_NEW:
	case SMB_COM_DELETE:
	case SMB_COM_FIND:
	case SMB_COM_COPY:
	case SMB_COM_NT_RENAME:
	case SMB_COM_QUERY_INFORMATION:
	case SMB_COM_NO_ANDX_COMMAND:
	case SMB_COM_OPEN:
	case SMB_COM_CREATE:
	case SMB_COM_CREATE_DIRECTORY:
	case SMB_COM_DELETE_DIRECTORY:
	case SMB_COM_FIND_UNIQUE:
	case SMB_COM_RENAME:
	case SMB_COM_CHECK_DIRECTORY:
	case SMB_COM_SET_INFORMATION:
	case SMB_COM_OPEN_PRINT_FILE:
		break;
	default:
		smblogprint(h->command, "smbcomsessionsetupandx: invalid andxcommand %s (0x%.2ux)\n",
			smboptable[andxcommand].name, andxcommand);
		goto fmtfail;
	}
	pdata++;
	andxoffset = smbnhgets(pdata); pdata += 2;
	s->peerinfo.maxlen = smbnhgets(pdata); pdata += 2;
	smbresponseinit(s, s->peerinfo.maxlen);
	s->client.maxmpxcount = smbnhgets(pdata); pdata += 2;
	vcnumber = smbnhgets(pdata); pdata += 2;
	sessionkey = smbnhgetl(pdata); pdata += 4;
	caseinsensitivepasswordlength = smbnhgets(pdata); pdata += 2;
	casesensitivepasswordlength = smbnhgets(pdata); pdata += 2;
	pdata += 4;
	s->peerinfo.capabilities = smbnhgetl(pdata); /*pdata += 4;*/
smbloglock();
smblogprint(h->command, "andxcommand: %s offset %ud\n", smboptable[andxcommand].name, andxoffset);
smblogprint(h->command, "client.maxbuffersize: %ud\n", s->peerinfo.maxlen);
smblogprint(h->command, "client.maxmpxcount: %ud\n", s->client.maxmpxcount);
smblogprint(h->command, "vcnumber: %ud\n", vcnumber);
smblogprint(h->command, "sessionkey: 0x%.8lux\n", sessionkey);
smblogprint(h->command, "caseinsensitivepasswordlength: %ud\n", caseinsensitivepasswordlength);
smblogprint(h->command, "casesensitivepasswordlength: %ud\n", casesensitivepasswordlength);
smblogprint(h->command, "clientcapabilities: 0x%.8lux\n", s->peerinfo.capabilities);
smblogunlock();

	mschapreply = smbbufferreadpointer(b);

	if (!smbbuffergetbytes(b, nil, caseinsensitivepasswordlength + casesensitivepasswordlength)) {
		smblogprint(h->command, "smbcomsessionsetupandx: not enough bdata for passwords\n");
		goto fmtfail;
	}
	if (!smbbuffergetstring(b, h, 0, &accountname)
		|| !smbbuffergetstring(b, h, 0, &primarydomain)
		|| !smbbuffergetstring(b, h, 0, &nativeos)
		|| !smbbuffergetstring(b, h, 0, &nativelanman)) {
		smblogprint(h->command, "smbcomsessionsetupandx: not enough bytes for strings\n");
		goto fmtfail;
	}

	for (sp = accountname; *sp; sp++)
		*sp = tolower(*sp);

smblogprint(h->command, "account: %s\n", accountname);
smblogprint(h->command, "primarydomain: %s\n", primarydomain);
smblogprint(h->command, "nativeos: %s\n", nativeos);
smblogprint(h->command, "nativelanman: %s\n", nativelanman);

	if (s->client.accountname && accountname[0] && strcmp(s->client.accountname, accountname) != 0) {
		smblogprint(h->command, "smbcomsessionsetupandx: more than one user on VC (before %s, now %s)\n",
			s->client.accountname, accountname);
		smbseterror(s, ERRSRV, ERRtoomanyuids);
	errordone:
		pr = SmbProcessResultError;
		goto done;
	}

	if (s->client.accountname == nil) {
		/* first time */
		if (accountname[0] == 0) {
			smbseterror(s, ERRSRV, ERRbaduid);
			goto errordone;
		}
		if ((casesensitivepasswordlength != 24 || caseinsensitivepasswordlength != 24)) {
			smblogprint(h->command,
				"smbcomsessionsetupandx: case sensitive/insensitive password length not 24\n");
			smbseterror(s, ERRSRV, ERRbadpw);
			goto errordone;
		}
		memcpy(&s->client.mschapreply, mschapreply, sizeof(s->client.mschapreply));
		if(s->cs == nil){
			smbseterror(s, ERRSRV, ERRerror);
			goto errordone;
		}
		s->cs->user = accountname;
		s->cs->resp = &s->client.mschapreply;
		s->cs->nresp = sizeof(MSchapreply);
		ai = auth_response(s->cs);
		if (ai == nil) {
			smblogprint(h->command, "authentication failed\n");
			smbseterror(s, ERRSRV, ERRbadpw);
			goto errordone;
		}
		smblogprint(h->command, "authentication succeeded\n");
		if (auth_chuid(ai, nil) < 0) {
			smblogprint(h->command, "smbcomsessionsetupandx: chuid failed: %r\n");
			auth_freeAI(ai);
		miscerror:
			pr = SmbProcessResultMisc;
			goto done;
		}
		auth_freeAI(ai);
		h->uid = 1;
		s->client.accountname = accountname;
		s->client.primarydomain = primarydomain;
		s->client.nativeos = nativeos;
		s->client.nativelanman = nativelanman;
		accountname = nil;
		primarydomain = nil;
		nativeos = nil;
		nativelanman = nil;
	}
	else {
		if (caseinsensitivepasswordlength == 24 && casesensitivepasswordlength == 24
			&& memcmp(&s->client.mschapreply, mschapreply, sizeof(MSchapreply)) != 0) {
			smblogprint(h->command, "second time authentication failed\n");
			smbseterror(s, ERRSRV, ERRbadpw);
			goto errordone;
		}
	}

	/* CIFS says 4 with or without extended security, samba/ms says 3 without */
	h->wordcount = 3;
	if (!smbresponseputandxheader(s, h, andxcommand, &andxfixupoffset))
		goto miscerror;
	if (!smbresponseputs(s, 0))
		goto miscerror;
	bytecountfixup = smbresponseoffset(s);
	if (!smbresponseputs(s, 0))
		goto miscerror;
	if (!smbresponseputstring(s, 1, smbglobals.nativeos)
		|| !smbresponseputstring(s, 1, smbglobals.serverinfo.nativelanman)
		|| !smbresponseputstring(s, 1, smbglobals.primarydomain))
		goto miscerror;
	offset = smbresponseoffset(s);
	smbresponseoffsetputs(s, bytecountfixup, offset - bytecountfixup - 2);
	s->state = SmbSessionEstablished;
	if (andxcommand != SMB_COM_NO_ANDX_COMMAND)
		pr = smbchaincommand(s, h, andxfixupoffset, andxcommand, andxoffset, b);
	else
		pr = SmbProcessResultReply;
done:
	free(accountname);
	free(primarydomain);
	free(nativeos);
	free(nativelanman);
	return pr;
}
コード例 #13
0
ファイル: smbcomwrite.c プロジェクト: CoryXie/nix-os
SmbProcessResult
smbcomwrite(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b)
{
	SmbTree *t;
	SmbFile *f;
	ushort fid;
	ushort count;
	ulong offset;
	long nb;
	ushort yacount;
	uchar fmt;

	if (h->wordcount != 5)
		return SmbProcessResultFormat;

	fid = smbnhgets(pdata); pdata += 2;
	count = smbnhgets(pdata); pdata += 2;
	offset = smbnhgetl(pdata);

	smblogprint(SMB_COM_WRITE, "smbcomwrite: fid 0x%.4ux count 0x%.4ux offset 0x%.8lux\n",
		fid, count, offset);

	if (!smbbuffergetb(b, &fmt)
		|| fmt != 1
		|| !smbbuffergets(b, &yacount)
		|| yacount != count
		|| smbbufferreadspace(b) < count)
		return SmbProcessResultFormat;
	
	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;
	}

	if (count == 0) {
		SmbProcessResult pr = smbtruncatefile(s, f, offset);
		if (pr != SmbProcessResultReply)
			return pr;
		nb = 0;
	}
	else {
		seek(f->fd, offset, 0);
		nb = write(f->fd, smbbufferreadpointer(b), count);
		if (nb < 0) {
			smbseterror(s, ERRDOS, ERRnoaccess);
			return SmbProcessResultError;
		}
	}
	h->wordcount = 1;
	if (!smbbufferputheader(s->response, h, &s->peerinfo)
		|| !smbbufferputs(s->response, nb)
		|| !smbbufferputs(s->response, 0))
		return SmbProcessResultMisc;
	return SmbProcessResultReply;
}
コード例 #14
0
ファイル: smbtransaction.c プロジェクト: Requaos/harvey
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;
}