Пример #1
0
static int
findbothflatten(SmbBuffer *b, SmbPeerInfo *p, Dir *d, ulong resumekey, ulong *nameoffsetp)
{
	vlong mtime, atime;
	ulong fixup;

	fixup = smbbufferwriteoffset(b);
	mtime = smbplan9time2time(d->mtime);
	atime = smbplan9time2time(d->atime);
poolcheck(mainmem);
	if (!smbbufferputl(b, 0)
		|| !smbbufferputl(b, resumekey)
		|| !smbbufferputv(b, mtime)
		|| !smbbufferputv(b, atime)
		|| !smbbufferputv(b, mtime)
		|| !smbbufferputv(b, mtime)
		|| !smbbufferputv(b, d->length)
		|| !smbbufferputv(b, smbl2roundupvlong(d->length, smbglobals.l2allocationsize))			// ha
		|| !smbbufferputl(b, (d->qid.type & QTDIR) ? 0x10 : 0x80)
		|| !smbbufferputl(b, smbstringlen(p, d->name))
		|| !smbbufferputl(b, 0)
		|| !smbbufferputb(b, 0)
		|| !smbbufferputb(b, 0)
		|| !smbbufferfill(b, 0, 24))
		return 0;
poolcheck(mainmem);
	*nameoffsetp = smbbufferwriteoffset(b);
	if (!smbbufferputstring(b, p, 0, d->name) || !smbbufferalignl2(b, 2))
		return 0;
poolcheck(mainmem);
	return smbbufferfixuprelativeinclusivel(b, fixup);
}
Пример #2
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;
}
Пример #3
0
void
rwrite(Job *job, Mfile *mf, Request *req)
{
	int rooted, wantsav, send;
	ulong cnt;
	char *err, *p, *atype;
	char errbuf[ERRMAX];

	err = nil;
	cnt = job->request.count;
	send = 1;
	if(mf->qid.type & QTDIR)
		err = "can't write directory";
	else if (job->request.offset != 0)
		err = "writing at non-zero offset";
	else if(cnt >= Maxrequest)
		err = "request too long";
	else
		send = 0;
	if (send)
		goto send;

	job->request.data[cnt] = 0;
	if(cnt > 0 && job->request.data[cnt-1] == '\n')
		job->request.data[cnt-1] = 0;

	/*
	 *  special commands
	 */
//	dnslog("rwrite got: %s", job->request.data);
	send = 1;
	if(strcmp(job->request.data, "age")==0){
		dnslog("dump, age & dump forced");
		dndump("/lib/ndb/dnsdump1");
		dnforceage();
		dndump("/lib/ndb/dnsdump2");
	} else if(strcmp(job->request.data, "debug")==0)
		debug ^= 1;
	else if(strcmp(job->request.data, "dump")==0)
		dndump("/lib/ndb/dnsdump");
	else if(strcmp(job->request.data, "poolcheck")==0)
		poolcheck(mainmem);
	else if(strcmp(job->request.data, "refresh")==0)
		needrefresh = 1;
	else if(strcmp(job->request.data, "restart")==0)
		stop = 1;
	else if(strcmp(job->request.data, "stats")==0)
		dnstats("/lib/ndb/dnsstats");
	else if(strncmp(job->request.data, "target ", 7)==0){
		target = atol(job->request.data + 7);
		dnslog("target set to %ld", target);
	} else
		send = 0;
	if (send)
		goto send;

	/*
	 *  kill previous reply
	 */
	mf->nrr = 0;
	mf->rr[0] = 0;

	/*
	 *  break up request (into a name and a type)
	 */
	atype = strchr(job->request.data, ' ');
	if(atype == 0){
		snprint(errbuf, sizeof errbuf, "illegal request %s",
			job->request.data);
		err = errbuf;
		goto send;
	} else
		*atype++ = 0;

	/*
	 *  tracing request
	 */
	if(strcmp(atype, "trace") == 0){
		if(trace)
			free(trace);
		if(*job->request.data)
			trace = estrdup(job->request.data);
		else
			trace = 0;
		goto send;
	}

	/* normal request: domain [type] */
	stats.qrecvd9p++;
	mf->type = rrtype(atype);
	if(mf->type < 0){
		snprint(errbuf, sizeof errbuf, "unknown type %s", atype);
		err = errbuf;
		goto send;
	}

	p = atype - 2;
	if(p >= job->request.data && *p == '.'){
		rooted = 1;
		*p = 0;
	} else
		rooted = 0;

	p = job->request.data;
	if(*p == '!'){
		wantsav = 1;
		p++;
	} else
		wantsav = 0;

	err = lookupqueryold(job, mf, req, errbuf, p, wantsav, rooted);
send:
	dncheck(0, 1);
	job->reply.count = cnt;
	sendmsg(job, err);
}
Пример #4
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;
}