示例#1
0
SmbBuffer *
smbbuffernew(ulong maxlen)
{
	SmbBuffer *b;
	b = smbemalloc(sizeof(SmbBuffer));
	b->buf = smbemalloc(maxlen);
	b->realmaxlen = b->maxlen = maxlen;
	b->rn = 0;
	b->wn = 0;
	b->flags = STRUCT | BUFFER;
	return b;
}
示例#2
0
char *
smbstringdup(SmbHeader *h, uchar *base, uchar **bdatap, uchar *edata)
{
	char *p;
	if (h && h->flags2 & SMB_FLAGS2_UNICODE) {
		uchar *bdata = *bdatap;
		uchar *savebdata;
		Rune r;
		int l;
		char *q;

		l = 0;
		if ((bdata - base) & 1)
			bdata++;
		savebdata = bdata;
		do {
			if (bdata + 2 > edata)
				return nil;
			r = smbnhgets(bdata); bdata += 2;
			l += runelen(r);
		} while (r != 0);
		p = smbemalloc(l);
		bdata = savebdata;
		q = p;
		do {
			r = smbnhgets(bdata); bdata += 2;
			q += runetochar(q, &r);
		} while (r != 0);
		*bdatap = bdata;
		return p;
	}
	return smbstrdup(bdatap, edata);
}
示例#3
0
文件: smballoc.c 项目: 99years/plan9
char *
smbestrdup(char *p)
{
	char *q;
	q = smbemalloc(strlen(p) + 1);
	return strcpy(q, p);
}
示例#4
0
文件: smblisten.c 项目: bhanug/harvey
static Session *
createsession(int fd)
{
	Session *s;
	s = smbemalloc(sizeof(Session));
	s->fd = fd;
	s->state = Connected;
	qlock(&sessions);
	if (!(*tcp.accept)(s, &s->write)) {
		qunlock(&sessions);
		free(s);
		return nil;
	}
	s->thread = procrfork(tcpreader, s, 32768, RFNAMEG);
	if (s->thread < 0) {
		qunlock(&sessions);
		(*s->write)(s, nil, -1);
		free(s);
		return nil;
	}
	s->next = sessions.head;
	sessions.head = s;
	qunlock(&sessions);
	return s;
}
示例#5
0
SmbBuffer *
smbbufferinit(void *base, void *bdata, ulong blen)
{
	SmbBuffer *b;
	b = smbemalloc(sizeof(*b));
	b->buf = base;
	b->flags = STRUCT;	
	b->rn = (uchar *)bdata - (uchar *)base;
	b->wn = b->rn + blen;
	b->realmaxlen = b->maxlen = b->wn;
	return b;
}
示例#6
0
int
smbbuffergetucs2(SmbBuffer *b, ulong flags, char **sp)
{
	uchar *bdata = b->buf + b->rn;
	uchar *edata = b->buf + b->wn;
	Rune r;
	int l;
	char *p, *q;
	uchar *savebdata;
	int first;

	l = 0;
	if ((flags & SMB_STRING_UNALIGNED) == 0 && (bdata - b->buf) & 1)
		bdata++;
	savebdata = bdata;
	first = 1;
	do {
		if (bdata + 2 > edata) {
			l++;
			break;
		}
		r = smbnhgets(bdata); bdata += 2;
		if (first && (flags & SMB_STRING_PATH) && r != '\\')
			l++;
		first = 0;
		if (flags & SMB_STRING_CONVERT_MASK)
			r = smbruneconvert(r, flags);
		l += runelen(r);
	} while (r != 0);
	p = smbemalloc(l);
	bdata = savebdata;
	q = p;
	first = 1;
	do {
		if (bdata + 2 > edata) {
			*q = 0;
			break;
		}
		r = smbnhgets(bdata); bdata += 2;
		if (first && (flags & SMB_STRING_PATH) && r != '\\')
			*q++ = '/';
		first = 0;
		if (flags & SMB_STRING_CONVERT_MASK)
			r = smbruneconvert(r, flags);
		q += runetochar(q, &r);
	} while (r != 0);
	b->rn = bdata - b->buf;
	*sp = p;
	return 1;
}
示例#7
0
SmbSearch *
smbsearchnew(SmbSession *s, SmbDirCache *dc, Reprog *r, SmbTree *t)
{
	SmbSearch *search;
	if (s->sidmap == nil)
		s->sidmap = smbidmapnew();
	search = smbemalloc(sizeof(SmbSearch));
	smbidmapadd(s->sidmap, search);
	search->dc = dc;
	search->rep = r;
	search->t = t;
	smblogprintif(smbglobals.log.sids, "smbsearchnew: 0x%.4ux\n", search->id);
	return search;
}
示例#8
0
void
smbbuffersetbuf(SmbBuffer *s, void *p, ulong maxlen)
{
	s->realmaxlen = s->maxlen = maxlen;
	if (s->buf) {
		if (s->flags & BUFFER)
			free(s->buf);
		s->buf = nil;
	}
	s->flags &= ~BUFFER;
	if (p)
		s->buf = p;
	else {
		s->buf = smbemalloc(maxlen);
		s->flags |= BUFFER;
	}
	smbbufferreset(s);
}
示例#9
0
int
smbsharedfilelock(SmbSharedFile *sf, SmbSession *s, uint16_t pid,
                  int64_t base,
                  int64_t limit)
{
    SmbLockListEntry smblock;
    SmbLockListEntry *l, *nl, **lp;
    smblock.s = s;
    smblock.pid = pid;
    smblock.base = base;
    smblock.limit = limit;
    if (sf->locklist) {
        for (l = sf->locklist->head; l; l = l->next)
            if (lockconflict(l, &smblock)) {
                smblogprintif(smbglobals.log.locks, "smbsharedfilelock: lock [%lld, %lld) failed because conflicts with [%lld, %lld)\n",
                              base, limit, l->base, l->limit);
                return 0;
            }
    }
    if (sf->locklist == nil)
        sf->locklist = smbemallocz(sizeof(SmbLockList), 1);
    for (lp = &sf->locklist->head; (l = *lp) != nil; lp = &l->next)
        if (lockorder(&smblock, l) <= 0)
            break;
    smblogprintif(smbglobals.log.locks, "smbsharedfilelock: lock [%lld, %lld) succeeded\n", base, limit);
    nl = smbemalloc(sizeof(*nl));
    *nl = smblock;
    nl->next = *lp;
    *lp = nl;
//{
//	smblogprintif(smbglobals.log.locks,"smbsharedfilelock: list\n");
//	for (l = sf->locklist->head; l; l = l->next)
//		smblogprintif(smbglobals.log.locks, "smbsharedfilelock: [%lld, %lld)\n", l->base, l->limit);
//}
    return 1;
}
示例#10
0
SmbProcessResult
smbtruncatefile(SmbSession *s, SmbFile *f, vlong offset)
{
	Dir *d;
	ulong o;
	uchar *db = nil;
	vlong length;
	int rv;
	SmbProcessResult pr;

	d = dirfstat(f->fd);
	assert(d);
	length = d->length;
	free(d);

	if (length == offset)
		return SmbProcessResultReply;

	rv = dirfwstatlength(f->fd, offset);
	if (rv == 0) {
		pr = SmbProcessResultReply;
		goto done;
	}
//smblogprint(-1, "dirfwstatlength failed: %r\n");
	if (length > offset) {
		int nfd;
		char *fullpath;
		if (offset > INMEMORYTRUNCTHRESH) {
			smblogprint(-1, "smbcomwrite: truncation beyond %lud not supported\n", offset);
			pr = SmbProcessResultUnimp;
			goto done;
		}
		db = smbemalloc(offset);
		if (pread(f->fd, db, offset, 0) != offset) {
			pr = SmbProcessResultMisc;
			goto done;
		}
		fullpath = nil;
		smbstringprint(&fullpath, "%s%s", f->t->serv->path, f->name);
		nfd = open(fullpath, f->p9mode | OTRUNC);
		free(fullpath);
		if (nfd < 0) {
			smbseterror(s, ERRDOS, ERRnoaccess);
			pr = SmbProcessResultError;
			goto done;
		}
		close(nfd);
		if (pwrite(f->fd, db, offset, 0) != offset) {
			pr = SmbProcessResultMisc;
			goto done;
		}
		pr = SmbProcessResultReply;
	}
	else {
		db = smbemalloc(16384);
		memset(db, 0, 16384);
		o = length;
		while (o < offset) {
			long tt = 16384;
			if (tt > offset - o)
				tt = offset - o;
			if (pwrite(f->fd, db, tt, o) != tt) {
				smbseterror(s, ERRDOS, ERRnoaccess);
				pr = SmbProcessResultError;
				goto done;
			}
			o += tt;
		}
		pr = SmbProcessResultReply;
	}
done:
	free(db);
	return pr;
}
示例#11
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;
}
示例#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;
}