Exemplo n.º 1
0
int
smbcomtransaction2(SmbSession *s, SmbHeader *h, uint8_t *pdata, SmbBuffer *b)
{
	int rv;
	char *errmsg;
	SmbProcessResult pr = SmbProcessResultDie;
	uint16_t op;

	errmsg = nil;
	rv = smbtransactiondecodeprimary2(&s->transaction, h, pdata, b, &errmsg);
	if (rv < 0) {
	fmtfail:
		pr = SmbProcessResultFormat;
		goto done;
	}
	if (rv == 0) {
		h->wordcount = 0;
		if (smbbufferputack(s->response, h, &s->peerinfo)) {
			pr = SmbProcessResultReply;
			s->nextcommand = SMB_COM_TRANSACTION2_SECONDARY;
		}
		goto done;
	}
	smblogprint(h->command, "smbcomtransaction2: scount %ud tpcount %lud tdcount %lud maxscount %lud maxpcount %lud maxdcount %lud\n",
		s->transaction.in.scount, s->transaction.in.tpcount, s->transaction.in.tdcount,
		s->transaction.in.maxscount, s->transaction.in.maxpcount, s->transaction.in.maxdcount);
	smbbufferfree(&s->transaction.out.parameters);
	smbbufferfree(&s->transaction.out.data);
	s->transaction.out.parameters = smbbuffernew(s->transaction.in.maxpcount);
	s->transaction.out.data = smbbuffernew(s->transaction.in.maxdcount);
	if (s->transaction.in.scount != 1)
		goto fmtfail;
	op = s->transaction.in.setup[0];
	if (op >= smbtrans2optablesize || smbtrans2optable[op].name == nil) {
		smblogprint(-1, "smbcomtransaction2: function %d unknown\n", op);
		pr = SmbProcessResultUnimp;
		goto done;
	}
	if (smbtrans2optable[op].process == nil) {
		smblogprint(-1, "smbcomtransaction2: %s unimplemented\n", smbtrans2optable[op].name);
		pr = SmbProcessResultUnimp;
		goto done;
	}
	pr = (*smbtrans2optable[op].process)(s, h);
	if (pr == SmbProcessResultReply) {
		char *errmsg;
		errmsg = nil;
		rv = smbtransactionrespond(&s->transaction, h, &s->peerinfo, s->response, &smbtransactionmethod2, s, &errmsg);
		if (!rv) {
			smblogprint(h->command, "smbcomtransaction2: failed: %s\n", errmsg);
			pr = SmbProcessResultMisc;
		}
		else
			pr = SmbProcessResultOk;
	}
done:
	free(errmsg);
	return pr;
}
Exemplo n.º 2
0
void
smbtransactionfree(SmbTransaction *t)
{
	free(t->in.parameters);
	free(t->in.data);
	free(t->in.setup);
	free(t->in.name);
	smbbufferfree(&t->out.parameters);
	smbbufferfree(&t->out.data);
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
int
smbcomtransaction(SmbSession *s, SmbHeader *h, uint8_t *pdata, SmbBuffer *b)
{
	int rv;
	char *errmsg;
	SmbProcessResult pr = SmbProcessResultDie;
	errmsg = nil;
	rv = smbtransactiondecodeprimary(&s->transaction, h, pdata, b, &errmsg);
	if (rv < 0) {
		pr = SmbProcessResultFormat;
		goto done;
	}
	if (rv == 0) {
		h->wordcount = 0;
		if (smbbufferputack(s->response, h, &s->peerinfo)) {
			pr = SmbProcessResultReply;
			s->nextcommand = SMB_COM_TRANSACTION_SECONDARY;
		}
		goto done;
	}
	smblogprint(h->command, "smbcomtransaction: %s scount %ud tpcount %lud tdcount %lud maxscount %lud maxpcount %lud maxdcount %lud\n",
		s->transaction.in.name, s->transaction.in.scount, s->transaction.in.tpcount, s->transaction.in.tdcount,
		s->transaction.in.maxscount, s->transaction.in.maxpcount, s->transaction.in.maxdcount);
	smbbufferfree(&s->transaction.out.parameters);
	smbbufferfree(&s->transaction.out.data);
	s->transaction.out.parameters = smbbuffernew(s->transaction.in.maxpcount);
	s->transaction.out.data = smbbuffernew(s->transaction.in.maxdcount);
	if (strcmp(s->transaction.in.name, smbglobals.pipelanman) == 0)
		pr = smbrap2(s);
	else {
		smbseterror(s, ERRDOS, ERRbadpath);
		pr = SmbProcessResultError;
		goto done;
	}
	if (pr == SmbProcessResultReply) {
		char *errmsg;
		errmsg = nil;
		rv = smbtransactionrespond(&s->transaction, h, &s->peerinfo, s->response, &smbtransactionmethod, s, &errmsg);
		if (!rv) {
			smblogprint(h->command, "smbcomtransaction: failed: %s\n", errmsg);
			pr = SmbProcessResultMisc;
		}
		else
			pr = SmbProcessResultOk;
	}
done:
	free(errmsg);
	return pr;
}
Exemplo n.º 5
0
SmbProcessResult
smbrap2(SmbSession *s)
{
	char *pstring;
	char *dstring;
	uint16_t pno;
	RapTableEntry *e;
	SmbProcessResult pr;
	SmbBuffer *inparam;

	inparam = smbbufferinit(s->transaction.in.parameters, s->transaction.in.parameters, s->transaction.in.tpcount);
	if (!smbbuffergets(inparam, &pno)
		|| !smbbuffergetstrinline(inparam, &pstring)
		|| !smbbuffergetstrinline(inparam, &dstring)) {
		smblogprintif(smbglobals.log.rap2, "smbrap2: not enough parameters\n");
		pr = SmbProcessResultFormat;
		goto done;
	}
	if (pno > nelem(raptable) || raptable[pno].name == nil) {
		smblogprint(-1, "smbrap2: unsupported procedure %ud\n", pno);
		pr = SmbProcessResultUnimp;
		goto done;
	}
	e = raptable + pno;
	pr = (*e->procedure)(inparam, s->transaction.out.parameters, s->transaction.out.data);
done:
	smbbufferfree(&inparam);
	return pr;
}
Exemplo n.º 6
0
static void
smbsessionfree(SmbSession *s)
{
	if (s) {
		smbidmapfree(&s->tidmap, disconnecttree, s);
		smbidmapfree(&s->sidmap, closesearch, s);
		smbbufferfree(&s->response);
		free(s->client.accountname);
		free(s->client.primarydomain);
		free(s->client.nativeos);
		free(s->client.nativelanman);
		free(s->transaction.in.parameters);
		free(s->transaction.in.data);
		free(s->transaction.in.setup);
		free(s->transaction.in.name);
		smbbufferfree(&s->transaction.out.parameters);
		smbbufferfree(&s->transaction.out.data);
		auth_freechal(s->cs);
		free(s);
	}
}
Exemplo n.º 7
0
int
smbsessionwrite(SmbSession *smbs, void *p, int32_t n)
{
	SmbHeader h;
	SmbOpTableEntry *ote;
	uint8_t *pdata;
	int rv;
	SmbBuffer *b = nil;
	uint16_t bytecount;
	SmbProcessResult pr;

	if (smbs->response == nil)
		smbs->response = smbbuffernew(576);
	else
		smbresponsereset(smbs);
	smbs->errclass = SUCCESS;
	smbs->error = SUCCESS;
//	print("received %ld bytes\n", n);
	if (n <= 0)
		goto closedown;
	b = smbbufferinit(p, p, n);
	if (!smbbuffergetheader(b, &h, &pdata, &bytecount)) {
		smblogprint(-1, "smb: invalid header\n");
		goto closedown;
	}
smbloglock();
smblogprint(h.command, "received:\n");
smblogdata(h.command, smblogprint, p, n, 0x1000);
smblogunlock();
	ote = smboptable + h.command;
	if (ote->name == nil) {
		smblogprint(-1, "smb: illegal opcode 0x%.2x\n", h.command);
		goto unimp;
	}
	if (ote->process == nil) {
		smblogprint(-1, "smb: opcode %s unimplemented\n", ote->name);
		goto unimp;
	}
	if (smbs->nextcommand != SMB_COM_NO_ANDX_COMMAND
		&& smbs->nextcommand != h.command) {
		smblogprint(-1, "smb: wrong command - expected %.2x\n", smbs->nextcommand);
		goto misc;
	}
	smbs->nextcommand = SMB_COM_NO_ANDX_COMMAND;
	switch (h.command) {
	case SMB_COM_NEGOTIATE:
	case SMB_COM_SESSION_SETUP_ANDX:
	case SMB_COM_TREE_CONNECT_ANDX:
	case SMB_COM_ECHO:
		break;
	default:
		if (smbs->state != SmbSessionEstablished) {
			smblogprint(-1, "aquarela: command %.2x unexpected\n", h.command);
			goto unimp;
		}
	}
	pr = (*ote->process)(smbs, &h, pdata, b);
	switch (pr) {
	case SmbProcessResultUnimp:
	unimp:
		smbseterror(smbs, ERRDOS, ERRunsup);
		pr = SmbProcessResultError;
		break;
	case SmbProcessResultFormat:
		smbseterror(smbs, ERRSRV, ERRsmbcmd);
		pr = SmbProcessResultError;
		break;
	case SmbProcessResultMisc:
	misc:
		smbseterror(smbs, ERRSRV, ERRerror);
		pr = SmbProcessResultError;
		break;
	case SmbProcessResultOk:
	case SmbProcessResultError:
	case SmbProcessResultReply:
	case SmbProcessResultDie:
		break;
	}
	if (pr == SmbProcessResultError) {
		smblogprint(h.command, "reply: error %d/%d\n", smbs->errclass, smbs->error);
		if (!smbresponseputerror(smbs, &h, smbs->errclass, smbs->error))
			pr = SmbProcessResultDie;
		else
			pr = SmbProcessResultReply;
	}
	else
		smblogprint(h.command, "reply: ok\n");
	if (pr == SmbProcessResultReply)
		rv = smbresponsesend(smbs) == SmbProcessResultOk ? 0 : -1;
	else if (pr == SmbProcessResultDie)
		rv = -1;
	else
		rv = 0;
	goto done;
closedown:
	rv = -1;
done:
	if (rv < 0) {
		smblogprintif(smbglobals.log.sessions, "shutting down\n");
		smbsessionfree(smbs);
	}
	smbbufferfree(&b);
	if (smbglobals.log.poolparanoia)
		poolcheck(mainmem);
	return rv;
}
Exemplo n.º 8
0
void
smbresponseinit(SmbSession *s, ushort maxlen)
{
	smbbufferfree(&s->response);
	s->response = smbbuffernew(maxlen);
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
SmbProcessResult
smbtrans2setfileinformation(SmbSession *s, SmbHeader *h)
{
	SmbTree *t;
	ushort infolevel;
	SmbBuffer *b;
	SmbProcessResult pr;
	ushort fid;
	SmbFile *f;
	vlong newsize;
	uvlong atime, mtime;
	ulong attr;
	ulong mode;

	t = smbidmapfind(s->tidmap, h->tid);
	if (t == nil) {
		smbseterror(s, ERRSRV, ERRinvtid);
		pr = SmbProcessResultError;
		goto done;
	}
	b = smbbufferinit(s->transaction.in.parameters, s->transaction.in.parameters, s->transaction.in.tpcount);
	if (!smbbuffergets(b, &fid) || !smbbuffergets(b, &infolevel)) {
	misc:
		pr = SmbProcessResultMisc;
		goto done;
	}

	f = smbidmapfind(s->fidmap, fid);
	if (f == nil) {
		smbseterror(s, ERRDOS, ERRbadfid);
		pr = SmbProcessResultError;
		goto done;
	}

	switch (infolevel) {
	case SMB_SET_FILE_ALLOCATION_INFO:
	case SMB_SET_FILE_END_OF_FILE_INFO:
		if (s->transaction.in.tdcount < 8)
			goto misc;
		newsize = smbnhgetv(s->transaction.in.data);
		pr = smbtruncatefile(s, f, newsize);
		if (pr == SmbProcessResultReply && !smbbufferputs(s->transaction.out.parameters, 0))
			goto misc;
		break;

	case SMB_SET_FILE_BASIC_INFO:
		if (s->transaction.in.tdcount < 4 * 8 + 4)
			goto misc;
		atime = smbnhgetv(s->transaction.in.data + 8);
		mtime = smbnhgetv(s->transaction.in.data + 24);
		attr = smbnhgetv(s->transaction.in.data + 32);
		if (attr) {
			Dir *od = dirfstat(f->fd);
			if (od == nil)
				goto noaccess;
			mode = smbdosattr2plan9wstatmode(od->mode, attr);
			free(od);
		}
		else
			mode = 0xffffffff;
		if (atime || mtime || mode != 0xffffffff) {
			Dir d;
			memset(&d, 0xff, sizeof(d));
			d.name = d.uid = d.gid = d.muid = nil;
			if (atime)
				d.atime = smbtime2plan9time(atime);
			if (mtime)
				d.mtime = smbtime2plan9time(mtime);
			d.mode = mode;
			if (dirfwstat(f->fd, &d) < 0) {
			noaccess:
				smbseterror(s, ERRDOS, ERRnoaccess);
				pr = SmbProcessResultError;
				goto done;
			}
		}
		if (!smbbufferputs(s->transaction.out.parameters, 0))
			goto misc;
		pr = SmbProcessResultReply;
		break;

	case SMB_SET_FILE_DISPOSITION_INFO:
		if (s->transaction.in.tdcount < 1)
			goto misc;
		f->sf->deleteonclose = *s->transaction.in.data;
		if (!smbbufferputs(s->transaction.out.parameters, 0))
			goto misc;
		pr = SmbProcessResultReply;
		break;

	default:
		smblogprint(-1, "smbtrans2setfileinformation: infolevel 0x%.4ux not implemented\n", infolevel);
		smbseterror(s, ERRDOS, ERRunknownlevel);
		pr = SmbProcessResultError;
		break;
	}
done:
	smbbufferfree(&b);
	return pr;
}
Exemplo n.º 11
0
SmbProcessResult
smbtrans2setpathinformation(SmbSession *s, SmbHeader *h)
{
	char *fullpath, *path;
	SmbTree *t;
	ushort infolevel;
	SmbBuffer *b;
	SmbProcessResult pr;
	ushort atime, adate, mtime, mdate;
	ulong attr;
	ulong mode;
	ulong size;
//	uvlong length;

	t = smbidmapfind(s->tidmap, h->tid);
	if (t == nil) {
		smbseterror(s, ERRSRV, ERRinvtid);
		pr = SmbProcessResultError;
		goto done;
	}
	b = smbbufferinit(s->transaction.in.parameters, s->transaction.in.parameters, s->transaction.in.tpcount);
	path = nil;
	if (!smbbuffergets(b, &infolevel) || !smbbuffergetbytes(b, nil, 4)
		|| !smbbuffergetstring(b, h, SMB_STRING_PATH, &path)) {
	misc:
		pr = SmbProcessResultMisc;
		goto done;
	}

	fullpath = nil;
	smbstringprint(&fullpath, "%s%s", t->serv->path, path);

	translogprint(s->transaction.in.setup[0], "path %s\n", path);
	translogprint(s->transaction.in.setup[0], "infolevel 0x%.4ux\n", infolevel);
	translogprint(s->transaction.in.setup[0], "fullpath %s\n", fullpath);

	switch (infolevel) {
	case SMB_INFO_STANDARD:
		if (s->transaction.in.tdcount < 6 * 4 + 2 * 2)
			goto misc;
		adate = smbnhgets(s->transaction.in.data + 6);
		atime = smbnhgets(s->transaction.in.data + 4);
		mdate = smbnhgets(s->transaction.in.data + 10);
		mtime = smbnhgets(s->transaction.in.data + 8);
		size = smbnhgetl(s->transaction.in.data + 12);
		attr = smbnhgets(s->transaction.in.data + 20);
		if (attr) {
			Dir *od = dirstat(fullpath);
			if (od == nil)
				goto noaccess;
			mode = smbdosattr2plan9wstatmode(od->mode, attr);
			free(od);
		}
		else
			mode = 0xffffffff;
		translogprint(s->transaction.in.setup[0], "mode 0%od\n", mode);

//		if (size)
//			length = size;
//		else
//			length = ~0LL;
	
		translogprint(s->transaction.in.setup[0], "size %lld\n", size);
		translogprint(s->transaction.in.setup[0], "adate %d atime %d", adate, atime);
		translogprint(s->transaction.in.setup[0], "mdate %d mtime %d\n", mdate, mtime);

		if (size || adate || atime || mdate || mtime || mode != 0xffffffff) {
			Dir d;
			memset(&d, 0xff, sizeof(d));
			d.name = d.uid = d.gid = d.muid = nil;
			if (adate || atime)
				d.atime = smbdatetime2plan9time(adate, atime, s->tzoff);
			if (mdate || mtime)
				d.mtime = smbdatetime2plan9time(mdate, mtime, s->tzoff);
			d.mode = mode;
			d.length = size;
			if (dirwstat(fullpath, &d) < 0) {
			noaccess:
				smbseterror(s, ERRDOS, ERRnoaccess);
				pr = SmbProcessResultError;
				goto done;
			}
		}
		if (!smbbufferputs(s->transaction.out.parameters, 0))
			goto misc;
		pr = SmbProcessResultReply;
		break;

	default:
		smblogprint(-1, "smbtrans2setpathinformation: infolevel 0x%.4ux not implemented\n", infolevel);
		smbseterror(s, ERRDOS, ERRunknownlevel);
		pr = SmbProcessResultError;
		break;
	}
done:
	smbbufferfree(&b);
	return pr;
}
Exemplo n.º 12
0
int
smbnetserverenum2(SmbClient *c, uint32_t stype, char *domain,
		  int *entriesp,
		  SmbRapServerInfo1 **sip, char **errmsgp)
{
	int rv;
	uint16_t ec, entries, total, converter;
	SmbRapServerInfo1 *si = nil;
	SmbBuffer *ipb = smbbuffernew(512);
	SmbBuffer *odb = smbbuffernew(65535);
	SmbBuffer *opb = smbbuffernew(8);
	smbbufferputs(ipb, 104);
	smbbufferputstring(ipb, nil, SMB_STRING_ASCII, "WrLehDz");
	smbbufferputstring(ipb, nil, SMB_STRING_ASCII, "B16BBDz");
	smbbufferputs(ipb, 1);
	smbbufferputs(ipb, smbbufferwritespace(odb));
	smbbufferputl(ipb, stype);
	smbbufferputstring(ipb, nil, SMB_STRING_ASCII, domain);
	rv = !smbclientrap(c, ipb, opb, odb, errmsgp);
	smbbufferfree(&ipb);
	if (rv == 0) {
		char *remark, *eremark;
		int remarkspace;
		int i;
		if (!smbbuffergets(opb, &ec)
			|| !smbbuffergets(opb, &converter)
			|| !smbbuffergets(opb, &entries)
			|| !smbbuffergets(opb, &total)) {
			smbstringprint(errmsgp, "smbnetserverenum2: not enough return parameters");
			rv = -1;
			goto done;
		}
		if (ec != 0) {
			rv = ec;
			goto done;
		}
		if (smbbufferreadspace(odb) < entries * 26) {
			smbstringprint(errmsgp, "smbnetserverenum2: not enough return data");
			rv = -1;
			goto done;
		}
		remarkspace = smbbufferreadspace(odb) - entries * 26;
		si = smbemalloc(entries * sizeof(SmbRapServerInfo1) + remarkspace);
		remark = (char *)&si[entries];
		eremark = remark + remarkspace;
		for (i = 0; i < entries; i++) {
			uint32_t offset;
			int remarklen;
			assert(smbbuffergetbytes(odb, si[i].name, 16));
			assert(smbbuffergetb(odb, &si[i].vmaj));
			assert(smbbuffergetb(odb, &si[i].vmin));
			assert(smbbuffergetl(odb, &si[i].type));
			assert(smbbuffergetl(odb, &offset));
			offset -= converter;
			if (!smbbufferoffsetcopystr(odb, offset, remark, eremark - remark, &remarklen)) {
				smbstringprint(errmsgp, "smbnetserverenum2: invalid string offset");
				rv = -1;
				goto done;
			}
			si[i].remark = remark;
			remark += remarklen;
		}
		*sip = si;
		si = nil;
		*entriesp = entries;
	}
	else
		rv = -1;	
done:
	free(si);
	smbbufferfree(&opb);
	smbbufferfree(&odb);
	return rv;
}
Exemplo n.º 13
0
SmbProcessResult
smbtrans2findnext2(SmbSession *s, SmbHeader *h)
{
	SmbBuffer *b;
	int debug;
	ushort sid, scount, infolevel;
	ulong resumekey;
	ushort flags;
	char *filename = nil;
	SmbProcessResult pr;
	ushort e;
	ulong nameoffset;
	ushort eos;
	SmbTree *t;
	SmbSearch *search;

	debug = smboptable[h->command].debug
		|| smbtrans2optable[SMB_TRANS2_FIND_NEXT2].debug
		|| smbglobals.log.find;
	b = smbbufferinit(s->transaction.in.parameters, s->transaction.in.parameters, s->transaction.in.tpcount);
	if (!smbbuffergets(b, &sid)
		|| !smbbuffergets(b, &scount)
		|| !smbbuffergets(b, &infolevel)
		|| !smbbuffergetl(b, &resumekey)
		|| !smbbuffergets(b, &flags)
		|| !smbbuffergetstring(b, h, 0, &filename)) {
		pr = SmbProcessResultFormat;
		goto done;
	}
	smblogprintif(debug,
		"smbtrans2findnext2: sid %d scount %d infolevel 0x%.4ux resumekey %lud flags 0x%.4ux filename %s\n",
		sid, scount, infolevel, resumekey, flags, filename);

	if (infolevel != SMB_INFO_STANDARD && infolevel != SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
		smblogprint(-1, "smbtrans2findnext2: infolevel 0x%.4ux not implemented\n", infolevel);
		smbseterror(s, ERRDOS, ERRunknownlevel);
		pr = SmbProcessResultError;
		goto done;
	}

	t = smbidmapfind(s->tidmap, h->tid);
	if (t == nil) {
		smbseterror(s, ERRSRV, ERRinvtid);
		pr = SmbProcessResultError;
		goto done;
	}

	search = smbidmapfind(s->sidmap, sid);
	if (search == nil) {
		smbseterror(s, ERRDOS, ERRnofiles);
		pr = SmbProcessResultError;
		goto done;
	}

	if (search->t != t) {
		smbseterror(s, ERRSRV, ERRinvtid);
		pr = SmbProcessResultError;
		goto done;
	}

	if ((flags & (1 << 3)) == 0) {
		long i;
		if (filename == nil) {
			smbseterror(s, ERRDOS, ERRnofiles);
			pr = SmbProcessResultError;
			goto done;
		}
		for (i = 0; i < search->dc->n; i++)
			if (strcmp(search->dc->buf[i].name, filename) == 0) {
				search->dc->i = i + 1;
				break;
			}
	}

	populate(s, search->dc, search->rep, infolevel, flags, scount, &e, &nameoffset);
	
	eos = search->dc->i >= search->dc->n;
	if ((flags & SMB_FIND_CLOSE) != 0 || ((flags & SMB_FIND_CLOSE_EOS) != 0 && eos))
		smbsearchclose(s, search);
	smbbufferputs(s->transaction.out.parameters, e);
	smbbufferputs(s->transaction.out.parameters, eos);
	smbbufferputs(s->transaction.out.parameters, 0);
	smbbufferputs(s->transaction.out.parameters, nameoffset);
	pr = SmbProcessResultReply;
done:
	smbbufferfree(&b);
	free(filename);
	return pr;
}
Exemplo n.º 14
0
SmbProcessResult
smbtrans2findfirst2(SmbSession *s, SmbHeader *h)
{
	SmbBuffer *b;
	char *pattern = nil;
	char *dir = nil;
	char *name = nil;
	ushort searchattributes, searchcount, flags, informationlevel;
	ulong searchstoragetype;
	SmbDirCache *dc = nil;
	ushort e;
	ulong nameoffset;
	ushort eos;
	SmbSearch *search;
	SmbProcessResult pr;
	Reprog *r = nil;
	SmbTree *t;
	int debug;

	debug = smboptable[h->command].debug
		|| smbtrans2optable[SMB_TRANS2_FIND_FIRST2].debug
		|| smbglobals.log.find;
poolcheck(mainmem);
	b = smbbufferinit(s->transaction.in.parameters, s->transaction.in.parameters, s->transaction.in.tpcount);
	if (!smbbuffergets(b, &searchattributes)
		|| !smbbuffergets(b, &searchcount)
		|| !smbbuffergets(b, &flags)
		|| !smbbuffergets(b, &informationlevel)
		|| !smbbuffergetl(b, &searchstoragetype)
		|| !smbbuffergetstring(b, h, SMB_STRING_PATH, &pattern)) {
		pr = SmbProcessResultFormat;
		goto done;
	}
	smbloglock();
	smblogprintif(debug, "searchattributes: 0x%.4ux\n", searchattributes);
	smblogprintif(debug, "searchcount: 0x%.4ux\n", searchcount);
	smblogprintif(debug, "flags: 0x%.4ux\n", flags);
	smblogprintif(debug, "informationlevel: 0x%.4ux\n", informationlevel);
	smblogprintif(debug, "searchstoragetype: 0x%.8lux\n", searchstoragetype);
	smblogprintif(debug, "pattern: %s\n", pattern);
	smblogunlock();
	smbpathsplit(pattern, &dir, &name);
	if (informationlevel != SMB_INFO_STANDARD && informationlevel != SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
		smblogprint(-1, "smbtrans2findfirst2: infolevel 0x%.4ux not implemented\n", informationlevel);
		smbseterror(s, ERRDOS, ERRunknownlevel);
		pr = SmbProcessResultError;
		goto done;
	}

	t = smbidmapfind(s->tidmap, h->tid);
	if (t == nil) {
		smbseterror(s, ERRSRV, ERRinvtid);
		pr = SmbProcessResultError;
		goto done;
	}

	dc = smbmkdircache(t, dir);
	if (dc == nil) {
		smbseterror(s, ERRDOS, ERRnoaccess);
		pr = SmbProcessResultError;
		goto done;
	}
poolcheck(mainmem);
	r = smbmkrep(name);
	populate(s, dc, r, informationlevel, flags, searchcount, &e, &nameoffset);
poolcheck(mainmem);
	eos = dc->i >= dc->n;
	if ((flags & SMB_FIND_CLOSE) != 0 || ((flags & SMB_FIND_CLOSE_EOS) != 0 && eos))
		smbdircachefree(&dc);
poolcheck(mainmem);
	if (dc) {
		/* create a search handle */
		search = smbsearchnew(s, dc, r, t);
		r = nil;
		dc = nil;
	}
	else
		search = nil;
	smbbufferputs(s->transaction.out.parameters, search ? search->id : 0);
	smbbufferputs(s->transaction.out.parameters, e);
	smbbufferputs(s->transaction.out.parameters, eos);
	smbbufferputs(s->transaction.out.parameters, 0);
	smbbufferputs(s->transaction.out.parameters, nameoffset);
	pr = SmbProcessResultReply;
done:
	smbbufferfree(&b);
	free(pattern);
	free(dir);
	free(name);
	smbdircachefree(&dc);
	free(r);
	return pr;
}