示例#1
0
SmbProcessResult
smbcomcreatedirectory(SmbSession *s, SmbHeader *h, uint8_t *, SmbBuffer *b)
{
	int fd;
	char *path;
	char *fullpath = nil;
	SmbTree *t;
	uint8_t fmt;

	if (h->wordcount != 0)
		return SmbProcessResultFormat;
	if (!smbbuffergetb(b, &fmt) || fmt != 0x04 || !smbbuffergetstring(b, h, SMB_STRING_PATH, &path))
		return SmbProcessResultFormat;
	smblogprint(h->command, "smbcomcreatedirectory: %s\n", path);
	t = smbidmapfind(s->tidmap, h->tid);
	if (t == nil) {
		smbseterror(s, ERRSRV, ERRinvtid);
		return SmbProcessResultError;
	}
	smbstringprint(&fullpath, "%s%s", t->serv->path, path);
	fd = create(fullpath, OREAD, DMDIR | 0775);
	if (fd < 0) {
		smblogprint(h->command, "smbcomcreatedirectory failed: %r\n");
		smbseterror(s, ERRDOS, ERRnoaccess);
		free(path);
		return SmbProcessResultError;
	}
	close(fd);
	free(fullpath);
	free(path);
	return smbbufferputack(s->response, h, &s->peerinfo);
}
示例#2
0
SmbProcessResult
smbcomsetinformation(SmbSession *s, SmbHeader *h, uint8_t *pdata,
		     SmbBuffer *b)
{
	uint16_t attr;
	uint32_t utime;
	char *name;
	if (h->wordcount != 8)
		return SmbProcessResultFormat;
	attr = smbnhgets(pdata); pdata += 2;
	utime = smbnhgetl(pdata);
	if (!smbbuffergetstring(b, h, SMB_STRING_PATH, &name))
		return SmbProcessResultFormat;
	smblogprint(h->command,
		"smbcomsetinformation: attr 0x%.4ux utime %lud path %s\n",
		attr, utime, name);
	if (utime) {
		Dir d;
		memset(&d, 0xff, sizeof(d));
		d.name = d.uid = d.gid = d.muid = nil;
		d.mtime = smbutime2plan9time(utime, s->tzoff);
		if (dirwstat(name, &d) < 0) {
			smbseterror(s, ERRDOS, ERRnoaccess);
			free(name);
			return SmbProcessResultError;
		}
	}
	free(name);		
	return smbbufferputack(s->response, h, &s->peerinfo);
}
示例#3
0
SmbProcessResult
smbcomflush(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *)
{
	SmbTree *t;
	SmbFile *f;
	ushort fid;
	Dir nulldir;
	if (h->wordcount != 1)
		return SmbProcessResultFormat;
	fid = smbnhgets(pdata);
	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;
	}
	memset(&nulldir, 0xff, sizeof(nulldir));
	nulldir.name = nulldir.uid = nulldir.gid = nulldir.muid = nil;
	dirfwstat(f->fd, &nulldir);
	return smbbufferputack(s->response, h, &s->peerinfo);
}
示例#4
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;
}
示例#5
0
SmbProcessResult
smbcomtreedisconnect(SmbSession *s, SmbHeader *h, uchar *, SmbBuffer *)
{
	if (!smbcheckwordcount("comtreedisconnect", h, 0))
		return SmbProcessResultFormat;
	smbtreedisconnectbyid(s, h->tid);
	return smbbufferputack(s->response, h, &s->peerinfo);
}
示例#6
0
SmbProcessResult
smbcomdelete(SmbSession *s, SmbHeader *h, uint8_t *pdata, SmbBuffer *b)
{
	SmbProcessResult pr;
	uint16_t sattr;
	uint8_t fmt;
	char *pattern = nil;
	char *dir = nil;
	char *name = nil;
	Reprog *r = nil;
	SmbTree *t;
	int x, count;
	SmbDirCache *dc = nil;

	if (h->wordcount != 1)
		return SmbProcessResultFormat;
	sattr = smbnhgets(pdata);
	if (!smbbuffergetb(b, &fmt) || fmt != 0x04
		|| !smbbuffergetstring(b, h, SMB_STRING_PATH, &pattern))
		return SmbProcessResultFormat;
	smblogprint(SMB_COM_DELETE, "searchattributes: 0x%.4x\npattern:%s\n", sattr, pattern);
	smbpathsplit(pattern, &dir, &name);
	t = smbidmapfind(s->tidmap, h->tid);
	if (t == nil) {
		smbseterror(s, ERRSRV, ERRinvtid);
		pr = SmbProcessResultError;
		goto done;
	}
	dc = smbmkdircache(t, dir);
	if (dc == nil) {
		pr = SmbProcessResultMisc;
		goto done;
	}
	r = smbmkrep(name);
	count = 0;
	for (x = 0; x < dc->n; x++) {
		if (!smbmatch(dc->buf[x].name, r))
			continue;
		if (smbremovefile(t, dir, dc->buf[x].name) == 0)
			count++;
	}
	if (count == 0) {
		smbseterror(s, ERRDOS, ERRnoaccess);
		pr = SmbProcessResultError;
	}
	else
		pr = smbbufferputack(s->response,h, &s->peerinfo);
done:
	free(pattern);
	free(dir);
	free(name);
	smbdircachefree(&dc);
	free(r);
	return pr;
}
示例#7
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;
}
示例#8
0
SmbProcessResult
smbcomsetinformation2(SmbSession *s, SmbHeader *h, uint8_t *pdata,
		      SmbBuffer *)
{
	uint16_t fid, adate, atime, mdate, mtime;
	SmbTree *t;
	SmbFile *f;
	Dir d;

	if (h->wordcount != 7)
		return SmbProcessResultFormat;
	fid = smbnhgets(pdata);
	adate = smbnhgets(pdata + 6);
	atime = smbnhgets(pdata + 8);
	mdate = smbnhgets(pdata + 10);
	mtime = smbnhgets(pdata + 12);
	smblogprint(h->command,
		"smbcomsetinformation2: fid 0x%.4ux adate 0x%.4ux atime 0x%.4ux mdate 0x%.4ux mtime 0x%.4ux\n",
		fid, adate, atime, mdate, mtime);
	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;
	}
	memset(&d, 0xff, sizeof(d));
	d.name = d.uid = d.gid = d.muid = nil;
	if (adate || atime || mdate || mtime) {
//smblogprint(-1, "smbcomsetinformation2: changing times not implemented\n");
//		return SmbProcessResultUnimp;
		/* something to change */
		if (!(adate && atime && mdate && mtime)) {
			/* some null entries */
			uint16_t odate, otime;
			Dir *od = dirfstat(f->fd);
			if (od == nil) {
				smbseterror(s, ERRDOS, ERRnoaccess);
				return SmbProcessResultError;
			}
			if (adate || atime) {
				/* something changed in access time */
				if (!(adate && atime)) {
					/* some nulls in access time */
					smbplan9time2datetime(d.atime, s->tzoff, &odate, &otime);
					if (adate == 0)
						adate = odate;
					if (atime == 0)
						atime = otime;
				}
				d.atime = smbdatetime2plan9time(adate, atime, s->tzoff);
			}
			if (mdate || mtime) {
				/* something changed in modify time */
				if (!(mdate && mtime)) {
					/* some nulls in modify time */
					smbplan9time2datetime(d.mtime, s->tzoff, &odate, &otime);
					if (mdate == 0)
						mdate = odate;
					if (mtime == 0)
						mtime = otime;
				}
				d.mtime = smbdatetime2plan9time(mdate, mtime, s->tzoff);
			}
			free(od);
		}
		if (dirfwstat(f->fd, &d) < 0) {
			smbseterror(s, ERRDOS, ERRnoaccess);
			return SmbProcessResultError;
		}
	}
	return smbbufferputack(s->response, h, &s->peerinfo);
}