Esempio n. 1
0
static SmbProcessResult
netserverenum2(SmbBuffer *inparam, SmbBuffer *outparam, SmbBuffer *outdata)
{
	uint16_t level, rbl;
	char *domain;
	uint32_t servertype;
	SmbProcessResult pr;
	SmbServerInfo *si[3];
	SmbServerInfo domainsi;
	int entries;

	/* WrLehDz
	 * ushort sLevel, RCVBUF pbBuffer, RCVBUFLEN cbBuffer, ENTCOUNT pcEntriesRead, ushort *pcTotalAvail,
	 * ulong fServerType, char *pszDomain
	*/

	if (!smbbuffergets(inparam, &level)
		|| !smbbuffergets(inparam, &rbl)
		|| !smbbuffergetl(inparam, &servertype)
		|| !smbbuffergetstr(inparam, 0, &domain)) {
	fmtfail:
		pr = SmbProcessResultFormat;
		goto done;
	}
	
	smblogprintif(smbglobals.log.rap2, "netserverenum2(%lud, %lud, 0x%.8lux, %s)\n",
		level, smbbufferwritespace(outdata), servertype, domain);

	if (level > 1)
		goto fmtfail;

	if (servertype == 0xffffffff)
		servertype &= ~(SV_TYPE_DOMAIN_ENUM | SV_TYPE_LOCAL_LIST_ONLY);

	if ((servertype & SV_TYPE_LOCAL_LIST_ONLY) != 0 && (servertype & SV_TYPE_DOMAIN_ENUM) == 0) 
		servertype = SV_TYPE_ALL & ~(SV_TYPE_DOMAIN_ENUM);

	entries = 0;

	if ((servertype & SV_TYPE_SERVER) != 0
		&& (domain[0] == 0 || cistrcmp(domain, smbglobals.primarydomain) == 0)) {
		si[entries++] = &smbglobals.serverinfo;
	}

	if ((servertype & SV_TYPE_DOMAIN_ENUM) != 0) {
		/* there's only one that I know about */
		memset(&domainsi, 0, sizeof(domainsi));
		domainsi.name = smbglobals.primarydomain;
		domainsi.stype = SV_TYPE_DOMAIN_ENUM;
		si[entries++] = &domainsi;
	}
	si[entries] = 0;

	pr = thingfill(outparam, outdata, &serverinfo, level, si);
			
done:
	free(domain);
	return pr;
}
Esempio n. 2
0
static int
getlock(SmbBuffer *b, int large, ushort *pidp, uvlong *offsetp, uvlong *lengthp)
{
	ulong ohigh, olow;
	ulong lhigh, llow;
	if (!smbbuffergets(b, pidp))
		return 0;
	if (large && !smbbuffergetbytes(b, nil, 2))
		return 0;
	if (large) {
		if (!smbbuffergetl(b, &ohigh) || !smbbuffergetl(b, &olow)
			|| !smbbuffergetl(b, &lhigh) || !smbbuffergetl(b, &llow))
			return 0;
		*offsetp = ((uvlong)ohigh << 32) | olow;
		*lengthp = ((uvlong)lhigh << 32) | llow;
		return 1;
	}
	if (!smbbuffergetl(b, &olow) || !smbbuffergetl(b, &llow))
		return 0;
	*offsetp = olow;
	*lengthp = llow;
	return 1;
}
Esempio n. 3
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;
}
Esempio n. 4
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;
}
Esempio n. 5
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;
}
Esempio n. 6
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;
}